首页 > 其他分享 >Android 13 about launcher3 (1)

Android 13 about launcher3 (1)

时间:2024-08-17 16:39:39浏览次数:9  
标签:about java packageName Android return Launcher3 com launcher3 android

Android 13 Launcher3
android13#launcher3#分屏相关

Launcher3修改 wm density界面布局不改变

/packages/apps/Launcher3/src/com/android/launcher3/InvariantDeviceProfile.java
Launcher的默认配置加载类,通过InvariantDeviceProfile方法可以看出,
CellLayout显示的应用行数和列数可以通过findClosestDeviceProfiles查询XML配置来读取配参

Launcher3图标布局原理解析

Android 13 diff

index 02ebb15cd1..36ce9bf7bf 100644
--- a/packages/apps/Launcher3/src/com/android/launcher3/util/DisplayController.java
+++ b/packages/apps/Launcher3/src/com/android/launcher3/util/DisplayController.java
@@ -284,7 +284,7 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
         if (change != 0) {
             mInfo = newInfo;
             final int flags = change;
-            MAIN_EXECUTOR.execute(() -> notifyChange(displayInfoContext, flags));
+            //MAIN_EXECUTOR.execute(() -> notifyChange(displayInfoContext, flags));
         }
     }
  

Android 11 diff

./packages/apps/Launcher3/src/com/android/launcher3/util/ConfigMonitor.java

   @Override
    public void onDisplayChanged(int displayId) {
        if (displayId != mDisplayId) {
            return;
        }
        Display display = getDefaultDisplay(mContext);
        display.getRealSize(mTmpPoint1);
 
        if (!mRealSize.equals(mTmpPoint1) && !mRealSize.equals(mTmpPoint1.y, mTmpPoint1.x)) {
            LogUtils.d(TAG, String.format("Display size changed from %s to %s", mRealSize, mTmpPoint1));
            notifyChange();
            return;
        }
 
        display.getCurrentSizeRange(mTmpPoint1, mTmpPoint2);
        if (!mSmallestSize.equals(mTmpPoint1) || !mLargestSize.equals(mTmpPoint2)) {
            LogUtils.d(TAG, String.format("Available size changed from [%s, %s] to [%s, %s]",
                    mSmallestSize, mLargestSize, mTmpPoint1, mTmpPoint2));
            notifyChange();
        }
    }
 
    public synchronized void notifyChange() {
 
        if (mCallback != null) {
            Consumer<Context> callback = mCallback;
            mCallback = null;
            new MainThreadExecutor().execute(() -> {
 
        //add text
        //LauncherAppMonitor.getInstance(mContext).onUIConfigChanged();
        //callback.accept(mContext);
        //add text
 
            });
        }
    }

Android 13 关于旋转屏幕之后,按home键回Launcher3失效

//自动旋转
public static final String ACCELEROMETER_ROTATION = "accelerometer_rotation";
adb shell settings get system accelerometer_rotation  --> 0 off 1 on

Android 12之后,Launcher3有两个模式,一个是平板,另一个是手机.
手机模式:桌面默认是不可以旋转的.

桌面设置页面:桌面空白处长按,进入home settings,有个allow home screen rotation就是旋转开关,手机模式默认是关闭的,平板模式这个偏好隐藏了.

./packages/apps/Launcher3/res/values/config.xml    
<string name="settings_fragment_name" translatable="false">com.android.launcher3.settings.SettingsActivity$LauncherSettingsFragment</string>

