前言:此方法没有使用无障碍、root、shizhuku等API,附上`Kotlin` 和 `java`两种代码,小白也能看懂
开门见山不啰嗦上代码
创建一个 Kotlin/java 文件/类,编写
getTopAppPackagename 方法
1 Kotlin:
/**
* ## 获取当前最顶层的应用
*/
@SuppressLint("ObsoleteSdkInt")
fun getTopAppPackagename(context: Context): Any = run {
//声明包名
var packagename = ""
//通过上下文获取 ActivityManager
val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
//根据安卓版本的不同进行处理
//情况1:安卓5.0以下(其实没必要做这个,现在手机没有这么低的了)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
//获取一个正在运行的任务数组
val runningTasks = activityManager.getRunningTasks(1)
//将此数组的第一个元素赋值给$packagename,这个就是前台运行的应用
packagename = runningTasks[0].topActivity!!.packageName
//安卓5.0(同样没必要)
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
// 获取正在运行的程序,放到数组中
val processes = activityManager.runningAppProcesses
if (processes.size == 0) return packagename
//遍历数组,如果遍历到权重最高的即是前台应用,返回其包名
processes.forEach {
if (it.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND)
return it.processName
}
// 安卓 5.0 以上通用,通过查看应用使用情况来判断栈顶的应用
} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
//获取当前时间
val endTime = System.currentTimeMillis()
//减去10秒,查询最近10秒内的应用使用情况
val startTime = endTime - 10000
//使用统计管理器
val usageStatsManager =
context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
// 获取最近10秒的应用使用日志事件
val usageEvents = usageStatsManager.queryEvents(startTime, endTime)
//创建一个使用事件对象
val event = UsageEvents.Event()
//声明最后移动到前景时间
var lastMoveToForegroundTime = 0L
//遍历最近10秒事件
while (usageEvents.hasNextEvent()) {
// 获取下一条事件
usageEvents.getNextEvent(event)
// 条件判断,符合条件即是前台应用
if (event.eventType == UsageEvents.Event.MOVE_TO_FOREGROUND && event.timeStamp > lastMoveToForegroundTime) {
lastMoveToForegroundTime = event.timeStamp
packagename = event.packageName
}
}
}
return packagename
}
考虑到会java的人不一定会 Kotlin, 附上Java代码,注释就免了看上面的一样:
@SuppressLint("ObsoleteSdkInt")
public static String getTopAppPackagename(Context context) {
String packagename = "";
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
List<ActivityManager.RunningTaskInfo> runningTasks = activityManager.getRunningTasks(1);
packagename = runningTasks.get(0).topActivity.getPackageName();
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = activityManager.getRunningAppProcesses();
if (runningAppProcesses.size() == 0) return packagename;
for (ActivityManager.RunningAppProcessInfo appProcess : runningAppProcesses) {
if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND)
return appProcess.processName;
}
} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
long end = System.currentTimeMillis();
long start = end - 10000;
UsageStatsManager statsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
UsageEvents usageEvents = statsManager.queryEvents(start, end);
UsageEvents.Event event = new UsageEvents.Event();
long lastMoveToForegroundTime = 0L;
while (usageEvents.hasNextEvent()) {
usageEvents.getNextEvent(event);
if (event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND && event.getTimeStamp() > lastMoveToForegroundTime) {
lastMoveToForegroundTime = event.getTimeStamp();
packagename = event.getPackageName();
}
}
}
return packagename;
}
能做啥
获取到当前栈顶的应用后,那能干的事儿可就多咯。
广告投放优化
安全性增强
比如可以禁止使用一些软件来保证自己应用的安全
应用性能优化
例如,如果你的应用不是当前活跃的应用,那可能不需要在后台执行资源密集型的任务,从而节省电池和处理器资源。
应用使用统计
这个就不用多说了吧
应用状态检测
指定应用的壁纸设置
例如哪些微信壁纸、QQ壁纸之类的
扩展
1 权限申请
使用此方法需要在清单文件中注册:
<!--查看应用使用情况-->
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"
5.0以上还需要在代码中动态申请(这个不用翻译成 java 了吧?):
val intent = Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS)
startActivityForResult(intent, USAGE_STATS_PERMISSION)
当然还要判断是否拥有这个权限,不然一打开就申请权限怪LOW的:
Kotlin:
fun haveUsageStatsPermission(context: Context) = run {
val appOpsManager = context.getSystemService(APP_OPS_SERVICE) as AppOpsManager
val i = appOpsManager.checkOpNoThrow(
"android:get_usage_stats",
Process.myUid(), context.packageName
)
val granted = i == AppOpsManager.MODE_ALLOWED
granted
}
java:
public static boolean haveUsageStatsPermission(Context context) {
AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
int i = appOpsManager.checkOpNoThrow(
"android:get_usage_stats",
Process.myUid(), context.getPackageName()
);
return i == AppOpsManager.MODE_ALLOWED;
}
2 后台保留
如果没有这个,你的应用在后台运行一段时间后就凉了,具体怎么做一搜一大堆,这里不多赘述。