Android8.1 Launcher3中应用icon的替换

客户给了一套应用icon图片,要求替换当前应用的icon,实现如下.

将要替换的应用包名存放在字符串数组中:

<string-array name="icon_package" translatable="false">
            <!-- 相机 -->
	    <item>com.android.camera2</item>
	    <!-- 浏览器 -->
	    <item>com.android.chrome,com.android.browser</item>
	    <!-- 联系人 -->
	    <item>com.android.contacts</item>
	    <!-- 电话 -->
	    <item>com.android.dialer</item>
	    <!-- 图库 -->
	    <item>com.android.gallery3d</item>
	    <!-- 音乐 -->
	    <item>com.android.music</item>
	    <!-- 设置 -->
	    <item>com.android.settings</item>
	    <!-- 应用商店 -->
	    <item>com.android.vending</item>
 </string-array>

将客户提供的应用icon的名称也存放在字符串数组中,注意应用icon图片名称在数组中位置要与包名数组中应用包名的位置

相对应,如下:

<string-array name="icon_package" translatable="false">
	    <!-- 相机 -->
	    <item>theme_camera.png</item>
	    <!-- 浏览器 -->
	    <item>theme_browser.png</item>
	    <!-- 联系人 -->
	    <item>theme_contacts.png</item>
	    <!-- 电话 -->
	    <item>theme_phone.png</item>
	    <!-- 图库 -->
	    <item>theme_gallery.png</item>
	    <!-- 音乐 -->
	    <item>theme_music.png</item>
	    <!-- 设置 -->
	    <item>theme_settings.png</item>
	    <!-- 应用商店 -->
	    <item>theme_appstore.png</item>
 </string-array>
Launcher3获取应用图标时都会经过一个类,IconCache.java

代码路径:packages/apps/Launcher3/src/com/android/launcher3/IconCache.java

在IconCache.java中找到函数:cacheLocked

函数中有下面几行代码:

entry.icon = LauncherIcons.createBadgedIconBitmap(
                   getFullResIcon(info), info.getUser(), mContext,
                   infoProvider.get().getApplicationInfo().targetSdkVersion);

没错这里就是设置应用icon的地方了,下面就需要我们在这里替换客户提供的应用icon了。

首先获取存放包名的字符串数组:

private String getIconPackage(int i){
	String[] arr = mContext.getResources().getStringArray(R.array.icon_package);

	return arr[i];
}

再通过存放icon图片名称的数组得到对应图片的资源ID:

private int getIconId(int i){

        String[] imageNameArr = mContext.getResources().getStringArray(R.array.icon_image);
	String imageName = null;
	if(!TextUtils.isEmpty(imageNameArr[i])){
             //获取图片的名称,去掉后缀
             imageName = imageNameArr[i].substring(0, imageNameArr[i].indexOf("."));
	}
        //通过图片名称获取图片的资源ID
        int resId = mContext.getResources().getIdentifier(imageName, "drawable" , mContext.getPackageName()); 
	return resId;
}

然后再实现替换应用icon的功能:

private void setAppIconTheme(ComponentName componentName, 
				Provider<LauncherActivityInfo> infoProvider, 
				LauncherActivityInfo info, 
				CacheEntry entry){
	String[] arr = mContext.getResources().getStringArray(R.array.icon_package);							
	//通过for循环取数组中的包名和系统应用的包名对比,匹配上则替换该应用的icon,替换成功就结束函数					
	for (int i = 0; i < arr.length; i++) {
		Log.d("lp","componentName.getPackageName()="+componentName.getPackageName());
                //这里判断字符串包含而不是相等,这样的好处我们可以在包名数组中的单个item中存放同类功能的不同应用,
                //比如邮箱存放如下:
                //<!-- 邮箱 -->
                //<item>com.google.android.gm.lite,com.android.email</item>
                if(getIconPackage(i).contains(componentName.getPackageName())){
			Log.d("lp","packageName("+ i +")="+getIconPackage(i));
			entry.icon = BitmapFactory.decodeResource(mContext.getResources(),getIconId(i));
			return;
		}
	}
        //for循环没匹配到,则执行默认代码
	entry.icon = LauncherIcons.createBadgedIconBitmap(
                   getFullResIcon(info), info.getUser(), mContext,
                   infoProvider.get().getApplicationInfo().targetSdkVersion);
}

接下来就用函数setAppIconTheme替换系统默认的代码:

protected CacheEntry cacheLocked(
            @NonNull ComponentName componentName,
            @NonNull Provider<LauncherActivityInfo> infoProvider,
            UserHandle user, boolean usePackageIcon, boolean useLowResIcon) {

        ........... 
        ........... 
        //此处省略 
        ........... 
        ........... 
        //用函数setAppIconTheme替换系统默认的代码: 
        if (mContext.getResources().getBoolean(R.bool.config_app_icon_theme)) { 
        	setAppIconTheme(componentName, infoProvider, info, entry);
        }else { 
        	entry.icon = LauncherIcons.createBadgedIconBitmap( getFullResIcon(info), 
        								info.getUser(), mContext, 
        								infoProvider.get().getApplicationInfo().targetSdkVersion);
        } 
        ...........
        ...........
        //此处省略
        ...........
        ...........
        return entry;
}

能力有限,不当之处请多多指正!!
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值