-
-
Notifications
You must be signed in to change notification settings - Fork 302
/
AppInfoUtils.java
398 lines (360 loc) · 13.4 KB
/
AppInfoUtils.java
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
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
package dev.utils.app.info;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.content.pm.ResolveInfo;
import android.os.Build;
import androidx.annotation.RequiresApi;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import dev.utils.DevFinal;
import dev.utils.LogPrintUtils;
import dev.utils.app.AppUtils;
import dev.utils.common.FileUtils;
import dev.utils.common.ForUtils;
/**
* detail: APP 信息获取工具类
* @author Ttt
* <pre>
* Android 11 ( R ) 适配
* @see <a href="https://developer.android.com/about/versions/11/privacy/package-visibility"/>
* <p></p>
* Android 11 ( R ) 需要加该权限 ( 无需申请 ) 才能够获取安装列表
* <uses-permission
* android:name="android.permission.QUERY_ALL_PACKAGES"
* tools:ignore="QueryAllPackagesPermission"/>
* </pre>
*/
public final class AppInfoUtils {
private AppInfoUtils() {
}
// 日志 TAG
private static final String TAG = AppInfoUtils.class.getSimpleName();
/**
* 通过 APK 路径 初始化 PackageInfo
* @param file APK 文件路径
* @return {@link PackageInfo}
*/
public static PackageInfo getPackageInfoToFile(final File file) {
if (!FileUtils.isFileExists(file)) return null;
return getPackageInfoToPath(file.getAbsolutePath());
}
/**
* 通过 APK 路径 初始化 PackageInfo
* @param apkUri APK 文件路径
* @return {@link PackageInfo}
*/
public static PackageInfo getPackageInfoToPath(final String apkUri) {
PackageManager packageManager = AppUtils.getPackageManager();
if (packageManager == null) return null;
try {
PackageInfo packageInfo = packageManager.getPackageArchiveInfo(
apkUri, PackageManager.GET_ACTIVITIES
);
// 设置 APK 位置信息
ApplicationInfo appInfo = packageInfo.applicationInfo;
// 必须加这两句, 不然下面 icon 获取是 default icon 而不是应用包的 icon
appInfo.sourceDir = apkUri;
appInfo.publicSourceDir = apkUri;
return packageInfo;
} catch (Exception e) {
LogPrintUtils.eTag(TAG, e, "getPackageInfoToPath");
}
return null;
}
/**
* 获取当前应用 PackageInfo
* @return {@link PackageInfo}
*/
public static PackageInfo getPackageInfo() {
return getPackageInfo(AppUtils.getPackageName());
}
/**
* 通过包名 获取 PackageInfo
* @param packageName 应用包名
* @return {@link PackageInfo}
*/
public static PackageInfo getPackageInfo(final String packageName) {
try {
// 获取对应的 PackageInfo ( 原始的 PackageInfo 获取 signatures 等于 null, 需要这样获取 )
return AppUtils.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
} catch (Exception e) {
LogPrintUtils.eTag(TAG, e, "getPackageInfo");
}
return null;
}
// =============
// = 获取基本信息 =
// =============
/**
* 通过 APK 路径 获取 AppInfoBean
* @param file APK 文件路径
* @return {@link AppInfoBean}
*/
public static AppInfoBean getAppInfoBeanToFile(final File file) {
return AppInfoBean.get(getPackageInfoToFile(file));
}
/**
* 通过 APK 路径 获取 AppInfoBean
* @param apkUri APK 文件路径
* @return {@link AppInfoBean}
*/
public static AppInfoBean getAppInfoBeanToPath(final String apkUri) {
return AppInfoBean.get(getPackageInfoToPath(apkUri));
}
/**
* 获取当前应用 AppInfoBean
* @return {@link AppInfoBean}
*/
public static AppInfoBean getAppInfoBean() {
return AppInfoBean.get(getPackageInfo());
}
/**
* 通过包名 获取 AppInfoBean
* @param packageName 应用包名
* @return {@link AppInfoBean}
*/
public static AppInfoBean getAppInfoBean(final String packageName) {
return AppInfoBean.get(getPackageInfo(packageName));
}
// =============
// = 获取详细信息 =
// =============
/**
* 获取 APK 详细信息
* @param file APK 文件路径
* @return {@link ApkInfoItem}
*/
public static ApkInfoItem getApkInfoItem(final File file) {
if (!FileUtils.isFileExists(file)) return null;
return getApkInfoItem(file.getAbsolutePath());
}
/**
* 获取 APK 详细信息
* @param apkUri APK 文件路径
* @return {@link ApkInfoItem}
*/
public static ApkInfoItem getApkInfoItem(final String apkUri) {
try {
return ApkInfoItem.get(getPackageInfoToPath(apkUri));
} catch (Exception e) {
LogPrintUtils.eTag(TAG, e, "getApkInfoItem");
return null;
}
}
// =
/**
* 获取 APP 详细信息
* @return {@link AppInfoItem}
*/
public static AppInfoItem getAppInfoItem() {
try {
return AppInfoItem.get(getPackageInfo());
} catch (Exception e) {
LogPrintUtils.eTag(TAG, e, "getAppInfoItem");
return null;
}
}
/**
* 获取 APP 详细信息
* @param packageName 应用包名
* @return {@link AppInfoItem}
*/
public static AppInfoItem getAppInfoItem(final String packageName) {
try {
return AppInfoItem.get(getPackageInfo(packageName));
} catch (Exception e) {
LogPrintUtils.eTag(TAG, e, "getAppInfoItem");
return null;
}
}
// =
/**
* 获取全部 APP 列表
* @return APP 列表
*/
public static List<AppInfoBean> getAppLists() {
return getAppLists(AppInfoBean.AppType.ALL);
}
/**
* 获取 APP 列表
* @param appType APP 类型
* @return APP 列表
*/
public static List<AppInfoBean> getAppLists(final AppInfoBean.AppType appType) {
// APP 信息
List<AppInfoBean> listApps = new ArrayList<>();
// 防止为 null
if (appType != null) {
// 管理应用程序包
PackageManager packageManager = AppUtils.getPackageManager();
if (packageManager == null) return listApps;
try {
// 获取手机内所有应用
List<PackageInfo> packList = packageManager.getInstalledPackages(0);
// 判断是否属于添加全部
if (appType == AppInfoBean.AppType.ALL) {
// 遍历 APP 列表
for (int i = 0, len = packList.size(); i < len; i++) {
PackageInfo packageInfo = packList.get(i);
// 添加符合条件的 APP 应用信息
listApps.add(new AppInfoBean(packageInfo, packageManager));
}
} else {
// 遍历 APP 列表
for (int i = 0, len = packList.size(); i < len; i++) {
PackageInfo packageInfo = packList.get(i);
// 获取 APP 类型
AppInfoBean.AppType currentAppType = AppInfoBean.getAppType(packageInfo);
// 判断类型
if (appType.equals(currentAppType)) {
// 添加符合条件的 APP 应用信息
listApps.add(new AppInfoBean(packageInfo, packageManager));
}
}
}
} catch (Exception e) {
LogPrintUtils.eTag(TAG, e, "getAppLists");
}
}
return listApps;
}
// =
/**
* 获取 APP 注册的权限
* @return APP 注册的权限
*/
public static List<String> getAppPermissionToList() {
return new ArrayList<>(getAppPermissionToSet());
}
/**
* 获取 APP 注册的权限
* @return APP 注册的权限
*/
public static Set<String> getAppPermissionToSet() {
String[] permissions = getAppPermission();
// 防止数据为 null
if (permissions != null && permissions.length != 0) {
Set<String> permissionSets = new HashSet<>();
Collections.addAll(permissionSets, permissions);
return permissionSets;
}
return Collections.emptySet();
}
/**
* 获取 APP 注册的权限
* @return APP 注册的权限数组
*/
public static String[] getAppPermission() {
return getAppPermission(AppUtils.getPackageName());
}
/**
* 获取 APP 注册的权限
* @param packageName 应用包名
* @return APP 注册的权限数组
*/
public static String[] getAppPermission(final String packageName) {
PackageInfo packageInfo = AppUtils.getPackageInfo(
packageName, PackageManager.GET_PERMISSIONS
);
if (packageInfo == null) return null;
try {
return packageInfo.requestedPermissions;
} catch (Exception e) {
LogPrintUtils.eTag(TAG, e, "getAppPermission");
}
return null;
}
/**
* 打印 APP 注册的权限
* @param packageName 应用包名
*/
public static void printAppPermission(final String packageName) {
PackageManager packageManager = AppUtils.getPackageManager();
if (packageManager == null) {
LogPrintUtils.eTag(TAG, "printAppPermission => packageManager is null");
return;
}
StringBuilder builder = new StringBuilder();
try {
PackageInfo packageInfo = packageManager.getPackageInfo(
packageName, PackageManager.GET_PERMISSIONS
);
String[] usesPermissionsArray = packageInfo.requestedPermissions;
for (String usesPermissionName : usesPermissionsArray) {
// 获取每个权限的名字, 如: android.permission.INTERNET
// 拼接日志
builder.append("usesPermissionName = ").append(usesPermissionName);
builder.append(DevFinal.SYMBOL.NEW_LINE);
// 通过 usesPermissionName 获取该权限的详细信息
PermissionInfo permissionInfo = packageManager.getPermissionInfo(
usesPermissionName, 0
);
// 获取该权限属于哪个权限组, 如: 网络通信
PermissionGroupInfo permissionGroupInfo = packageManager.getPermissionGroupInfo(
permissionInfo.group, 0
);
// 拼接日志
builder.append("permissionGroup = ")
.append(permissionGroupInfo.loadLabel(packageManager).toString())
.append(DevFinal.SYMBOL.NEW_LINE);
// 获取该权限的标签信息, 比如: 完全的网络访问权限
String permissionLabel = permissionInfo.loadLabel(packageManager).toString();
// 拼接日志
builder.append("permissionLabel = ")
.append(permissionLabel)
.append(DevFinal.SYMBOL.NEW_LINE);
// 获取该权限的详细描述信息, 比如: 允许该应用创建网络套接字和使用自定义网络协议
// 浏览器和其他某些应用提供了向互联网发送数据的途径, 因此应用无需该权限即可向互联网发送数据
String permissionDescription = permissionInfo.loadDescription(packageManager).toString();
// 拼接日志
builder.append("permissionDescription = ").append(permissionDescription);
builder.append(DevFinal.SYMBOL.NEW_LINE);
}
// 打印日志
LogPrintUtils.dTag(TAG, builder.toString());
} catch (Exception e) {
LogPrintUtils.eTag(TAG, e, "printAppPermission");
}
}
// =
/**
* 获取所有能够显示在桌面上的应用
* @return 所有能够显示在桌面上的应用
*/
@RequiresApi(api = Build.VERSION_CODES.M)
public static List<ResolveInfo> getAllLauncherIconPackages() {
try {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
// set match_all to prevent any filtering of the results
return AppUtils.getPackageManager()
.queryIntentActivities(intent, PackageManager.MATCH_ALL);
} catch (Exception e) {
LogPrintUtils.eTag(TAG, e, "getAllLauncherIconPackages");
}
return null;
}
/**
* 获取所有能够显示在桌面上的应用包名
* @return 所有能够显示在桌面上的应用包名
*/
@RequiresApi(api = Build.VERSION_CODES.M)
public static List<String> getAllLauncherIconPackageNames() {
LinkedHashSet<String> names = new LinkedHashSet<>();
ForUtils.forList((index, value) -> {
if (value != null) {
names.add(value.activityInfo.packageName);
}
}, getAllLauncherIconPackages());
return new ArrayList<>(names);
}
}