./packages/apps/Launcher3/src/com/android/launcher3/settings/SettingsActivity.java
public static class LauncherSettingsFragment extends PreferenceFragmentCompat 
{
    protected boolean initPreference(Preference preference) {
            switch (preference.getKey()) {
                case NOTIFICATION_DOTS_PREFERENCE_KEY:
                    return !WidgetsModel.GO_DISABLE_NOTIFICATION_DOTS;

                case ALLOW_ROTATION_PREFERENCE_KEY:
                    DisplayController.Info info =
                            DisplayController.INSTANCE.get(getContext()).getInfo();
                    if (info.isTablet(info.realBounds)) {
                        // Launcher supports rotation by default. No need to show this setting.
                        //是平板,不显示这个选项
                        return false;
                    }
                    // Initialize the UI once //非平板,默认显示,
                    preference.setDefaultValue(RotationHelper.getAllowRotationDefaultValue(info));//控制是否旋转
                    return true;
                    ...
                    
    }
}

./packages/apps/Launcher3/src/com/android/launcher3/states/RotationHelper.java
    public static boolean getAllowRotationDefaultValue(DisplayController.Info info) {
        android.util.Log.d("tag","info.currentSize.x: " +info.currentSize.x);
        android.util.Log.d("tag","info.currentSize.y: " +info.currentSize.y);
        float originalSmallestWidth = dpiFromPx(Math.min(info.currentSize.x, info.currentSize.y),
                DENSITY_DEVICE_STABLE);
        return originalSmallestWidth >= MIN_TABLET_WIDTH;//MIN_TABLET_WIDTH = 600;
    }
    
    
    public static float dpiFromPx(float size, int densityDpi) {
        float densityRatio = (float) densityDpi / DisplayMetrics.DENSITY_DEFAULT;//DENSITY_DEFAULT=160;
        return (size / densityRatio);
    }
    
    //关于DENSITY_DEVICE_STABLE
    private static int getDeviceDensity() {
        //ro.sf.lcd_density的值在初始化进程的时候从build.prop里读取写入一次,之后不会修改
        //qemu.sf.lcd_density覆写上边的值,目的是在模拟器的时候可以动态修改
        return SystemProperties.getInt("qemu.sf.lcd_density",
                SystemProperties.getInt("ro.sf.lcd_density", DENSITY_DEFAULT));
    }
    
    initialize()->初始化setIgnoreAutoRotateSettings
    
    private void setIgnoreAutoRotateSettings(boolean ignoreAutoRotateSettings,
            DisplayController.Info info) {
        // On large devices we do not handle auto-rotate differently.
        mIgnoreAutoRotateSettings = ignoreAutoRotateSettings;
        if (!mIgnoreAutoRotateSettings) {
            mHomeRotationEnabled = LauncherPrefs.get(mActivity).get(ALLOW_ROTATION);
            LauncherPrefs.get(mActivity).addListener(this, ALLOW_ROTATION);
        } else {
            LauncherPrefs.get(mActivity).removeListener(this, ALLOW_ROTATION);
        }
    }
    

    //手动控制屏幕旋转的方式
    
    private void setOritation(int i) {
        try {
            IWindowManager windowManagerService = WindowManagerGlobal.getWindowManagerService();
 		if (i == 0) {
                windowManagerService.freezeRotation(0);
                Settings.System.putInt(this.mContext.getContentResolver(), "accelerometer_rotation", 0);//关闭自动旋转
            } else if (i == 90) {
                windowManagerService.freezeRotation(1);
                Settings.System.putInt(this.mContext.getContentResolver(), "accelerometer_rotation", 0);
            } else if (i == 180) {
                windowManagerService.freezeRotation(2);
                Settings.System.putInt(this.mContext.getContentResolver(), "accelerometer_rotation", 0);
            } else if (i == 270) {
                windowManagerService.freezeRotation(3);
                Settings.System.putInt(this.mContext.getContentResolver(), "accelerometer_rotation", 0);
            } else if (i == -1) {
                Settings.System.putInt(this.mContext.getContentResolver(), "accelerometer_rotation", 1);//打开自动旋转
            }
        } catch (Exception e) {
		...
       }
    }
    
