Android 动态更换应用图标详情

近日,微博官方发布了一项新功能,即可以在App设置中动态更换微博的显示图标样式。根据微博官方的说法,除了最原始的图标外,微博还推出了另外10种不同的样式,既有3D微博、炫彩微博等保留了眼睛造型的新样式,也有奶酪甜馨、巧克力等以食物命名的“新口味”,还有梦幻紫、幻想星空等抽象派新造型,给了微博用户多种选择的自由。

不过需要注意的是,这一功能并不是面对所有人开放的,只有微博年费会员才能享受。此外,iOS10.3及以上和Android10及以上系统版本支持该功能,但是iPad与一加8Pro手机无法使用该功能。因部分手机存在系统差异,会导致该功能不可用,微博方面后续还会对该功能进行进一步优化。

图片[1]-Android 动态更换应用图标详情

技术实现

其实,说到底,上述功能用到的是动态更换桌面图标的技术。如果说多年以前,实现图标的切换还是一种时髦的技术,那么,我们可以直接使用PackageManager就可以实现动态更换桌面图标。

实现的细节是,在Manifest文件中使用标签准备多个Activity入口,没个activity都指向入口Activity,并且为每个拥有标签的activity设置单独的icon和应用名,最后调用SystemService服务kill掉launcher,并执行launcher的重启操作。

首先,我们在AndroidManifest.xml文件中添加如下代码:

<?xmlversion=”1.0″encoding=”utf-8″?>

<manifestxmlns:android=”http://schemas.android.com/apk/res/android”

xmlns:tools=”http://schemas.android.com/tools”

package=”com.xzh.demo”>

<!–权限–>

<uses-permissionandroid:name=”android.permission.KILL_BACKGROUND_PROCESSES”/>

<application

android:allowBackup=”true”

android:icon=”@mipmap/wb_default_logo”

android:label=”@string/app_name”

android:roundIcon=”@mipmap/wb_default_logo”

android:supportsRtl=”true”

android:theme=”@style/Theme.AndroidDemo”>

…//省略其他代码

<!–默认微博–>

<activity-alias

android:name=”com.xzh.demo.default”

android:targetActivity=”.MainActivity”

android:label=”@string/app_name”

android:enabled=”false”

android:icon=”@mipmap/wb_default_logo”

android:exported=”true”>

<intent-filter>

<actionandroid:name=”android.intent.action.MAIN”/>

<categoryandroid:name=”android.intent.category.LAUNCHER”/>

</intent-filter>

</activity-alias>

<!–3D微博–>

<activity-alias

android:name=”.threedweibo”

android:targetActivity=”.MainActivity”

android:label=”@string/wb_3d”

android:enabled=”false”

android:icon=”@mipmap/wb_3dweibo”

android:exported=”true”>

<intent-filter>

<actionandroid:name=”android.intent.action.MAIN”/>

<categoryandroid:name=”android.intent.category.LAUNCHER”/>

</intent-filter>

</activity-alias>

…//省略其他

</application>

</manifest>

上面配置中涉及到的属性如下:

android:name:注册的组件名字,启动组件的名称。android:enabled:是否启用这个组件,也就是是否显示这个入口。android:icon:图标android:label:名称android:targetActivity:默认的activity没有这个属性,指定目标activity,与默认的activity中的name属性是一样的,需要有相应的java类文件。

接着,我们在MainActivity触发Logo图标更换逻辑,代码如下:

classMainActivity:AppCompatActivity(){

varlist:List<LogoBean>=ArrayList()

varrecyclerView:RecyclerView?=null

varadapter:LogoAdapter?=null

overridefunonCreate(savedInstanceState:Bundle?){

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

initView()

initData()

initRecycle()

}

privatefuninitView(){

recyclerView=findViewById(R.id.recycle_view)

}

privatefuninitData(){

list=Arrays.asList(

LogoBean(R.mipmap.wb_default_logo,”默认图标”,true),

LogoBean(R.mipmap.wb_3dweibo,”3D微博”,false),

LogoBean(R.mipmap.wb_cheese_sweetheart,”奶酪甜心”,false),

LogoBean(R.mipmap.wb_chocolate_sweetheart,”巧克力”,false),

LogoBean(R.mipmap.wb_clear_colorful,”清透七彩”,false),

LogoBean(R.mipmap.wb_colorful_sunset,”多彩日落”,false),

LogoBean(R.mipmap.wb_colorful_weibo,”炫彩微博”,false),

LogoBean(R.mipmap.wb_cool_pool,”清凉泳池”,false),

LogoBean(R.mipmap.wb_fantasy_purple,”梦幻紫”,false),

LogoBean(R.mipmap.wb_fantasy_starry_sky,”幻想星空”,false),

LogoBean(R.mipmap.wb_hot_weibo,”热感微博”,false),

)

}

privatefuninitRecycle(){

adapter=LogoAdapter(this,list);

vallayoutManager=GridLayoutManager(this,3)

recyclerView?.layoutManager=layoutManager

recyclerView?.adapter=adapter

adapter?.setOnItemClickListener(object:OnItemClickListener{

overridefunonItemClick(view:View?,position:Int){

if(position==1){

changeLogo(“com.xzh.demo.threedweibo”)

}elseif(position==2){

changeLogo(“com.xzh.demo.cheese”)

}elseif(position==3){

changeLogo(“com.xzh.demo.chocolate”)

}else{

changeLogo(“com.xzh.demo.default”)

}

}

})

}

funchangeLogo(name:String){

valpm=packageManager

pm.setComponentEnabledSetting(

componentName,

PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP

)

pm.setComponentEnabledSetting(

ComponentName(this,name),

PackageManager.COMPONENT_ENABLED_STATE_ENABLED,PackageManager.DONT_KILL_APP

)

reStartApp(pm)

}

funreStartApp(pm:PackageManager){

valam=getSystemService(ACTIVITY_SERVICE)asActivityManager

valintent=Intent(Intent.ACTION_MAIN)

intent.addCategory(Intent.CATEGORY_HOME)

intent.addCategory(Intent.CATEGORY_DEFAULT)

valresolveInfos=pm.queryIntentActivities(intent,0)

for(resolveInfoinresolveInfos){

if(resolveInfo.activityInfo!=null){

am.killBackgroundProcesses(resolveInfo.activityInfo.packageName)

}

}

}

}

注意上面的changeLogo()方法中的字符串需要和AndroidManifest.xml文件中的<activity-alias>的name相对应。运行上面的代码,然后点击应用中的某个图标,就可以更换应用的桌面图标,

如下图所示:

图片[2]-Android 动态更换应用图标详情

不过,测试的时候也遇到

一些适配问题:

小米9:版本升级时,新版本在AndroidManifest中删除A3,老版本切换图标到A3,为卸载直接覆盖安装新版本,手机桌面图标消失。magic4:版本升级时,新版本在AndroidManifest中删除A3,老版本切换图标到A3,为卸载直接覆盖安装新版本,手机桌面图标切换到默认图标,但点击之后未能打开APP。

请登录后发表评论

    没有回复内容

  • 波浪
  • 波浪
  • 波浪
  • 波浪