Android 轻松打造一个APP动态切换桌面图标Launcher

时间:2022-10-30 23:50:36

动态更换应用Icon

原理1——activity-alias,清单文件Activity的属性

Alias:打包签名的时候经常看到是:别名的意思

activity-alias
1.是android里为了重复使用Activity而设计的。
2.这个属性可以用于创建多个不同的入口,相信做过系统Setting和Launcher开发的开发者在系统的源码中应该见过很多。

原理2——PackageManager

PackageManager是一个大统领类,可以管理所有的系统组件,得到系统的一些解析APK应用

        PackageManager pkgMgr = mContext.getPackageManager();
        // 获取手机内所有应用
        List<ApplicationInfo> list = pkgMgr.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);

//设置当前的组件有效
public void enableComponet(ComponentName componentName){
    mPm.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
}

//设置组件无效
public void disableComponent(ComponentName componentName){
    mPm.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
}

下面在清单文件里面声明:
  
<activity-alias
    android:name=".Test11"
    android:enabled="false"
    android:icon="@drawable/ic_launche_tidy"
    android:label="图标1"
    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=".Test12"
    android:enabled="false"
    android:icon="@drawable/logo"
    android:label="图标2"
    android:targetActivity=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>

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

在主程序测试:

package launcher.peng.cx.com.launcher;

import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    private ComponentName mDefault;
    private ComponentName mDouble11;
    private ComponentName mDouble12;
    private PackageManager mPm;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //得到组件,Android4大组件之一
        mDefault=getComponentName();
        mDouble11=new ComponentName(getBaseContext(),"launcher.peng.cx.com.launcher.Test11");
        mDouble12=new ComponentName(getBaseContext(),"launcher.peng.cx.com.launcher.Test12");
        mPm=getApplicationContext().getPackageManager();

        Button btn1,btn2;

        btn1=(Button)findViewById(R.id.btn_tubiao1);
        btn2=(Button)findViewById(R.id.btn_tubiao2);

        btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                changeIcon1();
            }
        });

        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                changeIcon2();
            }
        });
    }

    public void changeIcon1(){
        disableComponent(mDefault);
        disableComponent(mDouble12);
        enableComponet(mDouble11);
    }

    public void changeIcon2(){
        disableComponent(mDefault);
        disableComponent(mDouble11);
        enableComponet(mDouble12);
    }

    //设置当前的组件有效
    public void enableComponet(ComponentName componentName){
        mPm.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
    }

    //设置组件无效
    public void disableComponent(ComponentName componentName){
        mPm.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
    }

OK了,禁用默认的Activity后,启用双11的activity-alias,结果不变还是指向了默认的Activity,但图标已经发生了改变。

根据ROM的不同,在禁用了组件之后,会等一会,Launcher会自动刷新图标。


 注意

(1)在AndroidManifest.xml 文件中,新的 <activity> 必须放在 <activity-alias>之前定义,否则重定向可能会失败.


AS源码地址:http://download.csdn.net/detail/whb20081815/9775981