有些时候系统里预装了两个电话、桌面这样的应用,开机启动后系统会弹框让你选择使用那一个。
在系统设置中应用和通知里发现有默认应用选项,点进去发现是在 PermissionController 中
默认列表界面
adb shell dumpsys window | findstr mCurrentFocus
mCurrentFocus=Window{ffb6aca u0 com.android.permissioncontroller/com.android.packageinstaller.role.ui.DefaultAppListActivity}
默认应用详情界面
adb shell dumpsys window | findstr mCurrentFocus
mCurrentFocus=Window{d2fceb3 u0 com.android.permissioncontroller/com.android.packageinstaller.role.ui.DefaultAppActivity}
点击 Preference 切换是最终调用的代码走到 setRoleHolderAsUser()
vendor\mediatek\proprietary\packages\apps\PermissionController\src\com\android\packageinstaller\role\ui\ManageRoleHolderStateLiveData.java
public void setRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName, boolean add, int flags, @NonNull UserHandle user, @NonNull Context context) { if (getValue() != STATE_IDLE) { Log.e(LOG_TAG, "Already (tried) managing role holders, requested role: " + roleName + ", requested package: " + packageName); return; } if (DEBUG) { Log.i(LOG_TAG, (add ? "Adding" : "Removing") + " package as role holder, role: " + roleName + ", package: " + packageName); } mLastPackageName = packageName; mLastAdd = add; mLastFlags = flags; mLastUser = user; setValue(STATE_WORKING); RoleManager roleManager = context.getSystemService(RoleManager.class); Executor executor = context.getMainExecutor(); Consumer callback = successful -> { if (successful) { if (DEBUG) { Log.i(LOG_TAG, "Package " + (add ? "added" : "removed") + " as role holder, role: " + roleName + ", package: " + packageName); } setValue(STATE_SUCCESS); } else { if (DEBUG) { Log.i(LOG_TAG, "Failed to " + (add ? "add" : "remove") + " package as role holder, role: " + roleName + ", package: " + packageName); } setValue(STATE_FAILURE); } }; if (add) { roleManager.addRoleHolderAsUser(roleName, packageName, flags, user, executor, callback); } else { roleManager.removeRoleHolderAsUser(roleName, packageName, flags, user, executor, callback); } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
核心方法就是这个,那我们就可以仿照它来了,在 PermissionController 中监听开机广播,直接调用改方法设置默认应用就好。
各默认应用对应的 roleName 如下,改造一下 setRoleHolderAsUser(),传递 roleName 和 packageName
电话
role: android.app.role.DIALER, package: com.android.dialer
短信
role: android.app.role.SMS, package: com.android.mms
主屏幕
role: android.app.role.HOME, package: com.android.launcher3
浏览器
role: android.app.role.BROWSER, package: com.android.browser
vendor\mediatek\proprietary\packages\apps\PermissionController\AndroidManifest.xml
1
2
3
4
5
6
7
vendor\mediatek\proprietary\packages\apps\PermissionController\src\com\android\packageinstaller\TemporaryFileManager.java
package com.android.packageinstaller;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.SystemClock;
import android.util.Log;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import com.android.packageinstaller.permission.model.AppPermissionGroup;
import com.android.packageinstaller.permission.model.AppPermissions;
import com.android.packageinstaller.permission.model.Permission;
import com.android.packageinstaller.permission.utils.ArrayUtils;
import com.android.packageinstaller.permission.utils.Utils;
import java.util.List;
import java.io.File;
import java.io.IOException;
import android.app.role.RoleManager;
import android.os.UserHandle;
import android.os.Process;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
/**
* Manages files of the package installer and resets state during boot.
*/
public class TemporaryFileManager extends BroadcastReceiver { private static final String LOG_TAG = TemporaryFileManager.class.getSimpleName(); private void setBootFlag(Context context, int flag){ SharedPreferences sharedPreferences = context.getSharedPreferences("boot_CONFIG", Context.MODE_PRIVATE); Editor editor = sharedPreferences.edit(); editor.putInt("boot_flag", flag).commit(); } private boolean isFirstBoot(Context context){ SharedPreferences sharedPreferences = context.getSharedPreferences("boot_CONFIG", Context.MODE_PRIVATE); return sharedPreferences.getInt("boot_flag", 0) == 0; } @Override public void onReceive(Context context, Intent intent) { Log.e("permission", "action==="+ intent.getAction()); if (isFirstBoot(context)) { setRoleHolderAsUser(context, "com.android.dialer"); setBootFlag(context, 1); } long systemBootTime = System.currentTimeMillis() - SystemClock.elapsedRealtime(); File[] filesOnBoot = context.getNoBackupFilesDir().listFiles(); if (filesOnBoot == null) { return; } for (int i = 0; i < filesOnBoot.length; i++) { File fileOnBoot = filesOnBoot[i]; if (systemBootTime > fileOnBoot.lastModified()) { boolean wasDeleted = fileOnBoot.delete(); if (!wasDeleted) { Log.w(LOG_TAG, "Could not delete " + fileOnBoot.getName() + " onBoot"); } } else { Log.w(LOG_TAG, fileOnBoot.getName() + " was created before onBoot broadcast was " + "received"); } } } public void setRoleHolderAsUser(Context context, String packageName) { String roleName = "android.app.role.DIALER"; boolean add = true; int flags = 0; UserHandle user = Process.myUserHandle(); Log.i("permission", (add ? "Adding" : "Removing") + " package as role holder, role: " + roleName + ", package: " + packageName); RoleManager roleManager = context.getSystemService(RoleManager.class); Executor executor = context.getMainExecutor(); Consumer callback = successful -> { if (successful) { Log.d("permission", "Package " + (add ? "added" : "removed") + " as role holder, role: " + roleName + ", package: " + packageName); } else { Log.d("permission", "Failed to " + (add ? "add" : "remove") + " package as role holder, role: " + roleName + ", package: " + packageName); } }; roleManager.addRoleHolderAsUser(roleName, packageName, flags, user, executor, callback); Log.i("permission", "addRoleHolderAsUser done"); }
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
文章来源: blog.csdn.net,作者:android UGG,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/u012932409/article/details/112133761