在开发中有时候会需要在第三方应用里使用自己的应用,比如输入法。这时如果想要获取用户在那个平台使用了自己的应用,就会很麻烦,一般情况下我们会考虑获取最顶层应用的包名,然后自己写死几个去比对。代码如下
/**
* 获取顶层应用包名
* @return
*/
public static String getTopPackageName(Context context) {
String packageName = "";
try {
ActivityManager am = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {// 5.0及以上版本用这种方法获取顶层包名
List<ActivityManager.RunningAppProcessInfo> processInfos = am
.getRunningAppProcesses();
if (processInfos != null) {
for (ActivityManager.RunningAppProcessInfo processInfo : processInfos) {
if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
return processInfo.pkgList[0];
}
}
}
} else {
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
packageName = cn.getPackageName();
}
} catch (Exception e) {
// handel exception
}
return packageName;
}
可是在我使用的过程中该代码,并没有发挥它的作用,我使用一加6手机测试时,根本获取不到,为了解决这个问题我在网上找了很多资料但是都不是,很好用,具体原因也不清楚,直到最后才在众多的博客中找到了一个有用的,在这片博客里作者提到了一个系统的权限,该权限是系统权限,叫做允许查看应用,只有当开启这个权限时才能获取到第三方应用的包名。代码如下
public static String getTaskPackname(Context context) {
String currentApp = "andord";
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
@SuppressLint("WrongConstant") UsageStatsManager usm = (UsageStatsManager) context.getSystemService("usagestats");
long time = System.currentTimeMillis();
List<UsageStats> appList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000 * 1000, time);
if (appList != null && appList.size() > 0) {
SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>();
for (UsageStats usageStats : appList) {
if (usageStats.getPackageName().equals("android")){
continue;
}
mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
}
if (mySortedMap != null && !mySortedMap.isEmpty()) {
currentApp = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
}
}
} else {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> tasks = am.getRunningAppProcesses();
currentApp = tasks.get(0).processName;
}
LogUtil.e("TAG", "Current App in foreground is: " + currentApp,"");
return currentApp;
}
该方法是用来获取包名的,开启权限的方法如下
//是否可以开启
private boolean isNoOption() {
PackageManager packageManager = getApplicationContext()
.getPackageManager();
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
List<ResolveInfo> list = packageManager.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
return list.size() > 0;
}
//是否是已开启
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private boolean isNoSwitch() {
long ts = System.currentTimeMillis();
@SuppressLint("WrongConstant")
UsageStatsManager usageStatsManager = (UsageStatsManager) getApplicationContext()
.getSystemService("usagestats");
List<UsageStats> queryUsageStats = usageStatsManager.queryUsageStats(
UsageStatsManager.INTERVAL_BEST, 0, ts);
if (queryUsageStats == null || queryUsageStats.isEmpty()) {
return false;
}
return true;
}
值得一提的是当时的作者说道,并不是说有的手机都会有这个权限,因为国内的一些厂商把该权限阉割了。我目前测试的一加6和vivo是可以的。最后也是重点一定要在清单文件里加上权限,否则就算跳到开启权限的页面,也没有该选项
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission xmlns:tools="http://schemas.android.com/tools"
android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" />