欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > Android 动态修改APP图标

Android 动态修改APP图标

2024/10/24 12:32:04 来源:https://blog.csdn.net/qq_14876133/article/details/139504432  浏览:    关键词:Android 动态修改APP图标

文章目录

  • Android 动态修改APP图标
    • 定义activity-alias
    • 修改图标和App名
    • 监听APP前后台状态切换
    • 进入后台时切换修改图标和名字
    • 缺点

Android 动态修改APP图标

修改前:

在这里插入图片描述

修改后:

在这里插入图片描述

定义activity-alias

在 AndroidManifest.xml 中设置 activity-alias:

activity-alias标签中的属性:

标签作用
android:name别名
android:enabled是否启用别名
android:icon应用图标
android:label应用名
android:targetActivity必须指向原入口Activity

下面定义了2个alias标签:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.myapplication"><applicationandroid:name=".BaseApplication"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/Theme.MyApplication"><activity android:name=".SecondActivity" /><activity android:name=".MainActivity" /><activity-aliasandroid:name=".DefaultAliasActivity"android:enabled="true"android:exported="true"android:icon="@mipmap/ic_launcher"android:roundIcon="@mipmap/ic_launcher_round"android:targetActivity=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity-alias><activity-aliasandroid:name=".TaobaoAliasActivity"android:enabled="false"android:exported="true"android:icon="@mipmap/ic_taobao"android:label="taobao"android:targetActivity=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity-alias></application></manifest>

修改图标和App名

object AliasUtils {private const val DEFAULT_ALIAS = "com.example.myapplication.DefaultAliasActivity"private const val TAOBAO_ALIAS = "com.example.myapplication.TaobaoAliasActivity"fun setDefaultAlias(context: Context) {context.packageManager.apply {setComponentEnabledSetting(ComponentName(context, DEFAULT_ALIAS),PackageManager.COMPONENT_ENABLED_STATE_ENABLED,PackageManager.DONT_KILL_APP)setComponentEnabledSetting(ComponentName(context, TAOBAO_ALIAS),PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP)}}fun setTaobaoAlias(context: Context) {context.packageManager.apply {setComponentEnabledSetting(ComponentName(context, TAOBAO_ALIAS),PackageManager.COMPONENT_ENABLED_STATE_ENABLED,PackageManager.DONT_KILL_APP)setComponentEnabledSetting(ComponentName(context, DEFAULT_ALIAS),PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP)}}
}

监听APP前后台状态切换

