Android跳转权限设置界面的终极适配(支持各大定制ROM)

前言:

当我们的用户使用App时不小心拒绝了某项必要权限,而导致无法正常使用。这时候希望重新去打开该权限,那么问题来了,Android厂家定制的room五花八门,很多时候却发现找不到权限管理的入口。为了解决这一问题,如果我们应用中直接提供权限管理入口给用户,是不是会很方便的解决用户这一困扰呢?经过一番研究,整理出了大部分国产手机直接打开权限管理界面的方法

权限界面的跳转

一般项目中我们都会通过一个类来管理我们的Permission,即PermissionPageUtils

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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
/**
* 权限请求页适配,不同手机系统跳转到不同的权限请求页
*
* @author Donkor
*/

public class PermissionPageUtils {
private final String TAG = "PermissionPageManager";
private Context mContext;
//自己的项目包名
private String packageName="com.zm.demo";

public PermissionPageUtils(Context context) {
this.mContext = context;
}

public void jumpPermissionPage() {
String name = Build.MANUFACTURER;
L.e(TAG, "jumpPermissionPage --- name : " + name);
switch (name) {
case "HUAWEI":
goHuaWeiMainager();
break;
case "vivo":
goVivoMainager();
break;
case "OPPO":
goOppoMainager();
break;
case "Coolpad":
goCoolpadMainager();
break;
case "Meizu":
goMeizuMainager();
break;
case "Xiaomi":
goXiaoMiMainager();
break;
case "samsung":
goSangXinMainager();
break;
case "Sony":
goSonyMainager();
break;
case "LG":
goLGMainager();
break;
default:
goIntentSetting();
break;
}
}

private void goLGMainager(){
try {
Intent intent = new Intent(packageName);
ComponentName comp = new ComponentName("com.android.settings", "com.android.settings.Settings$AccessLockSummaryActivity");
intent.setComponent(comp);
mContext.startActivity(intent);
} catch (Exception e) {
Toast.makeText(mContext, "跳转失败", Toast.LENGTH_LONG).show();
e.printStackTrace();
goIntentSetting();
}
}
private void goSonyMainager(){
try {
Intent intent = new Intent(packageName);
ComponentName comp = new ComponentName("com.sonymobile.cta", "com.sonymobile.cta.SomcCTAMainActivity");
intent.setComponent(comp);
mContext.startActivity(intent);
} catch (Exception e) {
Toast.makeText(mContext, "跳转失败", Toast.LENGTH_LONG).show();
e.printStackTrace();
goIntentSetting();
}
}

private void goHuaWeiMainager() {
try {
Intent intent = new Intent(packageName);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ComponentName comp = new ComponentName("com.huawei.systemmanager", "com.huawei.permissionmanager.ui.MainActivity");
intent.setComponent(comp);
mContext.startActivity(intent);
} catch (Exception e) {
Toast.makeText(mContext, "跳转失败", Toast.LENGTH_LONG).show();
e.printStackTrace();
goIntentSetting();
}
}

private static String getMiuiVersion() {
String propName = "ro.miui.ui.version.name";
String line;
BufferedReader input = null;
try {
Process p = Runtime.getRuntime().exec("getprop " + propName);
input = new BufferedReader(
new InputStreamReader(p.getInputStream()), 1024);
line = input.readLine();
input.close();
} catch (IOException ex) {
ex.printStackTrace();
return null;
} finally {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return line;
}

private void goXiaoMiMainager() {
String rom = getMiuiVersion();
L.e(TAG,"goMiaoMiMainager --- rom : "+rom);
Intent intent=new Intent();
if ("V6".equals(rom) || "V7".equals(rom)) {
intent.setAction("miui.intent.action.APP_PERM_EDITOR");
intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
intent.putExtra("extra_pkgname", packageName);
} else if ("V8".equals(rom) || "V9".equals(rom)) {
intent.setAction("miui.intent.action.APP_PERM_EDITOR");
intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.PermissionsEditorActivity");
intent.putExtra("extra_pkgname", packageName);
} else {
goIntentSetting();
}
mContext.startActivity(intent);
}

private void goMeizuMainager() {
try {
Intent intent = new Intent("com.meizu.safe.security.SHOW_APPSEC");
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.putExtra("packageName", packageName);
mContext.startActivity(intent);
} catch (ActivityNotFoundException localActivityNotFoundException) {
localActivityNotFoundException.printStackTrace();
goIntentSetting();
}
}

private void goSangXinMainager() {
//三星4.3可以直接跳转
goIntentSetting();
}

private void goIntentSetting() {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", mContext.getPackageName(), null);
intent.setData(uri);
try {
mContext.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}

private void goOppoMainager() {
doStartApplicationWithPackageName("com.coloros.safecenter");
}

/**
* doStartApplicationWithPackageName("com.yulong.android.security:remote")
* 和Intent open = getPackageManager().getLaunchIntentForPackage("com.yulong.android.security:remote");
* startActivity(open);
* 本质上没有什么区别,通过Intent open...打开比调用doStartApplicationWithPackageName方法更快,也是android本身提供的方法
*/
private void goCoolpadMainager() {
doStartApplicationWithPackageName("com.yulong.android.security:remote");
/* Intent openQQ = getPackageManager().getLaunchIntentForPackage("com.yulong.android.security:remote");
startActivity(openQQ);*/
}

private void goVivoMainager() {
doStartApplicationWithPackageName("com.bairenkeji.icaller");
/* Intent openQQ = getPackageManager().getLaunchIntentForPackage("com.vivo.securedaemonservice");
startActivity(openQQ);*/
}

/**
* 此方法在手机各个机型设置中已经失效
*
* @return
*/
private Intent getAppDetailSettingIntent() {
Intent localIntent = new Intent();
localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (Build.VERSION.SDK_INT >= 9) {
localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
localIntent.setData(Uri.fromParts("package", mContext.getPackageName(), null));
} else if (Build.VERSION.SDK_INT <= 8) {
localIntent.setAction(Intent.ACTION_VIEW);
localIntent.setClassName("com.android.settings", "com.android.settings.InstalledAppDetails");
localIntent.putExtra("com.android.settings.ApplicationPkgName", mContext.getPackageName());
}
return localIntent;
}

private void doStartApplicationWithPackageName(String packagename) {
// 通过包名获取此APP详细信息,包括Activities、services、versioncode、name等等
PackageInfo packageinfo = null;
try {
packageinfo = mContext.getPackageManager().getPackageInfo(packagename, 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
if (packageinfo == null) {
return;
}
// 创建一个类别为CATEGORY_LAUNCHER的该包名的Intent
Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
resolveIntent.setPackage(packageinfo.packageName);
// 通过getPackageManager()的queryIntentActivities方法遍历
List<ResolveInfo> resolveinfoList = mContext.getPackageManager()
.queryIntentActivities(resolveIntent, 0);
Log.e("PermissionPageManager", "resolveinfoList" + resolveinfoList.size());
for (int i = 0; i < resolveinfoList.size(); i++) {
Log.e("PermissionPageManager", resolveinfoList.get(i).activityInfo.packageName + resolveinfoList.get(i).activityInfo.name);
}
ResolveInfo resolveinfo = resolveinfoList.iterator().next();
if (resolveinfo != null) {
// packageName参数2 = 参数 packname
String packageName = resolveinfo.activityInfo.packageName;
// 这个就是我们要找的该APP的LAUNCHER的Activity[组织形式:packageName参数2.mainActivityname]
String className = resolveinfo.activityInfo.name;
// LAUNCHER Intent
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
// 设置ComponentName参数1:packageName参数2:MainActivity路径
ComponentName cn = new ComponentName(packageName, className);
intent.setComponent(cn);
try {
mContext.startActivity(intent);
} catch (Exception e) {
goIntentSetting();
e.printStackTrace();
}
}
}
}

另外:

当前已适配测试的机型包括小米,华为,三星,锤子。代码仅供参考。

坚持原创技术分享,您的支持将鼓励我继续创作!