    Settings.System.getInt(mContext.getContentResolver(), Settings.System.USER_ROTATION, 0);
    adb shell settings get system user_rotation(修改后查询)
    
    
//修改  默认打开主界面旋转
+++ b/packages/apps/Launcher3/res/xml/launcher_preferences.xml
@@ -45,7 +45,7 @@
         android:key="pref_allowRotation"
         android:title="@string/allow_rotation_title"
         android:summary="@string/allow_rotation_desc"
-        android:defaultValue="false"
+        android:defaultValue="true"
         android:persistent="true"
         launcher:logIdOn="615"
         launcher:logIdOff="616" />
diff --git a/packages/apps/Launcher3/src/com/android/launcher3/states/RotationHelper.java b/packages/apps/Launcher3/src/com/android/launcher3/states/RotationHelper.java
index 7b4e2485ce..6693f9f123 100644
--- a/packages/apps/Launcher3/src/com/android/launcher3/states/RotationHelper.java
+++ b/packages/apps/Launcher3/src/com/android/launcher3/states/RotationHelper.java
@@ -55,7 +55,7 @@ public class RotationHelper implements OnSharedPreferenceChangeListener,
         // original dimensions to determine if rotation is allowed of not.
         float originalSmallestWidth = dpiFromPx(Math.min(info.currentSize.x, info.currentSize.y),
                 DENSITY_DEVICE_STABLE);
-        return originalSmallestWidth >= MIN_TABLET_WIDTH;
+        return true;//originalSmallestWidth >= MIN_TABLET_WIDTH;//add text
     }
    

从源头隐藏某个apk不在最近应用(RecentView)显示

//这个改法:再需要隐藏的app,按Recent,有动画时显得卡顿,建议可以在Launcher3内尝试隐藏
frameworks/base/services/core/java/com/android/server/wm/RecentTasks.java

    /**
     * @return the list of recent tasks for presentation.
     */
    private ArrayList<ActivityManager.RecentTaskInfo> getRecentTasksImpl(int maxNum, int flags,
            boolean getTasksAllowed, int userId, int callingUid) {
        final boolean withExcluded = (flags & RECENT_WITH_EXCLUDED) != 0;

        if (!isUserRunning(userId, FLAG_AND_UNLOCKED)) {
            Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
            return new ArrayList<>();
        }
        loadUserRecentsLocked(userId);

        final Set<Integer> includedUsers = getProfileIds(userId);
        includedUsers.add(Integer.valueOf(userId));

        final ArrayList<ActivityManager.RecentTaskInfo> res = new ArrayList<>();
        final int size = mTasks.size();
        int numVisibleTasks = 0;
        for (int i = 0; i < size; i++) {
            final Task task = mTasks.get(i);

            if (isVisibleRecentTask(task)) {
                numVisibleTasks++;
                if (isInVisibleRange(task, i, numVisibleTasks, withExcluded)) {
                    // Fall through
                } else {
                    // Not in visible range
                    continue;
                }
            } else {
                // Not visible
                continue;
            }

            // Skip remaining tasks once we reach the requested size
            if (res.size() >= maxNum) {
                continue;
            }

            // Only add calling user or related users recent tasks
            if (!includedUsers.contains(Integer.valueOf(task.mUserId))) {
                if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + task);
                continue;
            }

            ...

            //add text
            ComponentName cn = task.intent.getComponent();
            if(cn != null && cn.getPackageName().equals("com.xxx.xxx")){
                continue;
            }else{
                res.add(createRecentTaskInfo(task, true /* stripExtras */));
            }
            //add text
            
        }
        return res;
    }
    

Android T Launcher3
Android T Launcher3_recentView

T replace default launcher

关于3.0Ver 利用role不需要删除旧Launcher栈的补充.
case 1: 单独使用role,确实不需要删除旧Launcher栈,唯一需要注意点的是要在Launcher启动之前,把android.app.role.HOME替换,
所以需要在framework里某个必经之路上做文章..

//about home role
packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/role/model/HomeRoleBehavior.java
packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/role/ui/ManageRoleHolderStateLiveData.java

packages/modules/Permission/service/java/com/android/role/RoleService.java
addRoleHolderAsUser(...)
removeRoleHolderAsUser(...)
getRoleHoldersAsUser(...)


frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

