【问题标题】:Checking if an application is running in foreground检查应用程序是否在前台运行
【发布时间】:2016-03-30 00:19:02
【问题描述】:

在我的一个应用程序中,由于Intent(不是我的),我需要手动启动一个应用程序。之后,我想知道Intent 启动的这个应用程序是在前台运行、在后台运行还是被杀死。

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

ActivityManager.RunningAppProcessInfo 等其他方法仅返回我当前的应用程序,而不返回所有其他方法。我了解这是个人信息访问的安全问题,但没有其他办法吗?

编辑 1

查看 Android API 后,我找到了 UsageStatsManager 类,从以下帖子判断,它似乎是一个替代方案: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);
}

提前致谢。

【问题讨论】:

    标签: android service process permissions


    【解决方案1】:

    查看我的应用程序设置,没有权限的痕迹,所以我决定检查权限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 命令行,我手动授予了权限,并且我在之前的 EDIT 中定义的函数isAppForeground 终于可以正常工作了。

    adb -d shell pm grant com.package.name android.permission.PACKAGE_USAGE_STATS

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多