无极安卓网

安卓手机图标弄成一样 安卓桌面图标自定义修改方法

来源:无极安卓网

安卓手机图标弄成一样,在日常使用安卓手机时,我们总会发现一些应用的图标与其他应用不太一样,让人感到不协调。不过你也许不知道,其实可以对这些图标进行自定义修改,让所有应用的图标风格更一致。本文将为大家介绍安卓桌面图标自定义修改方法,让你的手机界面更加舒适和美观。

安卓桌面图标自定义修改方法

坎坷在前,坦途在后。这里先把遇到的一些问题写在前面,为了便于各位看官能先了解有什么问题存在,
步骤心中有,双手直颤抖的情况一点也不鲜见,所以此处对问题做一个汇总。
1、动态替换icon,只能替换内置的icon,无法从服务器端获取来更新icon;
2、动态替换icon以后,应用内更新的时候必须要切换到原始icon,否则可能导致出现更新
   安装失败(AS上表现为adb运行会失败),或者升级后出现多个应用图标或者应用图标桌面不显示
   的情况(这些问题都可以通过下面的开发规则规避掉,这个坑不是绝对会发生,但是大多数人
   可能会遇到。);
3、Android系统动态更换Icon会有时延,在不同的手机系统上刷新Icon的时间有差别,大概率会在5~10s
   左右,在这个时间内点击icon会"提示应用未安装"(大致都是这个提示);
