Android11.0 has a built-in third-party Launcher and is set as default. Launcher3 is retained and can be switched.

Android11.0 has a built-in third-party Launcher and is set as default. Launcher3 is retained and can be switched.

Android11.0 has a built-in third-party Launcher and is set as default. Launcher3 is retained and can be switched.

This article describes how to use the built-in third-party application as Launcher in Android 11 and keep the built-in Launcher3. After flashing, the built-in third-party application will be displayed and set as the default Launcher when the system starts.

  1. Add custom default launcher attributes and modify the file path: /device/rockchip/rk356x/rk356x.prop;
persist.sys.def_launcher=
persist.sys.def_launcher_enable=false
  1. Set custom attributes in a specific product, for example, in rk3568_r, modify the path:
    /device/rockchip/rk356x/rk3568_r/rk3568_r.mk
PRODUCT_PROPERTY_OVERRIDES += persist.sys.def_launcher=com.yjz.launcher
PRODUCT_PROPERTY_OVERRIDES += persist.sys.def_launcher_enable=true
  1. Select and set as the default launcher, modify the path /frameworks/base/core/java/com/android/internal/app/ResolverActivity.java;
    public final void onPostListReady(ResolverListAdapter listAdapter, boolean doPostProcessing,
            boolean rebuildCompleted) {
    
    
        if (isAutolaunching()) {
    
    
            return;
        }
        //新增
        if (rebuildCompleted && hasSetDefLauncher()) {
    
    
            return;
        }
      //*******省略代码******
    }


    final boolean postRebuildListInternal(boolean rebuildCompleted) {
    
    
        //*******省略代码******
        //添加
        if (rebuildCompleted && (hasSetDefLauncher() || maybeAutolaunchActivity())) {
    
    
            return true;
        }
        //*******省略代码******
    }

    //添加
    private boolean hasSetDefLauncher() {
    
    
        if (SystemProperties.getBoolean("persist.sys.def_launcher_enable", false)) {
    
    
            String defLauncher = SystemProperties.get("persist.sys.def_launcher", null);
            if (defLauncher != null && !"".equals(defLauncher)) {
    
    
                int size = mMultiProfilePagerAdapter.getActiveListAdapter().getDisplayResolveInfoCount();
                for (int i = 0; i < size; i++) {
    
    
                    DisplayResolveInfo dInfo = mMultiProfilePagerAdapter.getActiveListAdapter().getDisplayResolveInfo(i);
                    if (null != dInfo && defLauncher.equals(dInfo.getResolveInfo().activityInfo.packageName)) {
    
    
                        Log.d(TAG, "find need set default launcher, set default launcher--->" + dInfo.getResolveInfo().activityInfo.packageName);
                        startSelected(i, true, false);
                        return true;
                    }
                }
            }
        }
        return false;
    }
  1. When there are multiple launchers in the system in ResolverActivity, it is queried asynchronously and called back through the onPostListReady() method for setting. At this time, a pop-up window may flash. ResolverListAdapter can logically process the query data and only return the built-in application. A piece of data, processed through postRebuildListInternal() in ResolverActivity, modify the path:
    /frameworks/base/core/java/com/android/internal/app/ResolverListAdapter.java;
    protected boolean rebuildList(boolean doPostProcessing) {
    
    
        //********省略代码******
        if (mBaseResolveList != null) {
    
    
            currentResolveList = mUnfilteredResolveList = new ArrayList<>();
            mResolverListController.addResolveListDedupe(currentResolveList,
                    mResolverListCommunicator.getTargetIntent(),
                    mBaseResolveList);
        } else {
    
    
            currentResolveList = mUnfilteredResolveList =
                    mResolverListController.getResolversForIntent(
                            /* shouldGetResolvedFilter= */ true,
                            mResolverListCommunicator.shouldGetActivityMetadata(),
                            mIntents);
            if (currentResolveList == null) {
    
    
                processSortedList(currentResolveList, doPostProcessing);
                return true;
            }
            List<ResolvedComponentInfo> originalList =
                    mResolverListController.filterIneligibleActivities(currentResolveList,
                            true);
            if (originalList != null) {
    
    
                mUnfilteredResolveList = originalList;
            }
        }
        
        //添加
        if (null != currentResolveList && SystemProperties.getBoolean("persist.sys.def_launcher_enable", false)) {
    
    
            String defLauncher = SystemProperties.get("persist.sys.def_launcher", null);
            if (defLauncher != null && !"".equals(defLauncher)) {
    
    
                for (ResolvedComponentInfo info : currentResolveList) {
    
    
                    ResolveInfo resolveInfo = info.getResolveInfoAt(0);
                    if (defLauncher.equals(resolveInfo.activityInfo.packageName)) {
    
    
                        currentResolveList = new ArrayList<>();
                        currentResolveList.add(info);
                        Log.d(TAG, "find set default launcher--->" + resolveInfo.activityInfo.packageName);
                        break;
                    }
                }
            }
        }
        
        //********省略代码******
        // So far we only support a single other profile at a time.
        // The first one we see gets special treatment.
    }
  1. If Launcher3 is currently displayed, in Settings-Application-Default Application-Home Screen Application, the switching setting defaults to the third-party Launcher application. In a third-party application, when you click the return button on the navigation bar, you will return to Launcher3 because of the switching setting. After the default launcher, the previous task stack still exists and needs to be deleted. Modify the path: /packages/apps/PermissionController/src/com/android/permissioncontroller/role/model/HomeRoleBehavior.java;
