Android10 设置默认Launcher 您所在的位置:网站首页 华为怎么修改默认启动器 Android10 设置默认Launcher

Android10 设置默认Launcher

2023-12-27 20:39| 来源: 网络整理| 查看: 265

不保留系统launcher 在mk文件中添加这个属性LOCAL_OVERRIDES_PACKAGES := Launcher3 对应的mk中删除,不让其编译即可。 保留系统默认的Launcher

当系统存在多个launcher时,若没有设置默认launcher,开机启动后会弹出提示框,罗列所有launcher,用户选择并设置了默认launcher后,按home键以及以后重启都会进入默认的launcher。亦或者在设置--》应用和通知--》默认应用--》主屏幕应用 中也可设置默认launcher。

客户希望系统能直接就进入我设定的launcher而不是弹出框后选择然后设置

前提:客户的app需要有home属性

修改方法:

首先我们需要增加全局属性Settings.Global.DEFAULT_LAUNCHER,,客户可通过修改该属性设置自定义桌面

1:增加自定义属性: //frameworks\base\core\java\android\provider\Settings.java public static final class Global extends NameValueTable { public static final String DEFAULT_LAUNCHER = "my_default_launcher"; } public static final class System extends NameValueTable { public static final String DEFAULT_LAUNCHER = Global.DEFAULT_LAUNCHER; PUBLIC_SETTINGS.add(DEFAULT_LAUNCHER); MOVED_TO_GLOBAL.add(Settings.Global.DEFAULT_LAUNCHER); } frameworks\base\packages\SettingsProvider\src\com\android\providers\settings\DatabaseHelper.java private void loadGlobalSettings(SQLiteDatabase db) { loadStringSetting(stmt, Settings.Global.DEFAULT_LAUNCHER, R.string.default_launcher); } //frameworks\base\packages\SettingsProvider\res\values\defaults.xml com.android.launcher3/com.android.launcher3.Launcher

两种方法可选:

修改弹出框界面直接设置launcher,弹出提示框界面是:frameworks/base/core/java/com/android/internal/app/ResolverActivity.java:修改方法:在configureContentView内直接读取自定义的桌面,然后替代launcher3