class BaseApplication : Application() {companion object {private lateinit var INSTANCE: BaseApplicationfun getInstance(): BaseApplication {return INSTANCE}}override fun onCreate() {super.onCreate()INSTANCE = thisActivityManager.getInstance().init(INSTANCE)}
}
public final class ActivityManager implements Application.ActivityLifecycleCallbacks {private static volatile ActivityManager sInstance;/*** Activity 存放集合*/private final ArrayMap<String, Activity> mActivitySet = new ArrayMap<>();/*** 应用生命周期回调*/private final ArrayList<ApplicationLifecycleCallback> mLifecycleCallbacks = new ArrayList<>();/*** 当前应用上下文对象*/private Application mApplication;/*** 栈顶的 Activity 对象*/private Activity mTopActivity;/*** 前台并且可见的 Activity 对象*/private Activity mResumedActivity;private ActivityManager() {}public static ActivityManager getInstance() {if (sInstance == null) {synchronized (ActivityManager.class) {if (sInstance == null) {sInstance = new ActivityManager();}}}return sInstance;}public void init(Application application) {mApplication = application;mApplication.registerActivityLifecycleCallbacks(this);}/*** 获取 Application 对象*/public Application getApplication() {return mApplication;}/*** 获取栈顶的 Activity*/@Nullablepublic Activity getTopActivity() {return mTopActivity;}/*** 获取前台并且可见的 Activity*/@Nullablepublic Activity getResumedActivity() {return mResumedActivity;}/*** 判断当前应用是否处于前台状态*/public boolean isForeground() {return getResumedActivity() != null;}/*** 注册应用生命周期回调*/public void registerApplicationLifecycleCallback(ApplicationLifecycleCallback callback) {mLifecycleCallbacks.add(callback);}/*** 取消注册应用生命周期回调*/public void unregisterApplicationLifecycleCallback(ApplicationLifecycleCallback callback) {mLifecycleCallbacks.remove(callback);}/*** 销毁指定的 Activity*/public void finishActivity(Class<? extends Activity> clazz) {if (clazz == null) {return;}String[] keys = mActivitySet.keySet().toArray(new String[]{});for (String key : keys) {Activity activity = mActivitySet.get(key);if (activity == null || activity.isFinishing()) {continue;}if (activity.getClass().equals(clazz)) {activity.finish();mActivitySet.remove(key);break;}}}/*** 销毁所有的 Activity*/public void finishAllActivities() {finishAllActivities((Class<? extends Activity>) null);}/*** 销毁所有的 Activity** @param classArray 白名单 Activity*/@SafeVarargspublic final void finishAllActivities(Class<? extends Activity>... classArray) {String[] keys = mActivitySet.keySet().toArray(new String[]{});for (String key : keys) {Activity activity = mActivitySet.get(key);if (activity == null || activity.isFinishing()) {continue;}boolean whiteClazz = false;if (classArray != null) {for (Class<? extends Activity> clazz : classArray) {if (activity.getClass().equals(clazz)) {whiteClazz = true;}}}if (whiteClazz) {continue;}// 如果不是白名单上面的 Activity 就销毁掉activity.finish();mActivitySet.remove(key);}}@Overridepublic void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {if (mActivitySet.size() == 0) {for (ApplicationLifecycleCallback callback : mLifecycleCallbacks) {callback.onApplicationCreate(activity);}}mActivitySet.put(getObjectTag(activity), activity);mTopActivity = activity;}@Overridepublic void onActivityStarted(@NonNull Activity activity) {}@Overridepublic void onActivityResumed(@NonNull Activity activity) {if (mTopActivity == activity && mResumedActivity == null) {for (ApplicationLifecycleCallback callback : mLifecycleCallbacks) {callback.onApplicationForeground(activity);}}mTopActivity = activity;mResumedActivity = activity;}@Overridepublic void onActivityPaused(@NonNull Activity activity) {}@Overridepublic void onActivityStopped(@NonNull Activity activity) {if (mResumedActivity == activity) {mResumedActivity = null;}if (mResumedActivity == null) {for (ApplicationLifecycleCallback callback : mLifecycleCallbacks) {callback.onApplicationBackground(activity);}}}@Overridepublic void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {}@Overridepublic void onActivityDestroyed(@NonNull Activity activity) {mActivitySet.remove(getObjectTag(activity));if (mTopActivity == activity) {mTopActivity = null;}if (mActivitySet.size() == 0) {for (ApplicationLifecycleCallback callback : mLifecycleCallbacks) {callback.onApplicationDestroy(activity);}}}/*** 获取一个对象的独立无二的标记*/private static String getObjectTag(Object object) {// 对象所在的包名 + 对象的内存地址return object.getClass().getName() + Integer.toHexString(object.hashCode());}/*** 应用生命周期回调*/public interface ApplicationLifecycleCallback {/*** 第一个 Activity 创建了*/void onApplicationCreate(Activity activity);/*** 最后一个 Activity 销毁了*/void onApplicationDestroy(Activity activity);/*** 应用从前台进入到后台*/void onApplicationBackground(Activity activity);/*** 应用从后台进入到前台*/void onApplicationForeground(Activity activity);}
}

进入后台时切换修改图标和名字

override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)ActivityManager.getInstance().registerApplicationLifecycleCallback(object :ActivityManager.ApplicationLifecycleCallback {override fun onApplicationCreate(activity: Activity?) {}override fun onApplicationDestroy(activity: Activity?) {}override fun onApplicationBackground(activity: Activity?) {Log.e("TAG", "App处于后台")if (type == TYPE_DEFAULT) {AliasUtils.setDefaultAlias(this@MainActivity)} else if (type == TYPE_TAOBAO) {AliasUtils.setTaobaoAlias(this@MainActivity)}}override fun onApplicationForeground(activity: Activity?) {Log.e("TAG", "App处于前台")}})
}

缺点

  • 切换图标时,应用会自动退出,因此放在后台执行相对有好些。
  • 切换图标是一个耗时过程,1s~10s不等。
  • 在切换图标过程中,点击App图标,可能会提示“应用数据读取失败”等。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com