Android10.0应用图标隐藏方案(7.0-10.0)

Android7.0 - 9.0应用图标隐藏

Android1.0到9.0隐藏应用图标的方法很简单,只需要AndroidManifest.xml文件中的MainActivity中添加代码:

 <data android:host="MainActivity" android:scheme="com.learn.alias.target"
            tools:ignore="AppLinkUrlError" />

示例如下:

<activity
    android:name="com.learn.alias.target.MainActivity"
    android:excludeFromRecents="true"
    android:exported="true"
    android:finishOnTaskLaunch="false"
    android:launchMode="singleInstance">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <data android:host="MainActivity" android:scheme="com.learn.alias.target"
            tools:ignore="AppLinkUrlError" />
    </intent-filter>
</activity>

即可完成对应用图标的隐藏。不过这里需要注意一下,
android:scheme是大小写敏感的,必须以小写字母开头。
scheme设置后表示这个MainActivity可以响应Uricom.learn.alias.target的特定Intent

另外为什么加入这个之后app就不显示图标了呢?
因为这里把app的入口Activity声明为由接收隐式的Intent来启动,也就不会显示图标了。

外部隐式启动方式:

String scheme = "com.learn.alias.target";
Intent intent = new Intent();
intent.setComponent(new ComponentName(pkgName, clsName));
// 这里传设置好的scheme值
intent.setData(Uri.parse(scheme));
startActivity(intent);

这种方式既能隐藏图标,又可以被外部应用隐式启动,在Android系统10.0以下,这个方式是可以用的。但是Android系统10.0却不能用,下面就来做一下Android10.0的图标隐藏方式。

Android10.0应用图标隐藏

问题:上面的方法在Android10.0上为什么失效?

Android 10 限制了应用隐藏其启动器图标的能力。如果某个应用没有已启用的启动器 Activity,则系统会在启动器中显示一个合成的 Activity;此合成的 Activity 代表该应用在系统设置中的详情页面。
除非满足以下任一条件,否则应用必须具有图标:

  • 它是系统应用,即使是更新后的应用。
  • 它是托管式配置文件管理应用(工作资料所有者)。
  • 它未请求任何权限。
  • 它不包含任何组件(例如,Activity、内容提供程序、广播接收器和服务)。
  • 具有图标且拥有已启用的可启动 Activity 的应用不受影响。除了上面列出的例外情况,所有应用均会显示一个图标。如果应用没有图标,则会显示默认的系统图标。点按没有可启动 Activity 的应用图标时会打开应用信息屏幕。

如需详细了解用于显示应用图标的逻辑,包括不显示哪些类型的应用的应用图标
Android官网说明:
https://source.android.google.cn/setup/start/android-10-release?hl=zh-cn
https://developer.android.google.cn/reference/kotlin/android/content/pm/LauncherApps?hl=zh-cn#getactivitylist

解决方法:利用activity-alias来实现
从文章
https://blog.csdn.net/qq_30710615/article/details/106298458

https://stackoverflow.com/questions/8398514/hide-application-icon
中可以得知利用activity-alias可以实现Android10.0上应用图标隐藏功能,但唯一有个缺陷就是会保留透明的占位alias的图标。
具体实现步骤如下:

实现步骤

1. 创建AliasActivity.java

AliasActivity是一个1像素的透明Activity。

public class AliasActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Window window = getWindow();
        // 设置窗口位置在左上角
        window.setGravity(Gravity.LEFT | Gravity.TOP);
        WindowManager.LayoutParams params = window.getAttributes();
        params.x = 0;
        params.y = 0;
        params.width = 1;
        params.height = 1;
        window.setAttributes(params);
        finish();
    }
}
2. 创建AliasMainActivity

AliasMainActivity中在10.0以下,要禁用Alias1Activity,这样就不会显示透明图标(部分机型可能有缺陷)。

