在 Android 系统中,每个应用程序都有一个唯一的图标和名称,这些信息通常是在应用程序安装时设置的。但是,有时候可能需要在应用程序运行时动态地改变应用程序的图标和名称,例如在不同的场景下使用不同的图标和名称来区分应用程序。

activity-alias 是 Android 中的一种特殊的 Activity 标签,它可以用来为一个 Activity 创建一个别名,允许用户通过不同的入口进入同一个 Activity。这个别名 Activity 具有与原始 Activity 相同的功能和属性,但可以通过不同的 intent-filter 和 name 属性来定义不同的入口。

activity-alias 并不是代表一个 Activity,而是代表一个已经存在的 Activity 的别名。

1. 语法说明

activity-alias 的语法如下所示:

<activity-alias android:enabled=["true" | "false"]
                android:exported=["true" | "false"]
                android:icon="drawable resource"
                android:label="string resource"
                android:name="string"
                android:permission="string"
                android:targetActivity="string" >
    ...
</activity-alias>

属性说明: android:enabled:确定系统是否可以通过此别名实例化目标 Activity。如果可以,则设为 true,否则设为 falseandroid:exported:确定其他应用的组件是否可以通过此别名启动目标 Activity。如果可以,则设为 true,否则设为 false。 如果设为 false,则只有与别名在同一应用中的组件或具有同一用户 ID 的应用的组件可以通过别名启动目标 Activity。 android:icon:通过别名呈现给用户时,目标 Activity 的图标,可以理解为桌面上的应用图标。 android:label:通过别名呈现给用户时,别名的用户可读标签,可以理解为桌面上的应用名称。 android:name:别名的唯一名称,该名称类似于完全限定的类名称。但是,与目标 Activity 的名称不同,别名名称是任意的,它不引用实际类。 android:permission:客户端要使用别名启动目标 Activity 或让其执行某项操作而必须具备的权限的名称。如果未设置此属性,则无需权限即可通过别名激活目标。 android:targetActivity:可通过别名激活的 Activity 的名称。此名称必须与清单中别名前面 <activity> 元素的 name 属性匹配。

2. 操作步骤

2.1 向资源目录中添加一组新的 ICON

应用级模块 的资源目录(通常是<project>/<app-module>/src/main/res 目录下的 drawable/mipmap 目录)中添加一组新的图标集,并自定义名称。像添加 App 图标一样,把所有需要尺寸的图标都添加到 drawable/mipmap 目录中即可。

2.2 在清单文件中设置应用入口 Activity 的别名

资源添加完成后,在 AndroidManifest.xml 文件中设置应用入口 Activity 的别名,示例代码如下:

<application
    android:name="com.sf.sdk.demo.AppApplication"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    <activity
        android:name="com.sf.sdk.demo.MainActivity"
        android:configChanges="keyboardHidden|orientation|screenSize"
        android:exported="true"
        android:theme="@style/MainTheme">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <action android:name="android.intent.action.VIEW" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <activity-alias
        android:name="com.sf.sdk.demo.MainAlias"
        android:enabled="false"
        android:exported="true"
        android:icon="@mipmap/main_alias_launcher"
        android:label="@string/main_alias_name"
        android:targetActivity="com.sf.sdk.demo.MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <action android:name="android.intent.action.VIEW" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>

</application>

3. 代码进行图标切换

通过 android.content.pm.PackageManager#setComponentEnabledSetting() 方法启用/禁用组件来实现应用图标切换。

3.1 启用组件

public void enableComponent(Context context, ComponentName componentName) {
    PackageManager packageManager = context.getPackageManager();
    packageManager.setComponentEnabledSetting(componentName,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP);
}

3.2 禁用组件

public void disableComponent(Context context, ComponentName componentName) {
    PackageManager packageManager = context.getPackageManager();
    packageManager.setComponentEnabledSetting(componentName,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP);
}

4. 具体方案

切换应用图标会导致系统关闭应用进程,这里提供一种实现方案,具体方案如下:

  1. 控制图标显示:冷启动 App 时,调用接口判断是否需要切换 Icon。
  2. 触发时机:监听 App 前后台切换,当 App 切换到后台时切换应用图标,使得用户无感知。

5. 注意事项

  • 切换 Icon 会关闭应用进程,不是崩溃所以不会上报崩溃日志。
  • 切换 Icon 需要时间,部分机型需要几秒左右,之后能正常打开。
  • 切换 Icon 过程中,部分机型点击图标无法打开应用,提示应用未安装。
  • 该方案无法动态加载网络图片,只能切换本地资源内置的图标。
  • 该功能最好通过服务端配置控制具体显示哪个 Icon。

results matching ""

    No results matching ""