前言
此博客讲解如何在Android10系统上,将自己的应用设置成默认Launcher。
第一步添加需要设置成Launcher的应用
首先在需要成为Launcher的清单文件里添加如下关键
注意,要添加singleTask,否则会出现home键多次创建launchar 应用
<application>
<activity
android:name=".ui.MainActivity"
android:exported="true"
android:launchMode="singleTask">
<intent-filter>
<!-- 隐藏图标 -->
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<!-- 设置为 launcher -->
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.rayland.home" />
</intent-filter>
</activity>
</application>
将应用导入系统中
路径::~/aosp/packages/apps/ 如下图
Android.mk 内容如下
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
####
LOCAL_MODULE := Calligraphy
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_PROPRIETARY_MODULE := true
LOCAL_CERTIFICATE := PRESIGNED
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
include $(BUILD_PREBUILT)
到这一步,我们可以先选择编译系统,然后看看效果
这里可以看到这边启动了一个弹窗让你选择launcher。到这一步,我们就已经达到了一半的目的了
我们可以通过adb命令查看下这个弹窗,可以发现这个弹窗是叫一个ResolverActivity
第二步设置成默认Launcher
上面我们已经获知launcher的选择弹窗是ResolverActivity,现在目标很明确,就是修改ResolverActivity这个类,让它自动就选择我们需要的launcher应用,然后快速finish掉自己,不在显示。
在ResolverActivity添加如下代码(记得将中文注释删除,怕编译的时候不支持中文注释,这里只是说明一下简单的理解):
//add:Setdefaultluncher
private void setDefaultLauncher(String defPackageName, String defClassName) {
try {
final PackageManager pm = getPackageManager();
Log.i("deflauncherxxz", "deflauncher : PackageName = " +
defPackageName + " ClassName = " + defClassName);
//这里组装一个我们需要启动的launcher的IntentFilter,以提供PackageManager直接启动
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.MAIN");
filter.addCategory("android.intent.category.HOME");
filter.addCategory("android.intent.category.DEFAULT");
//这里创建一个intent并且添加Intent.ACTION_MAIN与Intent.CATEGORY_HOME,调用PackageManager的queryIntentActivities搜索符合的ResolveInfo列表数据
//简单的来说就是希望搜索下系统中有CATEGORY_HOME(设备启动显示的第一个活动)的数据
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
List<ResolveInfo> list = new ArrayList<ResolveInfo>();
//queryIntentActivities可以检索针对给定意图可以执行的所有活动。
list = pm.queryIntentActivities(intent, 0);
final int num = list.size();
ComponentName[] set = new ComponentName[num];
int bestMatch = 0;
for (int i = 0; i < num; i++) {
ResolveInfo r = list.get(i);
set[i] = new ComponentName(r.activityInfo.packageName, r.activityInfo.name);
//match是一个整数,它表示了应用程序与目标IntentFilter的匹配程度。这个值是由系统根据ResolveInfo对象中的各种信息(如包名、类名、动作、类别等)与目标IntentFilter的匹配程度来计算的。
if (r.match > bestMatch) bestMatch = r.match;
}
//选择首选活动
ComponentName preferredActivity = new ComponentName(defPackageName, defClassName);
//将组合好的数据添加到首选活动中
pm.addPreferredActivity(filter, bestMatch, set, preferredActivity);
} catch (Exception e) {
e.printStackTrace();
}
}
然后在onCreate方法里调用setDefaultLauncher
分析一波
end