检查应用程序是否在前台运行

时间:2016-03-30 00:19:03

标签: android service process permissions

在我的一个应用程序中,由于public class Board { public Board() { InitializeCards(); } private readonly List<Card> cards = new List<Card>(); private readonly Dictionary<int, int> cardsDictionary= new Dictionary<int, int>(); private void InitializeCards() { cards.Clear(); cardsDictionary.Clear(); // Fill the cards list with the cards, and the cardsDictionary with all the ID's and each match, using the cardsDisctionary.Add(someCard.ID, someOtherCard.ID) } private bool IsMatch(int id, int matchId) { int realMatch; if (cardsDictionary.TryGetValue(id, out realMatch)) { return matchId == realMatch; } return false; } } (不是我的),我需要手动启动应用程序。之后,我想知道Intent启动的这个应用程序是在前台,后台运行还是被杀死。

我创建了很多示例和片段,展示了如何获取正在运行的进程/应用程序列表,但他们正在调用自API 21以来已被弃用的方法,如Intenthttp://developer.android.com/reference/android/app/ActivityManager.html)。

其他方法(如ActivityManager.RunningTasks(..))仅返回我当前的应用程序而不是其他所有应用程序。我知道这是访问个人信息的安全问题,但没有别的办法吗?

编辑1

在查看Android API后,我找到了课程ActivityManager.RunningAppProcessInfo,并通过以下帖子判断,它似乎是另一种选择:How to get list of recent apps with Android API 21 Lollipop?。我尝试使用UsageStatsManager,但结果并不令人满意。我有一项服务,旨在定期验证所选应用程序是否在前台。

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

编辑2

看另一个例子(),我改写了我的<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions"/>函数,但仍然没有工作。我的isAppForeground列表始终为空。

UsageStats

提前致谢。

1 个答案:

答案 0 :(得分:0)

查看我的应用程序设置,没有任何权限跟踪,因此我决定检查是否真正授予了权限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