4、手机更换Icon后,有时候会在3~5s内,退回到桌面(有的可能是闪退)(这个问题和第2个问题有
   很大的相关性,按我下面的步骤操作可以解决该问题。

多入口配置

顾名思义就是配置应用程序多个入口,在AndroidManifest.xml中有一个叫activity-alias的标签,
望文生义,你理解的没错,就是activity别名,示例代码如下:

<activity-alias
     android:name="DefaultAlias" // 注册这个组件的名字,不需要创建该文件
     android:enabled="false"  // 桌面是否显示这个启动项
     android:label="支付宝"  // 显示的名称,也就是对应这个启动项显示在桌面上的app名称
     android:icon="@mipmap/ic_launcher" // Icon图标,也就是对应这个启动项显示在桌面上
                                           的app图标 
     android:targetActivity=".MainActivity"  //对应的原来的Activity组件,这里路径要跟
                                               注册的Activity对应。
     >
       <intent-filter> // LAUNCHER 启动入口
      <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.LAUNCHER" />
   </intent-filter>
  </activity-alias>

显示多个启动入口

如何做一个多个启动入口的app(桌面上显示多个图标),代码如下:


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.xk.ChangeIcon">
 
 <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
   
        <!--原Activity-->
        <activity
               android:enabled="true"
               android:name=".MainActivity">
               <intent-filter>
                      <action android:name="android.intent.action.MAIN" />
                      <category android:name="android.intent.category.LAUNCHER" />
               </intent-filter>
        </activity>
 
        <!--别名1-->
        <activity-alias
               android:name="NewActivity1"
               android:enabled="true"  // 这里设置的可是 true 哟
               android:label="Alias1"
               android:icon="@mipmap/ic_alias1_launcher"
               android:targetActivity=".MainActivity">
         <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
         </intent-filter>
        </activity-alias>
   
        <!--别名2-->
        <activity-alias
               android:name="NewActivity2"
               android:enabled="true" // 这里设置的可是 true 哟
               android:label="Alias2"
               android:icon="@mipmap/ic_alias2_launcher"
               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>

效果见下图,有图有真相
可以看到桌面上显示了三个图标,进入的都是MainActivity这个页面,
当然了,实际项目中我们只会显示一个图标,这里我们只需要
把"别名1"和"别名2"的android:enabled="true"改为"false"就行了,这样就只显示一个图标了,
就不放效果图了。

安卓手机图标弄成一样 安卓桌面图标自定义修改方法通过代码动态更换应用图标
今天是2020年1月17日,农历腊月23,也就是民俗中的小年,马上春节了,我们领导要求大年三十晚上
我们的应用Icon变换成春节特供Icon,到正月十五的晚上切换为原来的Icon。当然,前面说了这些图标
要预先设置在应用里。然后通过服务端提供的接口作为开关控制图标的切换。

下面贴代码喽
算了....你想骂就骂我吧,我混蛋,我下贱.....咳,还是贴点吧。

        PackageManager  mPackageManager = getApplicationContext().getPackageManager();
        //拿到默认的组件
        ComponentName defaultComponent = new ComponentName(getBaseContext(). 
                     "com.xk.ChangeIcon.DefaultAlias");  
        //拿到我注册的别名ChangeIcon组件
       ComponentName  newComponent = new ComponentName(getBaseContext(). 
                    "com.xk.ChangeIcon.ChangeIcon");

    /**
     * 启用组件
     *
     * @param componentName
     */
    private void enableComponent(ComponentName componentName) {
        int state = mPackageManager.getComponentEnabledSetting(componentName);
        if (state == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
            //已经启用
            return;
        }
        mPackageManager.setComponentEnabledSetting(componentName.
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED.
                PackageManager.DONT_KILL_APP);
    }

    /**
     * 禁用组件
     *
     * @param componentName
     */
    private void disableComponent(ComponentName componentName) {
        int state = mPackageManager.getComponentEnabledSetting(componentName);
        if (state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
            //已经禁用
            return;
        }
        mPackageManager.setComponentEnabledSetting(componentName.
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED.
                PackageManager.DONT_KILL_APP);
    }


特别说明:ComponentName里面的路径一定要写全了,如果在报错日志看到类似找不到这个路径的日志
的话,那十有八九就是这个问题了。

其实切换的代码很少,逻辑也很简单,啥?你还看不明白?蹲墙根去.....不解释。
这里我基于隐藏Alias2别名和MainActivity的情况下,显示Alias1 Icon的情况,见图如面:

安卓手机图标弄成一样 安卓桌面图标自定义修改方法
可以看到只显示这一个入口了,但是如果执行切换Icon的代码之后,退回到桌面观察App的Icon,
你会发现会在5~10s内才会更改,再者,在没有更换成功的时候如果我们点这个原来的App Icon,
会有"提示应用未安装"的提示。至此,通过代码我们已经实现了Icon的切换,但是!!!
这就完了??你以为这就完了??
走两步,,听我口令,走两步......一口老血喷出口......这么多bug.....继续往下看

你发现了什么问题?
更换了Icon之后,你停留在app打开的界面(不要通过手动回到桌面),也就那么一会儿,倏尔、
一刹那、一瞬间.....应用自动会到了桌面类似于应用发生了闪退,这就是前面提到的坑4这个问题。
为什么会这样子?
经过多次测试,原来是是因为代码里面设置了我们原来的真实的那个MainActiviy的enable为false,
就是下面这行代码:

  mPackageManager.setComponentEnabledSetting(componentName.
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED.
                PackageManager.DONT_KILL_APP);

只要代码设置了真实的那个Activity的enable为false,
也就是代码对应的PackageManager.COMPONENT_ENABLED_STATE_DISABLED,那就会导致我们的应用闪退,
那是不是我们不设置这个就好了呢?那我们不设置这个的话怎么隐藏真实的MainActivity的图标呢?
这里先卖个关子。

你以为只有这个问题吗?淡定,其实还有坑,只是这个坑不容易发现,这个时候我们回到我们当前
的情况,也就是当前我们已经切换到"Alias2"了,桌面上也只有这个图标了,我们也能点击这个图标
正常使用我们的应用,这些都没有问题,我们以为都是正常的了。
但是,这个时候,使用Android Studio运行项目的时候,会提示launch app失败,
控制台输出信息如下:

Error while executing: am start -n "com.xk.ChangeIcon/com.xk.ChangeIcon.MainActivity" -a 
android.intent.action.MAIN -c android.intent.category.LAUNCHER
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER]
 cmp=com.xk.ChangeIcon/.MainActivity }
Error type 3
Error: Activity class {com.xk.ChangeIcon/com.xk.ChangeIcon.MainActivity} does not exist.

Error while Launching activity

你以为坑完了,当然不会,因为开篇提到了4个坑,当然下文都会给出相关的解决方法。
就是我们代码动态更换了App Icon之后,在应用升级(更新应用)的时候,会导致安装失败,
或者是安装完成后出现多个图标甚至是没有图标出现在桌面上了!!这些问题是要遇到运行,
或者升级包的时候才会发现的。卧槽,菜都上桌了,你才发现氯化钠放多了,
这能忍???忍一时风平浪静,滚犊子..... 这就是我在前面提到的坑2这个点。

