我正在创建一个应用锁程序。如何在Android5.0(棒棒糖)中获取当前正在运行的任务?因为在该版本中,
getRunningTaskinfo
方法已经被弃用,那么如何解决这个问题?getRunningTaskinfo
方法已经被弃用,那么如何解决这个问题?试试这个:
ActivityManager mActivityManager =(ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE);
if(Build.VERSION.SDK_INT > 20){
String mPackageName = mActivityManager.getRunningAppProcesses().get(0).processName;
}
else{
String mpackageName = mActivityManager.getRunningTasks(1).get(0).topActivity.getPackageName();
}
我们可以使用UsageStats来获取:
public static String getTopAppName(Context context) {
ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
String strName = "";
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
strName = getLollipopFGAppPackageName(context);
} else {
strName = mActivityManager.getRunningTasks(1).get(0).topActivity.getClassName();
}
} catch (Exception e) {
e.printStackTrace();
}
return strName;
}
private static String getLollipopFGAppPackageName(Context ctx) {
try {
UsageStatsManager usageStatsManager = (UsageStatsManager) ctx.getSystemService("usagestats");
long milliSecs = 60 * 1000;
Date date = new Date();
List<UsageStats> queryUsageStats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, date.getTime() - milliSecs, date.getTime());
if (queryUsageStats.size() > 0) {
Log.i("LPU", "queryUsageStats size: " + queryUsageStats.size());
}
long recentTime = 0;
String recentPkg = "";
for (int i = 0; i < queryUsageStats.size(); i++) {
UsageStats stats = queryUsageStats.get(i);
if (i == 0 && !"org.pervacio.pvadiag".equals(stats.getPackageName())) {
Log.i("LPU", "PackageName: " + stats.getPackageName() + " " + stats.getLastTimeStamp());
}
if (stats.getLastTimeStamp() > recentTime) {
recentTime = stats.getLastTimeStamp();
recentPkg = stats.getPackageName();
}
}
return recentPkg;
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
//启用USAGE_STATS
// Declare USAGE_STATS permisssion in manifest
<uses-permission
android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" />
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
startActivity(intent);
获取API 21或更高版本的正在运行的应用程序的最佳解决方案如下,请尝试使用。这对我起作用了。
private String retriveNewApp() {
if (VERSION.SDK_INT >= 21) {
String currentApp = null;
UsageStatsManager usm = (UsageStatsManager) this.getSystemService(Context.USAGE_STATS_SERVICE);
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<>();
for (UsageStats usageStats : applist) {
mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
}
if (mySortedMap != null && !mySortedMap.isEmpty()) {
currentApp = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
}
}
Log.e(TAG, "Current App in foreground is: " + currentApp);
return currentApp;
}
else {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
String mm=(manager.getRunningTasks(1).get(0)).topActivity.getPackageName();
Log.e(TAG, "Current App in foreground is: " + mm);
return mm;
}
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
if (event.getPackageName() != null && event.getClassName() != null) {
Log.d("Foreground App", event.getPackageName().toString());
}
}
}
public static String getTopPkgName(Context context) {
String pkgName = null;
UsageStatsManager usageStatsManager = (UsageStatsManager) context
.getSystemService(Context.USAGE_STATS_SERVICE);
final long timeTnterval= 1000 * 600;
final long endTime = System.currentTimeMillis();
final long beginTime = endTime - timeTnterval;
final UsageEvents myUsageEvents = usageStatsManager .queryEvents(beginTime , endTime );
while (myUsageEvents .hasNextEvent()) {
UsageEvents.Event myEvent = new UsageEvents.Event();
myUsageEvents .getNextEvent(myEvent );
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
switch (myEvent .getEventType()) {
case UsageEvents.Event.ACTIVITY_RESUMED:
pkgName = myEvent .getPackageName();
break;
case UsageEvents.Event.ACTIVITY_PAUSED:
if (myEvent .getPackageName().equals(pkgName )) {
pkgName = null;
}
}
}else {
switch (event.getEventType()) {
case UsageEvents.Event.MOVE_TO_FOREGROUND:
pkgName = myEvent .getPackageName();
break;
case UsageEvents.Event.MOVE_TO_BACKGROUND:
if (myEvent .getPackageName().equals(pkgName )) {
pkgName = null;
}
}
}
}
return pkgName ;
}
你确定吗?根据最新的Android文档,LOLLIPOP更新不允许您了解除自己应用之外的其他应用程序的任何信息!
http://developer.android.com/reference/android/app/ActivityManager.html 您可以看到所有这些方法都已被弃用!
试试这个...这对我有用。
ActivityManager activityManager = (ActivityManager) getSystemService (Context.ACTIVITY_SERVICE);
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP)
{
String packageName = activityManager.getRunningAppProcesses().get(0).processName;
}
else if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP)
{
String packageName = ProcessManager.getRunningForegroundApps(getApplicationContext()).get(0).getPackageName();
}
else
{
String packageName = activityManager.getRunningTasks(1).get(0).topActivity.getPackageName();
}
.processName
并不总是进程的包名称。 - Sam@Manish Godhani的答案(https://dev59.com/oV4c5IYBdhLWcg3wUI0N#38829083)非常有效,但您必须为此提供正确的权限!
请参阅该答案的前两个要点:https://dev59.com/5V8d5IYBdhLWcg3wzEv4#42560422
可以像这样实现......
ActivityManager am =(ActivityManager)context.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
ActivityManager.RunningTaskInfo task = tasks.get(0); // current task
ComponentName rootActivity = task.baseActivity;
rootActivity.getPackageName();//*currently active applications package name*
对于棒棒糖:
ActivityManager mActivityManager =(ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE);
if(Build.VERSION.SDK_INT > 20){
String activityName =mActivityManager.getRunningAppProcesses().get(0).processName;
}
else{
String activityName = mActivityManager.getRunningTasks(1).get(0).topActivity.getPackageName();
}
完整示例,请查看这里...
有三种方法可以获取屏幕上当前活动的名称。
这种方式需要用户的额外权限,并且用户需要手动为您的应用启用此权限。
您需要首先在清单中添加权限。
<uses-permission
android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" />
val intent = Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS)
startActivity(intent)
var lastActivityName: String? = null
private fun getCurrentActivityName(): String? {
val usageStatsManager =
applicationContext.getSystemService(USAGE_STATS_SERVICE) as UsageStatsManager
try {
val currentTimeMillis = System.currentTimeMillis()
var activityName: String? = null
var packageName: String? = null
val queryEvents = usageStatsManager.queryEvents(
currentTimeMillis - 60000.toLong(),
currentTimeMillis
)
while (queryEvents.hasNextEvent()) {
val event = UsageEvents.Event()
queryEvents.getNextEvent(event)
if (event.eventType == 1) {
packageName = event.packageName
activityName = event.className
}
else if (event.eventType == 2) {
if (event.packageName != packageName) {
break
}
packageName = null
}
}
return if (packageName != null && activityName != null) {
lastActivityName = activityName
activityName
} else lastActivityName
} catch (e: Exception) {
e.printStackTrace()
}
return null
}
lastActivityName
,因为有时候在同一个活动中可能会得到null,所以你可以将其移除。
这可以通过辅助功能服务实现。 但是自从Android 11之后,如果没有添加特殊权限,就无法获取其他包名的列表。
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
<queries>
<intent>
<action android:name="android.intent.action.MAIN" />
</intent>
</queries>
res/xml/accessibility_setting.xml
(文件名可以是任何名称)。<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagDefault|flagReportViewIds|flagIncludeNotImportantViews"
android:accessibilityEventTypes="typeWindowStateChanged"
android:canRequestFilterKeyEvents="true"
android:canRetrieveWindowContent="true" />
<service
android:name=".services.MyAccessibilityService"
android:label="@string/app_name"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
android:exported="true">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessibility_setting" />
</service>
MyAccessibilityService
服务类和用于获取当前活动名称的函数:class MyAccessibilityService : AccessibilityService() {
var currentActivityName : String? = null
override fun onServiceConnected() {
//Define your initial configs here
}
@Synchronized
override fun onAccessibilityEvent(event: AccessibilityEvent) {
checkForCurrentActivity(event)
}
override fun onInterrupt() {
// define your interruption code here
}
checkForCurrentActivity(event)
将是:private fun checkForCurrentActivity(event: AccessibilityEvent) {
if (event.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
if (event.packageName != null && event.className != null) {
val componentName = ComponentName(
event.packageName.toString(),
event.className.toString()
)
if (isActivity(componentName)) {
val componentFlattenName = componentName.flattenToShortString()
currentActivityName = componentFlattenName.replace("/.", ".")
if (currentActivityName.contains("/")) {
currentActivityName = currentActivityName.split("/".toRegex())[1]
}
}
}
}
}
private fun isActivity(componentName: ComponentName): Boolean {
return try {
packageManager.getActivityInfo(componentName, 0)
} catch (e: PackageManager.NameNotFoundException) {
null
} != null
}
最后,您可以通过使用currentActivityName
轻松获得当前活动的名称。
最后,我将向您展示一种仅通过辅助功能权限而不使用QUERY_ALL_PACKAGES
的方法来获取当前活动的名称。
这个解决方案基于第二个解决方案,但有一个小区别。对于这个hack,您需要用以下内容替换isActivity(componentName)
:
private fun isActivity(componentName: ComponentName):Boolean {
val name = componentName.flattenToShortString()
return name.contains("/") &&
!name.contains("com.android.systemui") &&
!name.contains("Layout") &&
!name.contains(".widget") &&
!name.contains("android.view") &&
!name.contains("android.material") &&
!name.contains("android.inputmethodservice") &&
!name.contains("$") &&
!name.contains("android.view") &&
!name.contains("android.app.dialog")
}
currentActivityName
轻松获取当前活动名称。