jQuery鼠标指针特效

Android 11--设置第三方Launcher并默认 与 如何预置apk

1.0Ver

/frameworks/base/core/java/com/android/internal/app/ResolverActivity.java

+    private void setDefaultLauncher() {
+        try {
+            final PackageManager pm = getPackageManager();
+
+            //String defPackageName = "com.android.launcher3";
+            String defPackageName = "com.demo.launcher3";
+            String defClassName;
+
+            //defClassName = "com.android.searchlauncher.SearchLauncher";
+            defClassName = "com.demo.launcher.MainActivity";
+
+            Log.i("deflauncher", "deflauncher : PackageName = " +
+                    defPackageName + " ClassName = " + defClassName);
+
+            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);
+            List<ResolveInfo> list = new ArrayList<ResolveInfo>();
+            list = pm.queryIntentActivities(intent, 0);
+            final int N = list.size();
+            ComponentName[] set = new ComponentName[N];
+            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;
+            }
+            ComponentName preActivity = new ComponentName(defPackageName, defClassName);
+            pm.addPreferredActivity(filter, bestMatch, set, preActivity);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
     protected void onCreate(Bundle savedInstanceState, Intent intent,
             CharSequence title, int defaultTitleRes, Intent[] initialIntents,
             List<ResolveInfo> rList, boolean supportsAlwaysUseOption) {
         setTheme(appliedThemeResId());
         super.onCreate(savedInstanceState);
            
+        if(mResolvingHome){
+            setDefaultLauncher();
+            finish();
+            return;
+        }
+
         ...
2.0Ver

/frameworks/base/core/java/com/android/internal/app/ResolverActivity.java

public final void onPostListReady(ResolverListAdapter listAdapter, boolean doPostProcessing,
            boolean rebuildCompleted) {

    ...
     if (isAutolaunching()) {
             return;
         }
+        //add start
+        if(setCustomerDefLauncher()){
+            return;
+        }
+        //add end

    ...
                
}

final boolean postRebuildListInternal(boolean rebuildCompleted) {
        //...
        //add start
        if (rebuildCompleted && (setCustomerDefLauncher() || maybeAutolaunchActivity())) {
            return true;
        }
        //add end
    }

//add start
+    private boolean setCustomerDefLauncher(){
+        String defLauncher = "com.demo.launcher3";
+        int size = mMultiProfilePagerAdapter.getActiveListAdapter().getDisplayResolveInfoCount();
+        android.util.Log.d("TAG","setCustomerDefLauncher:"+size);
+        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;
+    }
//add end

多个launcher时,防止闪屏
/frameworks/base/core/java/com/android/internal/app/ResolverListAdapter.java;

protected boolean rebuildList(boolean doPostProcessing) {
        ...
        //add start
+        String defLauncher = "com.demo.launcher3;
+        for (ResolvedComponentInfo info : currentResolveList) {
+            ResolveInfo resolveInfo = info.getResolveInfoAt(0);
+            if (defLauncher.equals(resolveInfo.activityInfo.packageName)) {
+                currentResolveList = new ArrayList<>();
+                currentResolveList.add(info);
+                Log.d("tww", "find set default launcher--->" + resolveInfo.activityInfo.packageName);
+                break;
+            }
+        }
+        //add  end
+ 
        ...
}

如果当前为Launcher3显示,然后从设置里面切换默认为第三方Launcher应用,在第三方应用中,点击导航栏返回按键时,会返回到Launcher3,是因为切换设置默认launcher后,前一个的任务栈还存在,需要删除

+import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
+import android.os.RemoteException;

+    private void clearOldLauncherTask() {
+        ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+        List<ActivityManager.RunningTaskInfo> list = activityManager.getRunningTasks(Integer.MAX_VALUE);
+        if (list != null) {
+            for (ActivityManager.RunningTaskInfo item : list) {
+                Log.d("tag", "--->" + item.configuration.windowConfiguration.getActivityType());
+                Log.d("tag", "--->" + item.realActivity.getPackageName());
+                 //if(item.configuration.windowConfiguration.getActivityType() == WindowConfiguration.ACTIVITY_TYPE_HOME){}
+                if (item.realActivity.getPackageName().equals("com.android.launcher3")) {
+                    final int tId = item.taskId;
+                    try {
+                        Log.d("tag", "tId--->" + tId);
+                        ActivityTaskManager.getService().removeTask(tId);
+                    } catch (RemoteException e) {
+                        Log.d("tag", "--->RemoteException");
+                    }
+                }
+            }
+        }
+    }
+

知道了怎么删除旧的Launcher 任务栈,还需要知道删除旧的Launcher任务栈Timing,

第一个Timing点,可以发送广播通知删除旧的
/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 intent = new Intent(Intent.ACTION_MAIN)
                .addCategory(Intent.CATEGORY_HOME)
                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);

        //add start
        Intent launcherIntent = new Intent("xxxx.x.x.x.action");
        launcherIntent.putExtra("launcher_package_name", packageName);
        context.sendBroadcast(launcherIntent);
        //add  end
    }


