应用动态显示在桌面Launcher

启用禁用组件基础知识

PackageManager pm = getPackageManager();
pm.setComponentEnabledSetting(componentName,
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); // 禁用该componentName组件,如果带有category.LAUNCHER,则不会显示在Launcher上
pm.setComponentEnabledSetting(componentName,                                                        PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); // 启用componentName组件

应用动态出现在Launcher上

要应用出现在Launcher上,则启用组件,不出现则禁用组件.我们只需在适当时候做启用和禁用操作即可.一般是通过广播实现.比如当有SIM卡时应用出现,没有SIM则不出现.

public class BootCompletedReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        if (action == null) {
            return;
        }
        if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
            // 刚开机卡先禁用组件
            disableComp(yourCompName);
        }else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
            String SIMStatus = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
            if(!(IccCardConstants.INTENT_VALUE_ICC_ABSENT).equals(SIMStatus)){
                // 其他状态的卡说明存在卡,则启用组件
                enableComp(yourCompName);
            }else{
                // 卡处于ABSENT状态则取消图标显示,也就是引用带有Launcher的Category的组件
                disableComp(yourCompName);
            }
        }
    }
    // 启用组件
    public static void enableComp(ComponentName compName){
        PackageManager pm = getPackageManager();
        pm.setComponentEnabledSetting(compName,
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,     PackageManager.DONT_KILL_APP);
    }
    // 禁用组件
    public static void disableComp(ComponentName compName) {
        PackageManager pm = getPackageManager();
        pm.setComponentEnabledSetting(compName,
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,    PackageManager.DONT_KILL_APP);
    }
}

AndroidManifest.xml

<receiver android:name="com.nan.breeze.BootCompletedReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <action android:name="android.intent.action.SIM_STATE_CHANGED" />
    </intent-filter>
</receiver>

应用动态替换图标

既然可以动态禁用启用组件,再通过</activity-alias>属性,我们就可以实现在不更新应用的情况下替换应用图标. 从而实现类似天猫双11图标替换的效果

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>

属性解释

属性含义
enabled是否生效。配置多个activity-alias时,如果只想一个生效,就设置一个为true
exported是否可以被其他应用调起,配置intent-filter时默认为true,未配置intent-filter时默认为false,只能被应用自身调起
icon自定义生效时的icon
label作用同Activity标签中的label属性,主要表现为桌面上的app名称和activity的title的名称
name该activity-alias的名字
permission指明通过别名声明调起目标Activity所必需的权限
targetActivity指明目标Activity,类似于Activity标签中的name属性,需写明包类路径。表明通过activity-alias调起的是哪个Activity

示例

AndroidManifest.xml

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="Android ICON"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity-alias
        android:name=".MainAliasActivity"
        android:targetActivity=".MainActivity"
        android:icon="@mipmap/ic_launcher_change"
        android:enabled="false">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>
</application>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent">
    <Button
        android:layout_margin="10dp"
        android:id="@+id/btn_change_to_alias"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="切换至alias图标" />
    <Button
        android:layout_margin="10dp"
        android:id="@+id/btn_change_to_default"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="切换至默认图标" />
</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }
    private void initView() {
        Button changeToAlias = (Button) findViewById(R.id.btn_change_to_alias);
        Button changeToDefault = (Button) findViewById(R.id.btn_change_to_default);
        changeToAlias.setOnClickListener(this);
        changeToDefault.setOnClickListener(this);
    }
    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_change_to_alias:
                changeIcon("com.nan.breeze.MainActivity");
                break;
            case R.id.btn_change_to_default:
                changeIcon("com.nan.breeze.MainAliasActivity");
                break;
            default:
                break;
        }
    }
    public void changeIcon(String activityPath) {
        PackageManager pm = getPackageManager();
        pm.setComponentEnabledSetting(getComponentName(),
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
        pm.setComponentEnabledSetting(new ComponentName(this, activityPath),
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
        //重启桌面 加速显示 
//        restartSystemLauncher(pm);
    }
    public void restartSystemLauncher(PackageManager pm) {
        ActivityManager am = (ActivityManager) getSystemService(Activity.ACTIVITY_SERVICE);
        Intent i = new Intent(Intent.ACTION_MAIN);
        i.addCategory(Intent.CATEGORY_HOME);
        i.addCategory(Intent.CATEGORY_DEFAULT);
        List<ResolveInfo> resolves = pm.queryIntentActivities(i, 0);
        for (ResolveInfo res : resolves) {
            if (res.activityInfo != null) {
                // 调用该方法需要增加权限
                // <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
                am.killBackgroundProcesses(res.activityInfo.packageName);
            }
        }
    }
}

杀死桌面更换应用图标对用户有些突兀,我们只需在适当时候禁用启用,Launcher延时一会刷新图标也不失为一种选择.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值