public class AliasMainActivity extends AppCompatActivity {
    private Button toActivity, hideActivity;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 先禁用AliasMainActivity组件,启用alias组件
        AppIconUtil.set(AliasMainActivity.this, "com.learn.alias.target.AliasMainActivity", "com.learn.alias.target.Alias1Activity");
        // 10.0以下禁用alias后,透明图标就不存在了,10.0的必须开启,不然会显示主应用图标,10.0会有一个透明的占位图
        if (Build.VERSION.SDK_INT < 29) {
            // 禁用Alias1Activity
            AppIconUtil.disableComponent(this,"com.learn.alias.target.Alias1Activity");
        }
        Window window = getWindow();
        // 设置窗口位置在左上角
        window.setGravity(Gravity.LEFT | Gravity.TOP);
        WindowManager.LayoutParams params = window.getAttributes();
        params.x = 0;
        params.y = 0;
        params.width = 1;
        params.height = 1;
        window.setAttributes(params);
        finish();
    }
}
3. 创建AppIconUtil

AppIconUtil工具类,禁用或启用组件。

public class AppIconUtil {

    /**
     *
     * @param context
     * @param main com.learn.alias.MainActivity
     * @param alias com.learn.alias.AliasActivity
     */
    public static void set(Context context, String main, String alias) {
        disableComponent(context, main);
        enableComponent(context, alias);
    }

    /**
     * 启动组件
     */
    public static void enableComponent(Context context, String clazzName) {
        ComponentName componentName =  new ComponentName(context, clazzName);
        PackageManager mPackageManager = context.getPackageManager();
        mPackageManager.setComponentEnabledSetting(componentName, 			          PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
    }

    /**
     * 禁用组件
     */
    public static void disableComponent(Context context, String clazzName) {
        ComponentName componentName =  new ComponentName(context, clazzName);
        PackageManager mPackageManager = context.getPackageManager();
        mPackageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
    }

}
4. 新增透明图标

创建alias_icon.xml添加到drawable目录下,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#00000000"/>
</shape>
5. 新增透明主题

新增KeepLiveTheme主题到res\values下的style.xml文件中

<style name="KeepLiveTheme" parent="AppTheme">
        <item name="android:windowBackground">@null</item>
        <item name="android:windowIsTranslucent">true</item>
</style>
6. 修改AndroidManifest.xml文件
  • AliasMainActivity
    启动Activity。
  • MainActivity
    外部要启动的Activity。
  • AliasActivity
    Alias图标启动的Activity。
  • Alias1Activity
    activity-alias配置。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.learn.alias">

    <application
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:ignore="GoogleAppIndexingWarning">
        <activity
            android:name="com.learn.alias.target.AliasMainActivity"
            android:theme="@style/KeepLiveTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
                <data android:host="MainActivity" android:scheme="com.learn.alias.target"
                    tools:ignore="AppLinkUrlError" />
            </intent-filter>
        </activity>

        <!-- 外部要启动的Activity -->
        <activity
            android:name="com.learn.alias.target.MainActivity"
            android:excludeFromRecents="true"
            android:exported="true"
            android:finishOnTaskLaunch="false"
            android:launchMode="singleInstance">
        </activity>

        <!-- Alias图标启动的Activity -->
        <activity
            android:name="com.learn.alias.target.AliasActivity"
            android:excludeFromRecents="true"
            android:exported="false"
            android:finishOnTaskLaunch="false"
            android:launchMode="singleInstance"
            android:theme="@style/KeepLiveTheme" />

        <!-- activity-alias配置 -->
        <activity-alias
            android:name="com.learn.alias.target.Alias1Activity"
            android:enabled="true"
            android:icon="@drawable/alias_icon"
            android:label=""
            android:launchMode="singleTask"
            android:targetActivity="com.learn.alias.target.AliasActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity-alias>
    </application>
</manifest>

这种方式可以在7.0-10.0上隐藏图标,在10.0上会有透明图标占位,点击无反应。外部跳转的是MainActivity。
最后,demo源码地址:https://github.com/RenZhongrui/android-learn/tree/master/013-android-alias%20-hide

学习参考:
https://blog.csdn.net/lzfengluo/article/details/87812889
https://blog.csdn.net/qq_30710615/article/details/106298458
https://developer.huawei.com/consumer/cn/forum/topicview?tid=0201288299092590368&fid=24

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ruiurrui

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值