客户给了一套应用icon图片,要求替换当前应用的icon,实现如下.
将要替换的应用包名存放在字符串数组中:
<string-array name="icon_package" translatable="false">
<!-- 相机 -->
<item>.camera2</item>
<!-- 浏览器 -->
<item>,</item>
<!-- 联系人 -->
<item></item>
<!-- 电话 -->
<item></item>
<!-- 图库 -->
<item>.gallery3d</item>
<!-- 音乐 -->
<item></item>
<!-- 设置 -->
<item></item>
<!-- 应用商店 -->
<item></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获取应用图标时都会经过一个类,
代码路径:packages/apps/Launcher3/src/com/android/launcher3/
在中找到函数:cacheLocked
函数中有下面几行代码:
= (
getFullResIcon(info), (), mContext,
().getApplicationInfo().targetSdkVersion);
没错这里就是设置应用icon的地方了,下面就需要我们在这里替换客户提供的应用icon了。
首先获取存放包名的字符串数组:
private String getIconPackage(int i){
String[] arr = ().getStringArray(.icon_package);
return arr[i];
}
再通过存放icon图片名称的数组得到对应图片的资源ID:
private int getIconId(int i){
String[] imageNameArr = ().getStringArray(.icon_image);
String imageName = null;
if(!(imageNameArr[i])){
//获取图片的名称,去掉后缀
imageName = imageNameArr[i].substring(0, imageNameArr[i].indexOf("."));
}
//通过图片名称获取图片的资源ID
int resId = ().getIdentifier(imageName, "drawable" , ());
return resId;
}
然后再实现替换应用icon的功能:
private void setAppIconTheme(ComponentName componentName,
Provider<LauncherActivityInfo> infoProvider,
LauncherActivityInfo info,
CacheEntry entry){
String[] arr = ().getStringArray(.icon_package);
//通过for循环取数组中的包名和系统应用的包名对比,匹配上则替换该应用的icon,替换成功就结束函数
for (int i = 0; i < ; i++) {
("lp","()="+());
//这里判断字符串包含而不是相等,这样的好处我们可以在包名数组中的单个item中存放同类功能的不同应用,
//比如邮箱存放如下:
//<!-- 邮箱 -->
//<item>,</item>
if(getIconPackage(i).contains(())){
("lp","packageName("+ i +")="+getIconPackage(i));
= ((),getIconId(i));
return;
}
}
//for循环没匹配到,则执行默认代码
= (
getFullResIcon(info), (), mContext,
().getApplicationInfo().targetSdkVersion);
}
接下来就用函数setAppIconTheme替换系统默认的代码:
protected CacheEntry cacheLocked(
@NonNull ComponentName componentName,
@NonNull Provider<LauncherActivityInfo> infoProvider,
UserHandle user, boolean usePackageIcon, boolean useLowResIcon) {
...........
...........
//此处省略
...........
...........
//用函数setAppIconTheme替换系统默认的代码:
if (().getBoolean(.config_app_icon_theme)) {
setAppIconTheme(componentName, infoProvider, info, entry);
}else {
= ( getFullResIcon(info),
(), mContext,
().getApplicationInfo().targetSdkVersion);
}
...........
...........
//此处省略
...........
...........
return entry;
}
能力有限,不当之处请多多指正!!