android - 从包名获取前台 Activity ?

标签 android android-activity android-5.0-lollipop

我正在尝试从包名称中获取正在运行的 Activity 名称(前台 Activity 名称),众所周知,我们可以获得当前正在运行的 Activity 名称
通过这条线

mActivityManager.getRunningTasks(1).get(0).topActivity.getClassName()

但这项工作仅在 android 5.0 以下我需要在 5.0 以上相同的东西

我能得到当前的包名但不能得到 Activity

最佳答案

Android Lollipop 增强了安全性;有关详细信息,请参阅本文:getAppTask

您可以通过 UsageStats 类获取前台 Activity ;首先,您必须在 list 中添加此权限:

<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"
                                    tools:ignore="ProtectedPermissions"/>

和这个声明:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="your_application_package">

这将禁用警告,即权限是系统级别的,不会授予第三方应用程序。设备的用户可以通过“设置”应用授予权限。

因此,在您的 MainActivity 的 onCreate() 方法中,检查用户是否授予了此权限

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
        if(!hasPermission()){
            startActivityForResult(
                    new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS),
                    Constant.MY_PERMISSIONS_REQUEST_PACKAGE_USAGE_STATS);
        }
    }

如果没有,要求用户启用它:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == Constant.MY_PERMISSIONS_REQUEST_PACKAGE_USAGE_STATS){
        if (!hasPermission()){
            startActivityForResult(
                    new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS),
                    Constant.MY_PERMISSIONS_REQUEST_PACKAGE_USAGE_STATS);
        }
    }
}
private boolean hasPermission() {
    AppOpsManager appOps = (AppOpsManager)
            getSystemService(Context.APP_OPS_SERVICE);
    int mode = 0;
    if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.KITKAT) {
        mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS,
                android.os.Process.myUid(), getPackageName());
    }
    return mode == AppOpsManager.MODE_ALLOWED;
}

最后,这是一个放在后台服务中的 fragment ,它为您提供当前前台 Activity 的包名称:

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private String getUsageStatsForegroundActivityName() {


    UsageStatsManager mUsageStatsManager = (UsageStatsManager) MyApplication.getInstance().getSystemService(Context.USAGE_STATS_SERVICE);
    long endTime = System.currentTimeMillis();
    long beginTime = endTime - 1000 * 60;

    // result
    String topActivity = null;

    // We get usage stats for the last minute
    List<UsageStats> stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, beginTime, endTime);

    // Sort the stats by the last time used
    if (stats != null) {
        SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>();
        for (UsageStats usageStats : stats) {
            mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
        }
        if (mySortedMap != null && !mySortedMap.isEmpty()) {
            topActivity = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
            logger.info("topActivity: " + topActivity);
        }
    }
    if (topActivity != null)
        return topActivity;
    else
        return Constant.ACTIVITY_NOT_FOUND;

}

关于android - 从包名获取前台 Activity ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33710196/

相关文章:

Android,加载声音并立即播放?

java - 在 Android Activity 中保存/重新加载数据,可能使用单独的类

java - findViewById() 可能会为 HomeFragment.java 中的 getView() 产生 NullPointerException

Android 5.0 Toolbar fragment backstack

android - PackageManager.FEATURE_WEBVIEW 有什么用?

android - 如何在自定义时间开始通知?

android - 如何在 Flutter 应用中播放 .mp3 文件?

java - HashMap 删除不起作用

android - 从堆栈中删除 Activity

android - 如何在 ListView 中的禁用项之间添加分隔线? - Lollipop