+import android.app.role.RoleManager;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+

    @Override
    public void systemReady() {
        // In normal flow, systemReady is called before other system services are ready.
        // So it is better not to bind keyguard here.
        mKeyguardDelegate.onSystemReady();
        ...
        mAutofillManagerInternal = LocalServices.getService(AutofillManagerInternal.class);
        mGestureLauncherService = LocalServices.getService(GestureLauncherService.class);
+        setDefaultLauncherItemToHomeRole(mContext);//add
    }
    
    public void setDefaultLauncherItemToHomeRole(Context context) {
        RoleManager roleManager = context.getSystemService(RoleManager.class);
        String packageName = SystemProperties.get("persist.xx.def_xxx_launcher", null);
        
        List<String> list = roleManager_1.getRoleHolders("android.app.role.HOME");
        boolean repeat_flag = false;
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).equals(packageName)) {
                flag = true;
            }
        }
        
        if (repeat_flag) return;
        
        if (packageName != null && !"".equals(packageName)) {
            String roleName = "android.app.role.HOME";
            boolean add = true;
            int flags = 0;
            UserHandle user = Process.myUserHandle();
            Log.d("tag", "role: " + roleName + ", package: " + packageName);
            Executor executor = context.getMainExecutor();
            Consumer<Boolean> callback = successful -> {
                if (successful) {
                    Log.d("tag", "Success , role: " + roleName + ", package: " + packageName);
                } else {
                    Log.d("tag", "Failed , role: " + roleName + ", package: " + packageName);
                }
            };
            roleManager.addRoleHolderAsUser(roleName, packageName, flags, user, executor, callback);
        }
    }

case 2:ResolverActivity

frameworks/base/core/java/com/android/internal/app/ResolverActivity.java
onCreate()->rebuildList()->onPostListReady()->isAutolaunching()...                        

    protected void onCreate(Bundle savedInstanceState, Intent intent,
            CharSequence title, int defaultTitleRes, Intent[] initialIntents,
            List<ResolveInfo> rList, boolean supportsAlwaysUseOption) {
        setTheme(appliedThemeResId());
        super.onCreate(savedInstanceState);
        //add text
        if(true){
            setDefaultLauncher("com.xx.xxx");
            finish();
            return;
        }
        //add text
        mQuietModeManager = createQuietModeManager();
        ...
    }    
    
    //add text
    private List<ResolveInfo> getResolveInfoList() {
        PackageManager pm = getPackageManager();
        Intent intent = new Intent(Intent.ACTION_MAIN, null);
        intent.addCategory(Intent.CATEGORY_HOME);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        return pm.queryIntentActivities(intent, 0);
    }

    private ResolveInfo getCurrentLauncher() {
        PackageManager pm = getPackageManager();
        Intent intent = new Intent(Intent.ACTION_MAIN, null);
        intent.addCategory(Intent.CATEGORY_HOME);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        return pm.resolveActivity(intent, 0);
    }

    private void setDefaultLauncher(String packageName) {
        PackageManager pm = getPackageManager();
        ResolveInfo oldCurrentLauncher = getCurrentLauncher();
        List<ResolveInfo> packageInfos = getResolveInfoList();

        ResolveInfo customerLauncher = null;

        for (ResolveInfo ri : packageInfos) {
            if (!TextUtils.isEmpty(ri.activityInfo.packageName) && !TextUtils.isEmpty(packageName)
                    && TextUtils.equals(ri.activityInfo.packageName, packageName)) {
                customerLauncher = ri;
            }
        }

        if (customerLauncher == null) return;

        pm.clearPackagePreferredActivities(oldCurrentLauncher.activityInfo.packageName);//clear old Launcher
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intent.ACTION_MAIN);
        intentFilter.addCategory(Intent.CATEGORY_HOME);
        intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
        ComponentName componentName = new ComponentName(customerLauncher.activityInfo.packageName,
                customerLauncher.activityInfo.name);
        ComponentName[] componentNames = new ComponentName[packageInfos.size()];
        int defaultMatch = 0;
        for (int i = 0; i < packageInfos.size(); i++) {
            ResolveInfo resolveInfo = packageInfos.get(i);
            componentNames[i] = new ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name);
            if (defaultMatch < resolveInfo.match) {
                defaultMatch = resolveInfo.match;
            }
        }
        pm.clearPackagePreferredActivities(oldCurrentLauncher.activityInfo.packageName);
        pm.addPreferredActivity(intentFilter, defaultMatch, componentNames, componentName);
    }
    //add text