第二个Timing点
frameworks/base/services/core/java/com/android/server/role/RoleManagerService.java
        @Override
        public void addRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName,
                @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId,
                @NonNull RemoteCallback callback) {
            if (!mUserManagerInternal.exists(userId)) {
                Slog.e(LOG_TAG, "user " + userId + " does not exist");
                return;
            }
            userId = handleIncomingUser(userId, false, "addRoleHolderAsUser");
            getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS,
                    "addRoleHolderAsUser");

            Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
            Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
            Objects.requireNonNull(callback, "callback cannot be null");

            getOrCreateController(userId).onAddRoleHolder(roleName, packageName, flags,
                    callback);
            //add  start
            if (roleName.equals("android.app.role.HOME")) {
                Log.i("tag", "change value->packageName:" + packageName);
                if (packageName.equals("com.android.launcher3")) {
                    SystemProperties.set("persist.sys.xxx", null);
                } else {
                    SystemProperties.set("persist.sys.xxx", packageName);
                }
                //发送广播
            }
            //add  end
        }

第二个timing 早于第一个
参考1

3.0Ver 利用role结合2.0Ver删除旧Launcher栈
--- a/frameworks/base/core/java/com/android/internal/app/ResolverActivity.java
+++ b/frameworks/base/core/java/com/android/internal/app/ResolverActivity.java
@@ -55,6 +55,7 @@ import android.os.IBinder;
 import android.os.PatternMatcher;
 import android.os.RemoteException;
 import android.os.StrictMode;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.MediaStore;
@@ -1040,6 +1041,11 @@ public class ResolverActivity extends Activity implements
         if (isAutolaunching()) {
             return;
         }
+        //add Change to the customer's default launcher xxxx xxxx
+        if(rebuildCompleted && hasCustomerDefLauncher()){
+            return;
+        }
+        //add Change to the customer's default launcher xxxx xxxx
         if (isIntentPicker()) {
             ((ResolverMultiProfilePagerAdapter) mMultiProfilePagerAdapter)
                     .setUseLayoutWithDefault(useLayoutWithDefault());
@@ -1061,6 +1067,23 @@ public class ResolverActivity extends Activity implements
         }
     }