这里还有一种情况也会导致坑2的发生,例如,我们Demo现在是一个MainActivity和两个别名,
如果我们在下一个版本把这两个别名删除了,或者删除了我们当前安装包正在显示的别名,
那么安装的新版本可能就不会有应用图标显示了,那就会导致我们应用安装成功了,但是却没有入口!
类似的问题还有一些,主要都是在应用升级后发生,而且不管是导致安装失败、安装后没有图标
或者安装后产生多个图标,这些现象都是非常严重的,但是这些问题我们都是可以避免的。
做了这么多铺垫,真像唐僧,下面上主菜。

动态更换应用图标填坑指南

1、Activity的android:enabled属性,一定不要在代码里面去设置enabled这个值。否则会在切换图标的
   过程导致应用闪退,目前测试了小米、华为和官方模拟器都有在这个问题。
2、清单文件中设置Activity的android:enabled="false”.这个在之后的版本就固定这个值,如果设置
   为true了,则有可能在应用升级后出现多个图标;
3、然后为我们的应用设置一个默认的Activity-alias用来显示图标(也是唯一一个显示的,一般我们也
   只需要显示一个图标),也是用来代替第一点设置Activity的android:enabled="false”可能导致的
   桌面上没有应用图标的问题;
4、Activity-alias的android:enabled="true"的默认显示的项尽可能不要中途进行变动,如果确实需要
  使用新的默认值,则使用代码进行动态变换;
5、Activity-alias的android:enabled="true"的不要设置为多个,否则会出现多个图标,如果试图通过
  代码进行隐藏其中的一个或者几个,可能会出现图标消失的情况,这个第2点已经有提过了;
6、后面新的版本如果要加新的Activity-alias,那么都要设置android:enabled=“false”,这个清单
   文件中的值要设置成false,然后再通过代码动态变换;
7、后面新的版本的Activity-alias必须包含上一个版本的所有Activity-alias,主要是防止覆盖安装后
   应用图标消失的情况;

以上就是在做这个功能的过程中总结出来的规律,目前暂时没有发现在其它的问题。还有,按照这些
规则做的话,覆盖安装后的应用图标也会是你上一次通过代码动态修改成功的图标,因为手机的Launcher
会有记录,也就是我们通过代码会修改这个在Launcher中的记录。
对了,我们在清单文件中配置的Activity和Activity-alias的icon和label信息在新的版本中都是可以
换的,这些跟代码无关了,也就是跟我们平常换下app图标名称是一样的操作,希望大家不要误解了这里
。

所有的想法都要落地为产品

有的看官会心生疑问了,假如现在的应用入口就是默认的一个Activity,默认的enable也是true,
也没有配置任何的Activity-alias,而上文中提到建议清单文件中
的Activity的android:enabled="false”,那新版本设置成false会不会导致桌面Icon入口不见了呢?
可以确切的说,如果按照上文的步骤对你的新版本(可以动态切换图标的版本)进行设置的话,
是不会有以上情况产生的,光说不练,就是混蛋,上清单文件的示例代码:


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.xk.ChangeIcon">
 
 <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher_round"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
 
        <!--原Activity enabled固定为false,且不通过代码进行设置 -->
        <activity
               android:enabled="false"
               android:name=".MainActivity">
         <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
         </intent-filter>
        </activity>
 
        <!-- 固定设置一个默认的别名,用来替代原Activity-->
        <activity-alias
               android:name="DefaultAlias"
               android:enabled="true"
               android:label="@string/app_name"
               android:icon="@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-alias
               android:name=".ChangeIcon"
               android:enabled="false"
               android:label="Alias1"
               android:icon="@mipmap/ic_launcher"
               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>

打完收工

安卓手机图标的自定义修改方法有很多,我们可以从应用商店下载图标包,也可以使用第三方应用更改图标。无论是哪种方法,都可以让我们的手机桌面更加个性化和美观。希望大家都能找到自己喜欢的图标,让手机变得更加舒适和有趣。

相关文章

猜你喜欢