//********省略代码******
    @Override
    public void onHolderSelectedAsUser(@NonNull Role role, @NonNull String packageName,
            @NonNull UserHandle user, @NonNull Context context) {
    
    
        // Launch the new home app so the change is immediately visible even if the home button is
        // not pressed.
        
        //这里是发送一个广播到自定义服务中去删除旧的任务栈
        Intent it = new Intent("com.yjz.ACTION_SET_DEF_LAUNCHER_ENABLE");
        it.putExtra("packageName", packageName);
        context.sendBroadcast(it);

        Intent intent = new Intent(Intent.ACTION_MAIN)
                .addCategory(Intent.CATEGORY_HOME)
                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }

//********省略代码******
}
  1. Logic for clearing old task stacks in custom services:
    //********省略代码******
    private class CustomReceiver extends BroadcastReceiver {
    
    
        @Override
        public void onReceive(Context context, Intent intent) {
    
    
            String action = intent.getAction();
            if ("com.yjz.ACTION_SET_DEF_LAUNCHER_ENABLE".equals(action)) {
    
    
                String packageName = intent.getStringExtra("packageName");
                if (null != packageName && !"".equals(packageName)) {
    
    
                    String defLauncher = SystemProperties.get("persist.sys.def_launcher", null);
                    if (defLauncher != null && !"".equals(defLauncher) && defLauncher.equals(packageName)) {
    
    
                        SystemProperties.set("persist.sys.def_launcher_enable", "true");
                    } else {
    
    
                        SystemProperties.set("persist.sys.def_launcher_enable", "false");
                    }
                    clearOldLauncherTask(packageName, context);
                }
            }
        }
    }

    private void clearOldLauncherTask(String packageName, Context context) {
    
    
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> list = manager.getRunningTasks(Integer.MAX_VALUE);
        if (null != list) {
    
    
            for (ActivityManager.RunningTaskInfo item : list) {
    
    
                if (item.configuration.windowConfiguration.getActivityType() == WindowConfiguration.ACTIVITY_TYPE_HOME) {
    
    
                    if (!item.realActivity.getPackageName().equals(packageName)) {
    
    
                        final int tId = item.taskId;
                        try {
    
    
                            ActivityTaskManager.getService().removeTask(tId);
                        } catch (RemoteException e) {
    
    
                            Log.w(TAG, "Failed to remove task=" + tId, e);
                        }
                    }
                }
            }
        }
    }
  1. Add the built-in third-party application launcher and place the application and Android.mk under vendor/yjz/launcher/
    /vendor/yjz/launcher/Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := YJZLauncher
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := PRESIGNED
include $(BUILD_PREBUILT)
  1. Add YJZLauncher to the compilation system
    /device/rockchip/rk356x/rk3568_r/rk3568_r.mk
PRODUCT_PACKAGES += YJZLauncher
  1. Compile and flash verification

Guess you like

Origin blog.csdn.net/yjz_0314/article/details/134704763