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
可以响应Uri
为com.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