1:frameworks/base/core/java/com/android/internal/app/ResolverActivity.java 的configureContentView 读取设置的默认桌面,进行设置,mResolvingHome就是表示需要选择的是不是home 在这里只针对home作处理。 public boolean configureContentView(List payloadIntents, Intent[] initialIntents, List rList) { //.... if (rebuildCompleted) { //.... //phoebe add for default launcher for prop Settings.Global.DEFAULT_LAUNCHER if(mResolvingHome){ String defaultlauncher = Settings.Global.getString(getContentResolver(), Settings.Global.DEFAULT_LAUNCHER); final TargetInfo defaultTarget = mAdapter.targetInfoForDefault(defaultlauncher); Log.d(TAG, "zmm add for configureContentView:defaultlauncher:" + defaultlauncher + ":" + defaultTarget); if (defaultTarget != null) { safelyStartActivity(defaultTarget); mPackageMonitor.unregister(); mRegistered = false; finish(); return true; } } } } 2:在ResolveListAdapter 增加targetInfoForDefault方法,并且在rebuildList成功以后,再次设置默认laucnher public class ResolveListAdapter extends BaseAdapter { @Nullable public TargetInfo targetInfoForDefault(String info) { if (TextUtils.isEmpty(info)) { return null; } //com.yjx.inoexdash/com.yjx.inoexdash.ui.main.MainActivity String[] namesArray = info.trim().split("/"); if (namesArray == null || namesArray.length < 2) { return null; } String packageName = namesArray[0]; String activityInfo = namesArray[1]; if (TextUtils.isEmpty(packageName) || TextUtils.isEmpty(activityInfo)) { return null; } ComponentName componentName = new ComponentName(packageName.trim(), activityInfo.trim()); Log.d(TAG, "zmm add for targetInfoForDefault:" + componentName + ":" + mDisplayList.size()); for (TargetInfo targetInfo : mDisplayList) { ComponentName targetComponentName = targetInfo.getResolvedComponentName(); if (componentName.equals(targetComponentName)) { return targetInfo; } } return null; } private void postListReadyRunnable() { if (mPostListReadyRunnable == null) { mPostListReadyRunnable = new Runnable() { @Override public void run() { //phoebe add for default launcher for prop Settings.Global.DEFAULT_LAUNCHER String defaultlauncher = mResolvingHome ? Settings.Global.getString(context.getContentResolver(), Settings.Global.DEFAULT_LAUNCHER) : null; final TargetInfo defaultTarget = TextUtils.isEmpty(defaultlauncher) ? null : mAdapter.targetInfoForDefault(defaultlauncher); Log.d(TAG, "zmm add for postListReadyRunnable defaultlauncher:" + defaultlauncher + ":" + defaultTarget); if (defaultTarget != null) { safelyStartActivity(defaultTarget); finish(); return; } setHeader(); resetButtonBar(); onListRebuilt(); mPostListReadyRunnable = null; } }; getMainThreadHandler().post(mPostListReadyRunnable); } } }

修改ActivityManagerService 跳过ResolverActivity

1:ActivityStartController 的startHomeActivity方法内读取用户设置的桌面,并且跳过Settings,和Provision 因为第一次开机,会先Settings的CryptKeeper(加密),FallbackHome(设备正在启动中)接着是provision 的默认桌面,再是launcher3的Launcher页面 zmm add for startHomeActivity...com.android.settings.CryptKeeper:ComponentInfo{com.android.settings/com.android.settings.CryptKeeper} zmm add for startHomeActivity...com.android.settings.FallbackHome:ComponentInfo{com.android.settings/com.android.settings.FallbackHome} zmm add for startHomeActivity...com.android.provision.DefaultActivity:ComponentInfo{com.android.provision/com.android.provision.DefaultActivity} zmm add for startHomeActivity...com.android.launcher3.Launcher:ComponentInfo{com.android.launcher3/com.android.launcher3.Launcher} //frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) { final ActivityOptions options = ActivityOptions.makeBasic(); options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN); if (!ActivityRecord.isResolverActivity(aInfo.name)) { // The resolver activity shouldn't be put in home stack because when the foreground is // standard type activity, the resolver activity should be put on the top of current // foreground instead of bring home stack to front. options.setLaunchActivityType(ACTIVITY_TYPE_HOME); } //phoebe add for default launcher for prop Settings.Global.DEFAULT_LAUNCHER skip settings,Provision String shortName = (intent == null || intent.getComponent() == null) ? null : intent.getComponent().getPackageName(); if (!isSettingsApp(shortName) && !isProvisionApp(shortName) && setTargetActivityAsPreferredActivity()) { //Slog.d(TAG, " zmm add for startHomeActivity as user seetings.."); return; } //phoebe add for default launcher for prop Settings.Global.DEFAULT_LAUNCHER skip settings,Provision end ... } //判断是不是Settings app private boolean isSettingsApp(String shortName) { return shortName != null && shortName.equals("com.android.settings"); } //判断是不是Provision app private boolean isProvisionApp(String shortName) { return shortName != null && shortName.equals("com.android.provision"); } //设置用户设置的桌面 private boolean setTargetActivityAsPreferredActivity() { boolean result = false; Context context = mService.mContext; if (context == null) return result; String info = Settings.Global.getString(context.getContentResolver(), Settings.Global.DEFAULT_LAUNCHER); Slog.d(TAG, " zmm add for setTargetActivityAsPreferredActivity info=" + info); if (TextUtils.isEmpty(info)) { return result; } String[] namesArray = info.split("/"); if (namesArray == null || namesArray.length < 2) { return result; } String packageName = namesArray[0]; String activityInfo = namesArray[1]; if (TextUtils.isEmpty(packageName) || TextUtils.isEmpty(activityInfo)) { return result; } IntentFilter filter = new IntentFilter(); filter.addAction("android.intent.action.MAIN"); filter.addCategory("android.intent.category.HOME"); filter.addCategory("android.intent.category.DEFAULT"); Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_HOME); packageName = packageName.trim(); activityInfo = activityInfo.trim(); PackageManager pm = context.getPackageManager(); List list = pm.queryIntentActivities(intent, 0); final int N = list == null ? 0 : list.size(); ComponentName[] set = new ComponentName[N]; ComponentName componentName = null; int bestMatch = 0; for (int i = 0; i < N; i++) { ResolveInfo r = list.get(i); set[i] = new ComponentName(r.activityInfo.packageName, r.activityInfo.name); if (r.match > bestMatch) bestMatch = r.match; if (packageName.equals(r.activityInfo.packageName) && activityInfo.equals(r.activityInfo.name)) { /*modify target apk packageName 填写你的包名*/ componentName = set[i]; } } // Slog.e(TAG, "zmm add for setTargetActivityAsPreferredActivity newcomponentName=" + componentName); if (null != componentName) { pm.replacePreferredActivity(filter, IntentFilter.MATCH_CATEGORY_EMPTY, set, componentName); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); result = true; } return result; } 2:接着修改frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java,需要把用户在设置--》默认应用中选择的桌面应用保存到自定义的属性中。 ComponentName getHomeActivitiesAsUser(List allHomeCandidates, int userId) { ... for (int i = 0; i < resolveInfosSize; i++) { ResolveInfo resolveInfo = resolveInfos.get(i); if (resolveInfo.activityInfo != null && TextUtils.equals( resolveInfo.activityInfo.packageName, packageName)) { //phoebe add start ComponentName componentName = new ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name); Slog.d(TAG, "zmm add for getHomeActivitiesAsUser:com:"+componentName); String value = resolveInfo.activityInfo.packageName + "/" + resolveInfo.activityInfo.name; android.provider.Settings.Global.putString(mContext.getContentResolver(), android.provider.Settings.Global.DEFAULT_LAUNCHER, value); //phoebe add end return componentName; } } return null; }

以上两种都可实现根据用户配置切换默认launcher

1:adb 切换 adb shell settings put global my_default_launcher com.android.launcher3/com.android.launcher3.Launcher 2:app可如此调用: Settings.Global.putString(getContentResolver(), "my_default_launcher", "com.yjx.inoexdash/com.yjx.inoexdash.ui.main.MainActivity");

客户的app如果是普通的三方app,设置Global属性可能是报错没有权限:

Settings.Global.putString(getContentResolver(), "my_default_launcher", "com.yjx.inoexdash/com.yjx.inoexdash.ui.main.MainActivity"); 报错:缺少权限:Manifest.permission.WRITE_SECURE_SETTINGS 该权限是系统app才能申请的权限,普通app申请不到的话,我们可以去掉该限制。 diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -1249,18 +1250,23 @@ public class SettingsProvider extends ContentProvider { private boolean mutateGlobalSetting(String name, String value, String tag, boolean makeDefault, int requestingUserId, int operation, boolean forceNotify, int mode) { - // Make sure the caller can change the settings - treated as secure. - enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS); String pkg = "com.android.settings"; //数据写入时使用系统settings应用的包名,系统会进行调用进程的包名判断 if(!"my_default_launcher".equals(name)){ //phoebe add 自定义数据不进行权限验证 pkg = ""; // Make sure the caller can change the settings - treated as secure. enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS); } //下面修改在插入操作时使用上面预设的包名,绕过包名验证 @@ -1268,7 +1274,7 @@ public class SettingsProvider extends ContentProvider { case MUTATION_OPERATION_INSERT: { return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM, name, value, tag, makeDefault, - getCallingPackage(), forceNotify, CRITICAL_GLOBAL_SETTINGS); + "".equals(pkg)?getCallingPackage():pkg, forceNotify, CRITICAL_GLOBAL_SETTINGS); }

每日语录:滴水穿石!!!加油!!!

单曲循环《如愿》



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有