Android13设置默认Launcher分析
Android13设置默认Launcher分析
RK3588 Android13 预安装自己的apk应用及把这个应用设置为默认桌面
Android R设置默认桌面

标签:about,java,packageName,Android,return,Launcher3,com,launcher3,android
From: https://www.cnblogs.com/kato-T/p/18364590

相关文章

  • Android架构组件中的MVVM
    Android架构组件中的MVVM(Model-View-ViewModel)模式是一种广泛应用的设计模式,它通过将应用程序分为三个主要部分(Model、View、ViewModel)来分离用户界面和业务逻辑,从而提高代码的可维护性、可扩展性和可测试性。下面将详细介绍MVVM模式在Android开发中的实战应用,包括基本概念......
  • Android开发 - 使用自定义接口在新窗口中传回数据
    在Android开发中,有时候我们需要在新打开的窗口中传递数据回来。例如:在新打开的DialogFragment窗口传递数据回MainActivity启动窗口代码举例首先在MainActivity中定义实例化一个DialogFragment窗口//MainActivity.java//点击按钮打开一个DialogFragment窗口......
  • Android Linux EAS优化-schedtune
    SchedTuneSchedTune是一项与CPU调频相关的性能提升技术,它实现为一个cgroup控制器。这个控制器提供了一个名称为schedtune.boost的配置参数,运行时系统可以使用它来更改该组中的进程的调度方式。每当调整这个参数的时候,它会使受影响的进程看起来比实际更重(或更轻)。如果一个组被提......
  • 腾讯地图SDK Android版开发 3 显示定位
    地图SDKAndroid版开发3显示定位前言概念定位数据定位模式定位样式类显示定位地图包相关类和接口TencentMapLocationSourceLocationSource.OnLocationChangedListener示例代码模拟定位显示效果图获取定位定位包相关类和接口TencentLocationManagerTencentLocationRe......
  • 腾讯地图SDK Android版开发 5 地图交互操作
    腾讯地图SDKAndroid版开发5地图交互操作前言控件介绍控件介绍接口控件常量地图控件点击事件示例代码效果图地图手势地图手势方法说明地图手势开关地图手势事件当地图被点击时回调接口当地图被长按时回调接口地图手势识别的回调地图状态地图状态类地图状态构造类地......
  • 基于flask+vue框架的基于Android的大学校园车辆管理系统统后[开题+论文+程序]-计算机
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着大学校园规模的不断扩大与师生数量的激增,校园内的车辆管理问题日益凸显。传统的人工管理方式不仅效率低下,难以满足高峰时段的车辆进出......
  • 将Android手机的屏幕投屏到macos系统上
    技术分享点: 将Android手机的屏幕投屏到macos上 先安装scrcpy: 1.在macos终端安装scrcpy brewinstallscrcpy---在macos上执行 若macos上没有adb、则需要安装 brewinstallandroid-platform-tools 进行相关配置 WIFI使用: 1.确保PC和手机在同一Wifi中 ......
  • 【GiraKoo】Android Studio替换gradle中的JCenter源
    由于JCenter关闭,一些陈旧的库需要替换Jcenter源。在C://users/xxxx/.gradle/init.gradle(如果没有,需自行创建)中更新以下内容。allprojects{repositories{defALIYUN_REPOSITORY_URL='https://maven.aliyun.com/repository/public'defALIYUN_JCENTER_U......
  • Android T 关于屏幕旋转 (一)
    (Tto13)需求:Settings里面添加一个屏幕旋转的选项//资源文件diff---a/packages/apps/Settings/res/values-zh-rCN/strings.xml+++b/packages/apps/Settings/res/values-zh-rCN/strings.xml@@-5988,4+5988,6@@<stringname="personalize_dashboard_summary">隐......
  • Android经典实战之约束布局ConstraintLayout的实用技巧和经验
    本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点ConstraintLayout是Android中一种强大的布局管理器,能够帮助你创建复杂而灵活的布局。它通过约束系统将一个View的位置和大小与其他View或父布局联系起来,使得......