Android 安卓设置默认桌面代码实现

3 篇文章 1 订阅
2 篇文章 0 订阅

在工作中有时候会开发定制的启动器,然后每次都要按home键选择定制启动器后再按一下才能选择始终,这样一个是比较麻烦,另一个是不想用户自行控制,所以需要代码来设置默认桌面。

找到系统设置默认桌面位置,跟踪代码调用

跟踪这个界面的代码发现设置是在这里 DefaultHomePicker.java这个文件里面,其实就是调用packageManage的replacePreferredActivity方法。

    protected boolean setDefaultKey(String key) {
        if (!TextUtils.isEmpty(key)) {
            final ComponentName component = ComponentName.unflattenFromString(key);
            final List<ResolveInfo> homeActivities = new ArrayList<>();
            mPm.getHomeActivities(homeActivities);
            final List<ComponentName> allComponents = new ArrayList<>();
            for (ResolveInfo info : homeActivities) {
                final ActivityInfo appInfo = info.activityInfo;
                ComponentName activityName = new ComponentName(appInfo.packageName, appInfo.name);
                allComponents.add(activityName);
            }
            mPm.replacePreferredActivity(
                    DefaultHomePreferenceController.HOME_FILTER,
                    IntentFilter.MATCH_CATEGORY_EMPTY,
                    allComponents.toArray(new ComponentName[0]),
                    component);

            // Launch the new Home app so the change is immediately visible even if
            // the Home button is not pressed.
            final Context context = getContext();
            Intent i = new Intent(Intent.ACTION_MAIN);
            i.addCategory(Intent.CATEGORY_HOME);
            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(i);
            return true;
        }
        return false;
    }

这里用到的方法是隐藏的,所以我们反射调用,如下

    public void setDefaultLauncherApp(ComponentName componentName) {
        PackageManager packageManager = mContext.getPackageManager();
        Class<?> refPackageManager = packageManager.getClass();
        Method[] methods = refPackageManager.getDeclaredMethods();
        Method mReplacePreferredActivity = null;
        Method mGetHomeActivities = null;
        for (Method method : methods) {
            if (method.getName().equals("replacePreferredActivity")) {
                mReplacePreferredActivity = method;
            }
            if (method.getName().equals("getHomeActivities")) {
                mGetHomeActivities = method;
            }
        }
        mReplacePreferredActivity.setAccessible(true);
        mGetHomeActivities.setAccessible(true);

        IntentFilter HOME_FILTER = new IntentFilter(Intent.ACTION_MAIN);
        HOME_FILTER.addCategory(Intent.CATEGORY_HOME);
        HOME_FILTER.addCategory(Intent.CATEGORY_DEFAULT);
        final List<ComponentName> allComponents = new ArrayList<>();
        final List<ResolveInfo> homeActivities = new ArrayList<>();
        try {
            mGetHomeActivities.invoke(packageManager, homeActivities);
            for (ResolveInfo info : homeActivities) {
                final ActivityInfo appInfo = info.activityInfo;
                ComponentName activityName = new ComponentName(appInfo.packageName, appInfo.name);
                allComponents.add(activityName);
            }
            mReplacePreferredActivity.invoke(packageManager, HOME_FILTER, IntentFilter.MATCH_CATEGORY_EMPTY, allComponents.toArray(new ComponentName[0]), componentName);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

至于为什么要用这种反射方法去找到对应的方法而不是用方法名直接get出来,这个原因之前的文章有讲过,是有时候直接提提不出来,用遍历方法的方式这时候根据方法名去找对应的方法。

这个方法里面传的是ComponentName 这个就是需要设置的启动器的包名和启动的activity名,如果这个activity没有加home标签的话,那会设置不成功。

并且需要系统权限(系统签名)才能调用这个,请注意以上代码基于Android P,不保证之前和之后版本能用

以上。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值