1. 程式人生 > >android Launcher3中定製第三方apk圖示,實現類似主題功能

android Launcher3中定製第三方apk圖示,實現類似主題功能

最近遇到在Launcher中對於指定的app需使用使用指定的圖示,實現類似於主題的功能。要實現這樣的功能就要弄清楚Launcher是如何載入app圖示的。

首先定位到com.android.launcher3.IconCache.java這個類的cacheLocked()方法

private CacheEntry cacheLocked(ComponentName componentName, LauncherActivityInfoCompat info,
            HashMap<Object, CharSequence> labelCache, UserHandleCompat user, boolean usePackageIcon) {
        CacheKey cacheKey = new CacheKey(componentName, user);
        CacheEntry entry =
mCache.get(cacheKey); if (entry == null) { entry = new CacheEntry(); ....... entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user); //用於初始化應用圖示 entry.icon = Utilities.createIconBitmap( info.
getBadgedIcon(mIconDpi), mContext); } else { ...... return entry; }

首先通過通過info.getBadgedIcon(mIconDpi)來獲取應用原始launcher圖示的Drawable,mIconDpi為圖圖片資源id,然後通過Utilities.createIconBitmap(Drawable icon, Context context)方法來對圖示進行簡單的處理(要修改所有Launcher圖示的背景等,可以在此方法中修改)。

其中info.getBadgedIcon(mIconDpi)就是決定應用圖示的方法。該方法最終會進入com.android.launcher3.compat.LauncherActivityInfoCompatV16.java類的getBadgedIcon()–>getIcon();通過Resources來獲取圖示的。 
我採用的方法,首先自定義一個類,LauncherIconTheme.java,該類的內容如下

package com.android.launcher3;

import com.android.launcher3.R;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;

public final  class LauncherIconTheme {
    //google郵箱
    private static int GMAIL = R.drawable.ic_launcher_gmail;
    //google地圖
    private static int GOOGLE_MAPS = R.drawable.ic_launcher_googlemaps;
    //自定義的應用資源id
    ...................

    private static String TAG = "LauncherIconTheme";

        //根據包名、類名獲取Bitmap
    public static Bitmap  getIconBitmap(Context context , String packageName , String className) {
        Resources resources = context.getResources();
        int iconId = getIconId(packageName, className);
        if (iconId != -1){
            return BitmapFactory.decodeResource(resources, iconId);
        }
        return null;
    }
        //根據包名、類名獲取Drawable   要用到的就是這個方法
    public static Drawable getIconDrawable(Context context , String packageName , String className) {
        Resources resources = context.getResources();
        int iconId = getIconId(packageName, className);
        if ( iconId != -1) {
            return resources.getDrawable(iconId);
        }
        return null;
    }
        //根據包名、類名獲取資源定義的圖示資源id
    private static int getIconId(String packageName , String className){
        if ( "com.google.android.gm".equals(packageName)
                && "com.google.android.gm.ConversationListActivityGmail".equals(className)) {
            return GMAIL;

        }else if ("com.google.android.apps.maps".equals(packageName)
                && "com.google.android.maps.MapsActivity".equals(className)) {
            return GOOGLE_MAPS;

        }else if ....................
            .................................
        }else{
            return -1;          
        }
    }   
}

然後在IconCache的cacheLocked方法中

    /**
     * Retrieves the entry from the cache. If the entry is not present, it creates a new entry.
     * This method is not thread safe, it must be called from a synchronized method.
     */
    private CacheEntry cacheLocked(ComponentName componentName, LauncherActivityInfoCompat info,
            HashMap<Object, CharSequence> labelCache, UserHandleCompat user, boolean usePackageIcon) {
        CacheKey cacheKey = new CacheKey(componentName, user);
        CacheEntry entry = mCache.get(cacheKey);
        if (entry == null) {
           .................................

                entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user);
                //實現修改圖示的邏輯
                Drawable themeDrawable = LauncherIconTheme
                        .getIconDrawable(mContext,
                                componentName.getPackageName(), componentName.getClassName());
                if ( themeDrawable != null ) {
                    entry.icon = Utilities.createIconBitmap(
                            themeDrawable, mContext);
                }else{
                    entry.icon = Utilities.createIconBitmap(
                            info.getBadgedIcon(mIconDpi), mContext);                    
                }
            } else {
             ...........................................
        return entry;
    }

結束。此方法中只是簡單的在Launcher中實現自定義應用圖示的功能,有啥不足希望大家指出,共同進步。


相關推薦

android Launcher3定製第三方apk圖示實現類似主題功能

最近遇到在Launcher中對於指定的app需使用使用指定的圖示,實現類似於主題的功能。要實現這樣的功能就要弄清楚Launcher是如何載入app圖示的。首先定位到com.android.launcher3.IconCache.java這個類的cacheLocked()方法p

可編輯div的使用實現類似textarea功能

簡介 最近在做專案中遇到一個有意思的功能:在一個文字域中不僅可以輸入正常的漢字和英文,還可以在游標處插入一些自定義的內容,如:“《java程式設計思想》”,那麼這本書的書名和書名號作為一個整體插入到游標處,要刪除也是一起刪除不可以單獨刪除幾個字,很顯然用傳統的

Android Launcher3 禁止使用者拖動圖示建立資料夾控制拖動圖示到另一個圖示時的動畫效果

禁止使用者拖拽應用圖示建立資料夾,需要在Workspace中的onDrop()方法的createUserFolderIfNecessary方法註釋掉。這樣就不再建立資料夾。 // If the

