Android10 设置默认Launcher

这篇具有很好参考价值的文章主要介绍了Android10 设置默认Launcher。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

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

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

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

<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.HOME"/>
    <category android:name="android.intent.category.LAUNCHER"/>
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

修改方法:

首先我们需要增加全局属性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
<string name="default_launcher" translatable="false">com.android.launcher3/com.android.launcher3.Launcher</string>

两种方法可选:

  • 修改弹出框界面直接设置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<Intent> payloadIntents, Intent[] initialIntents,
        List<ResolveInfo> 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<ResolveInfo> 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<ResolveInfo> 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);
                 }

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

单曲循环《如愿》文章来源地址https://www.toymoban.com/news/detail-472512.html

到了这里,关于Android10 设置默认Launcher的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android 10.0 Launcher 启动流程

    在前面SystemUI启动流程中说到,在SystemServer中会去启动各种系统服务,这里的launcher也是启动的其中一个服务ActivityManagerService去启动的。在android10之前,系统四大组件的启动都是在ActivityManagerService中,在android10中,单独抽出了一个ActivityTaskManagerService,主要负责Activity的管理和

    2024年02月04日
    浏览(40)
  • Android10/11 原生Launcher3深度定制

    一、引言 关于Android10和11系统Launcher3的定制有很多,根据项目的需求会进行各种定制开发, 于是就需要研究Launcher3的源码。本文主要从Android 11的Launcher3QuickStep着手 (go版本或者其他版本类似)从常用的修改进行分析,首先就得大致理解 Launcher3各个 类的作用。 1.1、常用类简

    2023年04月17日
    浏览(47)
  • el-table多选框设置默认选中,翻页保留选中状态

    最近碰到个需求,el-table列表渲染数据,要求有多选框并且附带默认选中,翻页后保留选中状态 写默认选中时百度一下还很简单,但是碰到个bug,第一次翻页可以保留,第二次翻页回来之后选中的就没了。 经过研究解决,记录一下,直接上代码了 默认选中只需要给table增加

    2024年02月14日
    浏览(52)
  • android 13.0 添加系统字体并且设置为默认字体

    在13.0系统定制化开发中,在产品定制中,有产品需求对于系统字体风格不太满意,所以想要更换系统的默认字体,对于系统字体的修改也是常有的功能,而系统默认也支持增加字体,所以就来添加楷体字体为系统字体,并替换为系统默认字体, 接下来就来分析下替换默认字

    2024年02月22日
    浏览(64)
  • 【干货】Android系统定制基础篇:第十四部分(禁止第三方应用调用系统设置、增加TP配置、增加摄像头镜像设置、增加摄像头默认角度设置、修改默认语言)

    修改文件 frameworksbasecorejavaandroidappActivityManagerNative.java 如下: 属性配置: Android 主板定制过程中经常出现客户需要临时适配各种 TP(包括 USB TP),因此在设置菜单中加入 xy 交换,x 反转,y 反转常用配置,以客户多样性需求。 以下修改基于Android 8.1 SDK,如下: 属性配置

    2024年02月10日
    浏览(50)
  • Android 13.0 系统多个播放器app时,设置默认播放器

     在13.0的系统产品开发中,对于在系统中有多个播放器的时候,这时候如果调用代码打开播放器,会出现多个播放器列表让用户 选择启动哪个播放器,所以产品开发需求需要设置默认播放器,当打开播放器的时候,就直接打开播放器就可以了,所以就需要 了解查询播放器列

    2024年02月08日
    浏览(67)
  • android 12.0 第三方输入法app设置系统默认输入法

    在12.0的产品开发中,有功能需要要求设置默认输入法,替换掉系统的输入法,所以这就需要了解设置输入法的相关功能需求,然后根据输入法包名来设置默认输入法 在设置系统默认输入法中 每个系统输入法的id不同 根据id设置输入法 需要先根据需要设置默认输入法的id,来

    2024年02月07日
    浏览(62)
  • Android系统启动(四) — Launcher 启动过程

    1 Launcher 概述 系统启动的最后一步是启动一个应用程序来显示系统中已经安装的应用程序,这个应用程序就叫做 Launcher 。 Launcher 在启动过程中会请求 PackageManagerService 返回系统中已经安装的应用程序信息,并将这些信息封装成一个快捷图标列表显示在系统屏幕上,这样用户就

    2024年02月01日
    浏览(43)
  • Android 系统桌面 App —— Launcher 开发(1)

    Launcher就是Android系统的桌面,俗称“HomeScreen”也就是我们开机后看到的第一个App。launcher其实就是一个app,它的作用是显示和管理手机上其他App。目前市场上有很多第三方的launcher应用,比如“小米桌面”、“91桌面”等等 要让app作为Launcher,需要在Manifest中添加两个category:

    2024年02月11日
    浏览(61)
  • 邮件服务支持Exchange协议,资产历史账号支持设置保留数量,JumpServer堡垒机v3.10.2 LTS版本发布

    2024年1月22日,JumpServer开源堡垒机正式发布v3.10.2 LTS版本。JumpServer开源项目组将对v3.10 LTS版本提供长期的支持和维护,并定期迭代发布小版本。欢迎广大社区用户升级至v3.10 LTS版本,以获得更佳的使用体验。 在v3.10.2 LTS版本中,JumpServer的邮件服务功能新增支持Exchange协议。目

    2024年01月24日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包