检查应用程序是否 运行 在前台
Checking if an application is running in foreground
在我的一个应用程序中,由于 Intent
(不是我的),我需要手动启动一个应用程序。在那之后,我想知道这个由 Intent
启动的应用程序是 运行 在前台,在后台还是被杀死。
我创建了很多示例和片段,展示了如何获取 运行 processes/applications 的列表,但它们调用的方法自 API 21 以来已被弃用,例如 [=15] =] (http://developer.android.com/reference/android/app/ActivityManager.html).
其他方法如 ActivityManager.RunningAppProcessInfo
仅 return 我当前的应用程序而不是所有其他方法。我知道这是访问个人信息的安全问题,但是没有其他办法吗?
编辑 1
看了AndroidAPI,发现了classUsageStatsManager
,从下面的post判断,好像是备选的:How to get list of recent apps with Android API 21 Lollipop?。我尝试使用 UsageStatsManager
但结果并不令人满意。我有一项服务旨在定期验证所选应用程序是否在前台。
public class CastService extends Service
{
private static final String TAG = "CastService";
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
ResolveInfo launchable = (ResolveInfo)intent.getExtras().get("selectedApp");
final String packageName = launchable.activityInfo.packageName;
final Handler handler = new Handler();
final int delay = 2000; // ms
handler.postDelayed(new Runnable()
{
@Override
public void run()
{
Log.i(TAG, "isAppInactive(" + packageName + ") : " + isAppInactive(packageName));
handler.postDelayed(this, delay);
}
}, delay);
return Service.START_NOT_STICKY;
}
@Override
public IBinder onBind(Intent intent)
{
return null;
}
protected boolean isAppInactive(String packageName)
{
UsageStatsManager usageStatsManager = (UsageStatsManager)getSystemService(Context.USAGE_STATS_SERVICE);
return usageStatsManager.isAppInactive(packageName);
}
}
该服务工作正常,每两秒记录一次方法 isAppInactive
的结果。不幸的是,即使相关应用程序在后台或被杀死,结果也不会改变:
I/CastService: isAppInactive(com.sec.android.gallery3d) : false
我以为我忘记在 AndroidManifest.xml
中添加权限,但它并没有解决它。
<uses-permission
android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions"/>
编辑 2
查看另一个示例 (),我重写了 isAppForeground
函数,但仍然无法正常工作。我的 UsageStats
列表总是空的。
protected boolean isAppForeground(String packageName)
{
UsageStatsManager usageStatsManager = (UsageStatsManager)getSystemService(Context.USAGE_STATS_SERVICE);
long time = System.currentTimeMillis();
List<UsageStats> stats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000 * 10, time);
String topPackageName = new String();
if(stats != null)
{
SortedMap<Long,UsageStats> mySortedMap = new TreeMap<>();
for (UsageStats usageStats : stats)
{
mySortedMap.put(usageStats.getLastTimeUsed(),usageStats);
}
if(mySortedMap != null && !mySortedMap.isEmpty())
{
topPackageName = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
}
}
return topPackageName.equals(packageName);
}
提前致谢。
查看我的应用程序设置,没有权限的踪迹,所以我决定检查权限 PACKAGE_USAGE_STATS
是否真的被授予,感谢以下功能。
public static boolean isPermissionGranted(Context context, String permission)
{
AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
int mode = appOps.checkOpNoThrow(permission, android.os.Process.myUid(), context.getPackageName());
boolean granted = mode == AppOpsManager.MODE_ALLOWED;
Log.i(TAG, "isPermissionGranted(" + permission + ", " + android.os.Process.myUid() + ", " + context.getPackageName() + ") : " + granted);
return granted;
}
我在调试模式下测试我的应用程序,它没有要求我允许之前的权限。多亏了终端和 adb 命令行,我手动授予了权限,我在之前编辑中定义的函数 isAppForeground
终于可以正常工作了。
adb -d shell pm grant com.package.name android.permission.PACKAGE_USAGE_STATS
在我的一个应用程序中,由于 Intent
(不是我的),我需要手动启动一个应用程序。在那之后,我想知道这个由 Intent
启动的应用程序是 运行 在前台,在后台还是被杀死。
我创建了很多示例和片段,展示了如何获取 运行 processes/applications 的列表,但它们调用的方法自 API 21 以来已被弃用,例如 [=15] =] (http://developer.android.com/reference/android/app/ActivityManager.html).
其他方法如 ActivityManager.RunningAppProcessInfo
仅 return 我当前的应用程序而不是所有其他方法。我知道这是访问个人信息的安全问题,但是没有其他办法吗?
编辑 1
看了AndroidAPI,发现了classUsageStatsManager
,从下面的post判断,好像是备选的:How to get list of recent apps with Android API 21 Lollipop?。我尝试使用 UsageStatsManager
但结果并不令人满意。我有一项服务旨在定期验证所选应用程序是否在前台。
public class CastService extends Service
{
private static final String TAG = "CastService";
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
ResolveInfo launchable = (ResolveInfo)intent.getExtras().get("selectedApp");
final String packageName = launchable.activityInfo.packageName;
final Handler handler = new Handler();
final int delay = 2000; // ms
handler.postDelayed(new Runnable()
{
@Override
public void run()
{
Log.i(TAG, "isAppInactive(" + packageName + ") : " + isAppInactive(packageName));
handler.postDelayed(this, delay);
}
}, delay);
return Service.START_NOT_STICKY;
}
@Override
public IBinder onBind(Intent intent)
{
return null;
}
protected boolean isAppInactive(String packageName)
{
UsageStatsManager usageStatsManager = (UsageStatsManager)getSystemService(Context.USAGE_STATS_SERVICE);
return usageStatsManager.isAppInactive(packageName);
}
}
该服务工作正常,每两秒记录一次方法 isAppInactive
的结果。不幸的是,即使相关应用程序在后台或被杀死,结果也不会改变:
I/CastService: isAppInactive(com.sec.android.gallery3d) : false
我以为我忘记在 AndroidManifest.xml
中添加权限,但它并没有解决它。
<uses-permission
android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions"/>
编辑 2
查看另一个示例 (),我重写了 isAppForeground
函数,但仍然无法正常工作。我的 UsageStats
列表总是空的。
protected boolean isAppForeground(String packageName)
{
UsageStatsManager usageStatsManager = (UsageStatsManager)getSystemService(Context.USAGE_STATS_SERVICE);
long time = System.currentTimeMillis();
List<UsageStats> stats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000 * 10, time);
String topPackageName = new String();
if(stats != null)
{
SortedMap<Long,UsageStats> mySortedMap = new TreeMap<>();
for (UsageStats usageStats : stats)
{
mySortedMap.put(usageStats.getLastTimeUsed(),usageStats);
}
if(mySortedMap != null && !mySortedMap.isEmpty())
{
topPackageName = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
}
}
return topPackageName.equals(packageName);
}
提前致谢。
查看我的应用程序设置,没有权限的踪迹,所以我决定检查权限 PACKAGE_USAGE_STATS
是否真的被授予,感谢以下功能。
public static boolean isPermissionGranted(Context context, String permission)
{
AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
int mode = appOps.checkOpNoThrow(permission, android.os.Process.myUid(), context.getPackageName());
boolean granted = mode == AppOpsManager.MODE_ALLOWED;
Log.i(TAG, "isPermissionGranted(" + permission + ", " + android.os.Process.myUid() + ", " + context.getPackageName() + ") : " + granted);
return granted;
}
我在调试模式下测试我的应用程序,它没有要求我允许之前的权限。多亏了终端和 adb 命令行,我手动授予了权限,我在之前编辑中定义的函数 isAppForeground
终于可以正常工作了。
adb -d shell pm grant com.package.name android.permission.PACKAGE_USAGE_STATS