共计 4483 个字符,预计需要花费 12 分钟才能阅读完成。
一、背景
近日,微博官网公布了一项新性能,即能够在 App 设置中动静更换微博的显示图标款式。依据微博官网的说法,除了最原始的图标外,微博还推出了另外 10 种不同的款式,既有 3D 微博、炫彩微博等保留了眼睛造型的新款式,也有奶酪甜馨、巧克力等以食物命名的“新口味”,还有梦幻紫、空想星空等抽象派新造型,给了微博用户多种抉择的自在。
不过须要留神的是,这一性能并不是面对所有人凋谢的,只有微博年费会员能力享受。此外,iOS 10.3 及以上和 Android 10 及以上零碎版本反对该性能,然而 iPad 与一加 8Pro 手机无奈应用该性能。因局部手机存在零碎差别,会导致该性能不可用,微博方面后续还会对该性能进行进一步优化。
二、技术实现
其实,说到底,上述性能用到的是动静更换桌面图标的技术。如果说多年以前,实现图标的切换还是一种时尚的技术,那么,咱们能够间接应用 PackageManager 就能够实现动静更换桌面图标。
实现的细节是,在 Manifest 文件中应用标签筹备多个 Activity 入口,没个 activity 都指向入口 Activity,并且为每个领有标签的 activity 设置独自的 icon 和利用名,最初调用 SystemService 服务 kill 掉 launcher,并执行 launcher 的重启操作。
首先,咱们在 AndroidManifest.xml 文件中增加如下代码:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.xzh.demo">
<!-- 权限 -->
<uses-permission android: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>
<action android:name="android.intent.action.MAIN" />
<category android: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>
<action android:name="android.intent.action.MAIN" />
<category android: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 图标更换逻辑,代码如下:
class MainActivity : AppCompatActivity() {var list: List<LogoBean> = ArrayList()
var recyclerView: RecyclerView? = null
var adapter: LogoAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initView()
initData()
initRecycle()}
private fun initView() {recyclerView = findViewById(R.id.recycle_view)
}
private fun initData() {
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),
)
}
private fun initRecycle() {adapter =LogoAdapter(this,list);
val layoutManager = GridLayoutManager(this, 3)
recyclerView?.layoutManager = layoutManager
recyclerView?.adapter = adapter
adapter?.setOnItemClickListener(object : OnItemClickListener {override fun onItemClick(view: View?, position: Int) {if(position==1){changeLogo("com.xzh.demo.threedweibo")
}else if (position==2){changeLogo("com.xzh.demo.cheese")
}else if (position==3){changeLogo("com.xzh.demo.chocolate")
}else {changeLogo("com.xzh.demo.default")
}
}
})
}
fun changeLogo(name: String) {
val pm = 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)
}
fun reStartApp(pm: PackageManager) {val am = getSystemService(ACTIVITY_SERVICE) as ActivityManager
val intent = Intent(Intent.ACTION_MAIN)
intent.addCategory(Intent.CATEGORY_HOME)
intent.addCategory(Intent.CATEGORY_DEFAULT)
val resolveInfos = pm.queryIntentActivities(intent, 0)
for (resolveInfo in resolveInfos) {if (resolveInfo.activityInfo != null) {am.killBackgroundProcesses(resolveInfo.activityInfo.packageName)
}
}
}
}
留神下面的 changeLogo()办法中的字符串须要和 AndroidManifest.xml 文件中的 <activity-alias>
的 name 绝对应。运行下面的代码,而后点击利用中的某个图标,就能够更换利用的桌面图标,如下图所示。
不过,测试的时候也遇到一些适配问题:
- 小米 9:版本升级时,新版本在 AndroidManifest 中删除 A3,老版本切换图标到 A3,为卸载间接笼罩装置新版本,手机桌面图标隐没。
- magic 4: 版本升级时,新版本在 AndroidManifest 中删除 A3,老版本切换图标到 A3,为卸载间接笼罩装置新版本,手机桌面图标切换到默认图标,但点击之后未能关上 APP。