+    //add Change to the customer's default launcher xxxx xxxx
+    private boolean hasCustomerDefLauncher() {
+        String def_customer_launcher = SystemProperties.get("persist.sys.def_customer_launcher", null);
+        if (def_customer_launcher != null && !"".equals(def_customer_launcher)) {
+            int size = mMultiProfilePagerAdapter.getActiveListAdapter().getDisplayResolveInfoCount();
+            for (int i = 0; i < size; i++) {
+                DisplayResolveInfo info = mMultiProfilePagerAdapter.getActiveListAdapter().getDisplayResolveInfo(i);
+                if (info != null && def_customer_launcher.equals(info.getResolveInfo().activityInfo.packageName)) {
+                    startSelected(i, true, false);
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+    //add Change to the customer's default launcher xxxx xxxx
+
     protected void onListRebuilt(ResolverListAdapter listAdapter) {
         final ItemClickListener listener = new ItemClickListener();
         setupAdapterListView((ListView) mMultiProfilePagerAdapter.getActiveAdapterView(), listener);
diff --git a/frameworks/base/core/java/com/android/internal/app/ResolverListAdapter.java b/frameworks/base/core/java/com/android/internal/app/ResolverListAdapter.java
old mode 100644
new mode 100755
index eef722e32b..006e8c00d1
--- a/frameworks/base/core/java/com/android/internal/app/ResolverListAdapter.java
+++ b/frameworks/base/core/java/com/android/internal/app/ResolverListAdapter.java
@@ -38,6 +38,7 @@ import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
 import android.os.RemoteException;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.text.TextUtils;
@@ -219,6 +220,22 @@ public class ResolverListAdapter extends BaseAdapter {
             }
         }

+        //add Resolve pop-up flashing when multiple launchers exist xxxx xxxx
+        if (currentResolveList != null) {
+            String def_customer_launcher = SystemProperties.get("persist.sys.def_customer_launcher", null);
+            if (def_customer_launcher != null && !"".equals(def_customer_launcher)) {
+                for (ResolvedComponentInfo info : currentResolveList) {
+                    ResolveInfo resolveInfo = info.getResolveInfoAt(0);
+                    if (def_customer_launcher.equals(resolveInfo.activityInfo.packageName)) {
+                        currentResolveList = new ArrayList<>();
+                        currentResolveList.add(info);
+                        break;
+                    }
+                }
+            }
+        }
+        //add Resolve pop-up flashing when multiple launchers exist xxxx xxxx
+
         // So far we only support a single other profile at a time.
         // The first one we see gets special treatment.
         for (ResolvedComponentInfo info : currentResolveList) {
diff --git a/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java b/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 0c1bb79279..73f9204ce1 100755
--- a/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -230,6 +230,10 @@ import java.io.PrintWriter;
 import java.util.HashSet;
 import java.util.List;

+import android.app.role.RoleManager;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+
 /**
  * WindowManagerPolicy implementation for the Android phone UI.  This
  * introduces a new method suffix, Lp, for an internal lock of the
@@ -5005,7 +5009,33 @@ public class PhoneWindowManager implements WindowManagerPolicy {
         }

         mAutofillManagerInternal = LocalServices.getService(AutofillManagerInternal.class);
+        setDefaultLauncherItem(mContext);//add
+    }
+
+    //add Whether default selected customer's launcher xxxx xxxx
+    public void setDefaultLauncherItem(Context context) {
+        boolean whether_force = SystemProperties.getBoolean("persist.sys.force_customer_launcher_enable", false);// ture: force use customer's launcher
+        if (!whether_force) return;
+        String packageName = SystemProperties.get("persist.sys.def_customer_launcher", null);
+        if (packageName != null && !"".equals(packageName)) {
+            String roleName = "android.app.role.HOME";
+            boolean add = true;
+            int flags = 0;
+            UserHandle user = Process.myUserHandle();
+            Log.d("PhoneWindowManager_Launcher", "role: " + roleName + ", package: " + packageName);
+            RoleManager roleManager = context.getSystemService(RoleManager.class);
+            Executor executor = context.getMainExecutor();
+            Consumer<Boolean> callback = successful -> {
+                if (successful) {
+                    Log.d("PhoneWindowManager_Launcher", "Success , role: " + roleName + ", package: " + packageName);
+                } else {
+                    Log.d("PhoneWindowManager_Launcher", "Failed , role: " + roleName + ", package: " + packageName);
+                }
+            };
+            roleManager.addRoleHolderAsUser(roleName, packageName, flags, user, executor, callback);
+        }
     }
+    //add Whether default selected customer's launcher xxxx xxxx

     /** {@inheritDoc} */
     @Override
diff --git a/frameworks/base/services/core/java/com/android/server/role/RoleManagerService.java b/frameworks/base/services/core/java/com/android/server/role/RoleManagerService.java
old mode 100644
new mode 100755
index b75bce833e..24801c396d
--- a/frameworks/base/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/frameworks/base/services/core/java/com/android/server/role/RoleManagerService.java
@@ -48,11 +48,13 @@ import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.ShellCallback;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManagerInternal;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.Log;
 import android.util.PackageUtils;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -515,6 +517,16 @@ public class RoleManagerService extends SystemService implements RoleUserState.C

             getOrCreateController(userId).onAddRoleHolder(roleName, packageName, flags,
                     callback);
+            //add change use launcher xxxx xxxx
+            if (roleName.equals("android.app.role.HOME")) {
+                Log.i("PhoneWindowManager_Launcher", "change persist.sys.def_customer_launcher value->packageName:" + packageName);
+                if (packageName.equals("com.android.launcher3")) {
+                    SystemProperties.set("persist.sys.def_customer_launcher", null);
+                } else {
+                    SystemProperties.set("persist.sys.def_customer_launcher", packageName);
+                }
+            }
+            //add change use launcher xxxx xxxx
         }

         @Override
diff --git a/packages/apps/PermissionController/src/com/android/permissioncontroller/role/ui/ManageRoleHolderStateLiveData.java b/packages/apps/PermissionController/src/com/android/permissioncontroller/role/ui/ManageRoleHolderStateLiveData.java
old mode 100644
new mode 100755
index 07698fbc67..0ef9ab6055
--- a/packages/apps/PermissionController/src/com/android/permissioncontroller/role/ui/ManageRoleHolderStateLiveData.java
+++ b/packages/apps/PermissionController/src/com/android/permissioncontroller/role/ui/ManageRoleHolderStateLiveData.java
@@ -19,6 +19,7 @@ package com.android.permissioncontroller.role.ui;
 import android.app.role.RoleManager;
 import android.content.Context;
 import android.os.UserHandle;
+import android.os.SystemProperties;
 import android.util.Log;

 import androidx.annotation.NonNull;
@@ -74,6 +75,13 @@ public class ManageRoleHolderStateLiveData extends LiveData<Integer> {
             Log.i(LOG_TAG, (add ? "Adding" : "Removing") + " package as role holder, role: "
                     + roleName + ", package: " + packageName);
         }
+        //add force use customer's launcher xxxx xxxx
+        boolean whether_force = SystemProperties.getBoolean("persist.sys.force_customer_launcher_enable", false);// ture: force use customer's launcher
+        if (roleName.equals("android.app.role.HOME") && whether_force){
+            Log.i("PhoneWindowManager_Launcher", "force use customer's launcher,don't change !");
+            return;
+        }
+        //add force use customer's launcher xxxx xxxx
         mLastPackageName = packageName;
         mLastAdd = add;
         mLastFlags = flags;

Android预置Apk,Android.mk/Android.bp

预置apk,整个东西其实非常简单,因为系统本身它自己也内置不少apk,找到对应目录,查看它怎么写,.mk或.bp文件,依葫芦画瓢就行了!!!
系统应用:Browser2,Calendar等,一般都在packages目录下

build/make/target/product/handheld_product.mk

 # /product packages
 PRODUCT_PACKAGES += \
+       demo \
     Browser2 \
     Calendar \
     Camera2 \
     ...

Android.bp

android_app_import {
    name: "demo",       //要编译生成apk名字,单编译模块时候 make MyApp
    // this needs to be a privileged application
    privileged: true,    //当一个模块被标识为 privileged: true 时,它将被视为具有特权权限,
    					 //可以访问系统级别的资源或执行特权操作。
    // Make sure the build system doesn't try to resign the APK
    dex_preopt: {
        enabled: true,  // 是否启用dex预优化 是否预先生成dex文件,默认为true。
                        // 该属性会影响应用的首次启动速度及Android系统的启动速度
    },
    arch: {            //通过cpu平台类型选择apk
        arm: {
            apk: "demo.apk",
        },
        arm64: {
            apk: "demo.apk",
        },
        x86: {
            apk: "demo.apk",
        },
        x86_64: {
            apk: "demo.apk",
        },
    },
   certificate: "platform", // 指定APK的签名方式
}


//类似
android_app_import {
    name: "SogouInput",
    apk: "SogouInput.apk",
    // 保留apk自己的签名
    // presigned: true,
    // 打开将放到对应分区目录的priv-app文件夹下
    privileged: true, 
    // 使用系统签名
    certificate: "platform",
    // 打开将放到system_ext分区
    // system_ext_specific: true, 
    // 打开将放到product分区
    // product_specific: true, 
    // 打开将放到vendor分区
    // proprietary: true,
    // device_specific: true
    dex_preopt: {
        enabled: false,
    },
}

Android 13 内置三方应用app zzh
可能遇到的问题,预置apk 有没有需要带so库,预置的整个apk是可以卸载还是不能卸载?

//权限问题
frameworks/base/data/etc/privapp-permissions-platform.xml

//Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Module name should match apk name to be installed
LOCAL_MODULE := MyExample
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_PREBUILT_JNI_LIBS := lib\arm64-v8a\xxxx.so
LOCAL_CERTIFICATE := PRESIGNED
include $(BUILD_PREBUILT)

Android预置第三方Apk,so库不能读取问题
预置无源码apk到Android系统(带so文件)
Android.mk参数解析

添加第三方应用apk文件

LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := xxx.apk
LOCAL_MODULE_CLASS := APPS
#可以为user、eng、tests、optional,optional代表在任何版本下都编译
LOCAL_MODULE_TAGS := optional
#编译模块的名称
LOCAL_MODULE := Taobao
#可以为testkey、platform、shared、media、PRESIGNED(使用原签名),platform代表为系统应用
LOCAL_CERTIFICATE := testkey
#应用输出路径,此处为data/app
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
#module的后缀,可不设置
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_DEX_PREOPT := false #不进行预先优化,一般第三方应用会避免优化,而导致APP各种异常
include $(BUILD_PREBUILT)

android内置可卸载APP集成方案

posted @ 2024-04-14 19:29  僵小七  阅读(1165)  评论(0编辑  收藏  举报