系统的选择弹窗是:
frameworks/base/core/java/com/android/internal/app/ResolverActivity.java
protected boolean onTargetSelected(TargetInfo target, boolean alwaysCheck) {///......if (alwaysCheck) {final int userId = getUserId();final PackageManager pm = getPackageManager();android.util.Log.e("XShawn, "+TAG, "filter="+filter); // android.content.IntentFilter@3544861for(int i = 0 ; i < filter.countActions(); i++){android.util.Log.e("XShawn, "+TAG, "filter.getAction["+i+"]="+filter.getAction(i));}for(int i = 0 ; i < filter.countCategories(); i++){android.util.Log.e("XShawn, "+TAG, "filter.getCategory["+i+"]="+filter.getCategory(i));}android.util.Log.e("XShawn, "+TAG, "bestMatch="+bestMatch); // 1081344android.util.Log.e("XShawn, "+TAG, "set="+set); // [Landroid.content.ComponentName;@4f68f86android.util.Log.e("XShawn, "+TAG, "getComponent="+intent.getComponent()); // com.ordissimo.android.tablet.launcher/com.ordissimo.android.tablet.launcher.home.HomeActivity// Set the preferred Activitypm.addPreferredActivity(filter, bestMatch, set, intent.getComponent());if (ri.handleAllWebDataURI) {// Set default Browser if neededfinal String packageName = pm.getDefaultBrowserPackageNameAsUser(userId);if (TextUtils.isEmpty(packageName)) {pm.setDefaultBrowserPackageNameAsUser(ri.activityInfo.packageName, userId);}}} else {try {mMultiProfilePagerAdapter.getActiveListAdapter().mResolverListController.setLastChosen(intent, filter, bestMatch);} catch (RemoteException re) {Log.d(TAG, "Error calling setLastChosenActivity\n" + re);}}///......}
这里适合打印系统处理时产生的各种参数,进而拿到设置默认Launcher的关键参数。
尝试在SystemServer中 startSystemUI之后设置默认launcher,但首次开机时设置不上,可能是开机向导还没走完,系统没有初始化完的原因。
尝试在SystemServer中startOtherService之前设置,也不太理想。
设置默认Launcher,设置方法可参考PackageManagerService.setHomeActivity方法。
采用监听开机广播的方式处理:
MtkSettings\src\com\emdoor\customization\PreferredActivityReceiver.java
/** ****** Copyright © 2015-2022 XShawn ********* Q Q:930226956 (请备注您的信息)* 邮箱:shawn.xiafei@foxmail.com* 语雀:https://www.yuque.com/xshawn* 更新:2022-03-31 10:21* ********** All Rights Reserved. *************/package com.emdoor.customization;import android.content.BroadcastReceiver;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.content.pm.PackageManager;import android.content.pm.ResolveInfo;import android.os.SystemProperties;import android.provider.Settings;import android.util.Log;import java.util.ArrayList;import java.util.List;public class PreferredActivityReceiver extends BroadcastReceiver {private static final String TAG = "XShawn, PreferredActivityReceiver";private static final String KEY_ORDISSIMO_SUPPORT = "ro.com.ordissimo.support";private static final String KEY_ORDISSIMO_INIT = "ordissimo_init";@Overridepublic void onReceive(Context context, Intent intent) {Log.w(TAG, "action: " + intent.getAction());if (SystemProperties.getBoolean(KEY_ORDISSIMO_SUPPORT, false)) {setDefaultHome(context);}}private static void setDefaultHome(Context context) {if (isOrdissimoInit(context)) {Log.w(TAG, "default home has already been set.");return;}Log.w(TAG, "try to set default home...");// target activityfinal ComponentName targetHome = new ComponentName("com.ordissimo.android.tablet.launcher","com.ordissimo.android.tablet.launcher.home.HomeActivity");final PackageManager pm = context.getPackageManager();List<ResolveInfo> homeActivities = new ArrayList<>();ComponentName currentHome = pm.getHomeActivities(homeActivities);// pre-check statusif (targetHome.equals(currentHome)) {Log.w(TAG, "default home has already been set.");setOrdissimoInit(context, true);return;}// available setComponentName[] set = homeActivities.parallelStream().map(resolveInfo -> resolveInfo.activityInfo.getComponentName()).toArray(ComponentName[]::new);// set default homecontext.getPackageManager().replacePreferredActivity(getHomeFilter(),IntentFilter.MATCH_CATEGORY_EMPTY,set,targetHome);// after-check status.currentHome = pm.getHomeActivities(homeActivities);if (targetHome.equals(currentHome)) {Log.w(TAG, "set default home success.");setOrdissimoInit(context, true);}}private static IntentFilter getHomeFilter() {IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);filter.addCategory(Intent.CATEGORY_HOME);filter.addCategory(Intent.CATEGORY_DEFAULT);return filter;}private static boolean isOrdissimoInit(Context context) {return Settings.Global.getInt(context.getContentResolver(), KEY_ORDISSIMO_INIT, 0) == 1;}private static void setOrdissimoInit(Context context, boolean done) {Settings.Global.putInt(context.getContentResolver(), KEY_ORDISSIMO_INIT, done ? 1 : 0);}}
注册广播接收器:
<!-- START. For Ordissimo-Customization. By XShawn@20220331. --><receiverandroid:name="com.emdoor.customization.PreferredActivityReceiver"android:enabled="true"android:exported="true"><intent-filter><action android:name="android.intent.action.BOOT_COMPLETED" /><action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" /><action android:name="android.intent.action.USER_PRESENT" /></intent-filter></receiver><!-- END. For Ordissimo-Customization. By XShawn@20220331. -->
但开机广播是有延时性的,在有开机向导的前提下,能够成功设置默认launcher。
若没有开机向导,开机后直接就进了launcher,此时开机广播还没有发出来,所以默认不成功。
优化方案
找到安装APP的位置,安装完成,主动发广播去修改默认launcher,但这样每次安装都会自动默认上。
//frameworks\base\services\core\java\com\android\server\pm\PackageManagerService.javatry {PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,System.currentTimeMillis(), user);updateSettingsLI(newPackage, installerPackageName, null, res, user);if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {prepareAppDataAfterInstallLIF(newPackage);//------------------------if (pkgName.equals("com.dianxinos.dxhome")){//发送广播Intent intent = new Intent("emdoor.intent.action.UPDATE_LANUCHER_APPS");mContext.sendBroadcast(intent);}//------------------------} else {// Remove package from internal structures, but keep around any// data that might have already existeddeletePackageLIF(pkgName, UserHandle.ALL, false, null,PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);}} catch (PackageManagerException e) {res.setError("Package couldn't be installed in " + pkg.codePath, e);}