android在只擁有第三方apk的情況下在自己app開啟第三方app

前提是第三方apk的AndroidManifest的某個activity中的export = "true" /** * * 開啟另一個app * @param packageName * @param classNam

Android開發的SQLite事務處理即beginTransaction()方法

使用SQLiteDatabase的beginTransaction()方法可以開啟一個事務,程式執行到endTransaction() 方法時會檢查事務的標誌是否為成功,如果程式執行到endTransaction()之前呼叫了setTransactionSuccessful() 

Android studio檢視Device File Explorer並使用sqlit3對資料庫進行操作

首先確保手機與電腦進行連線,手機屬於開發者模式。開啟Android studio找到view,點選view找到“Tool Windows ”,將滑鼠指向“Tool Windows”後找到"Device File Explorer".點選後就可以進行檢視。若想對其中的sqlit

Android Makefileinherit-product函式簡介以及與include的區別

    在 Android Makefile 中時不時會看見 inherit-product 函式的使用,類似下方這樣:         $(call  inherit-product,  vendor/dolby/ds/dolby-product.mk)     從引數來

Android Studio匯入第三方庫工程的方法

1.下載所需庫工程,此處以httpzoid為例子,在工程根目錄下建立一個extras資料夾用於存放庫工程。將httpzoid放到extras目錄中 2.專案上點選右鍵開啟Open Module Settings,點選紅框中的加號新增一個module 選擇匯入庫工程

android studio使用第三方so庫(終結版)

    安卓開發中,經常會用到第三方C++庫,然後不知道是我對系統不熟悉的原因,還是安卓支援C++開發本來就比較弱,反正其中踩了很多坑。     android studio 版本 3.0.1,  在PC上安裝android studio3.1.2,就是配置不成功,後面再筆

android textview 的\n直接顯示不換行

今天在給TextView setText的時候出現了個問題,大概內容是這樣的我想讓他換行,但是他給我原封不動的顯示成\n了。 要是在程式碼中這樣寫也沒有問題: System.out.println("nihao\nnihao"); 經過最後的嘗試,這樣解決了我也不知道為什

Android 系統工程內建APK

有些時候需要將一些自已寫的apk內建到系統,也就是第三方內建。內建的原因一部是讓apk擁有系統級許可權,一部分為了內建apk定製刷機包。 系統級: 1、先在package/apps中建立一個資料夾,如HWScanServer 2、將編譯好的apk以及所以呼叫的so庫放

關於如何在Android Studio上匯入第三方類庫Module框架

最近剛開始接觸AS,頭疼了兩個星期,期間走一步錯幾處,那叫一個頭疼,不過逛了論壇,各種查百度總算大部分都解決了,但因為太麻煩,懶得記筆記了。今天又碰上一個頭疼的問題,在GitHub上下載了一個async-http的框架,下載的是資料夾,以前到如果jar的架包,卻

Android Studio匯入aar依賴時需要修改的檔案

需要在build.gradle檔案中新增如下紅色部分apply plugin: 'com.android.application' android { compileSdkVersion 27 defaultConfig { applicationId

android-Webview】設定多個cookie實現webview儲存登入資訊

方法:通過重複呼叫 cookieManager.setCookie(url,cookie1); 來儲存多個cookie。 程式碼: /** * Sync Cookie */ private void syncCookie(Context

android通過webView載入第三方h5應用無法載入圖片和播放視訊的解決方法

只需給webview的配置中加上下面這段程式碼即可解決 這是Android5.0 WebView中Http和Https混合問題,在Android5.0 以及以上的系統,當WebView載入的連結為Https開頭,但是連結裡面的內容,比如圖片為Http連結,這時

Android開發第三方支付SDK的接入與使用(支付寶+微信支付+銀聯)

支付寶微信銀行卡支付SDK接入 支付寶支付: 一.  繫結前提: 我們自己要和支付寶簽約(商戶簽約).-->運營完成 祕鑰配置-->協助運營完成祕鑰的配置(公鑰互換),可能程式設計師會參與 整合支付寶-->必須是程式設計師去做二.  繫結步驟 整合呼叫支付

Intellij Idea Maven工程編譯時無法關聯lib資料夾第三方jar包執行時報錯找不到類

[問題描述]  將lib資料夾或者資料夾中jar包新增到依賴中,執行的時候仍然找不到jar包中的class。 [解決思路] 將lib資料夾中的jar安裝到本地maven倉庫中,修改pom.xml檔案新增jar依賴。 [解決步驟] [1] maven安裝jar包的命令如下:

android studio 判斷是否有網路並且跳轉到設定網路介面的工具類

在使用app的情況下,我們需要判斷使用者是否有網路,並提示跳轉到設定網路的介面,可以封裝成一個工具類(判斷是否有網) public boolean isConn(Context context){ //1.得到網路管理類  ConnectivityManager manag

android開發懸浮窗被禁用無許可權開啟懸浮窗的解決方案

首先,感謝這兩篇博文http://blog.csdn.net/cankingapp/article/details/51569576 http://blog.csdn.net/cool_fuwei/article/details/53070232 瞭解知識:

android.mk引用第三方庫的方法

by Denis.ding 一、整合第三方jar包: 1.在專案目錄下建立目錄libs(不建立也行,一會兒指向對應路徑就好),將第三方的jar包放進去。 2.在Android.mk檔案中進行配置: include $(CLEAR_VARS)  LOCAL_PREBUIL