Cannot get foreground activity name in Android Lollipop 5.0 only

℡╲_俬逩灬. 提交于 2019-11-27 11:42:42

You need to use the new UsageStatsManager and call its queryUsageStats method to get the history of activities launched. Please note that the user will be required to provide access to usage stat on the device settings at Security->Apps with usage access.

Links:

UsageStatsManager documentation

queryUsageStats method documentation

This works for me on Lollipop (21):

    ActivityManager manager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);

    List<ActivityManager.RunningAppProcessInfo> tasks = manager.getRunningAppProcesses();

    Log.i("current_app",tasks.get(0).processName);
Vishal Butani

you can use below code and get the current foreground activity package name.

 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
        // intentionally using string value as Context.USAGE_STATS_SERVICE was
        // strangely only added in API 22 (LOLLIPOP_MR1)
        @SuppressWarnings("WrongConstant")
        UsageStatsManager usm = (UsageStatsManager) getSystemService("usagestats");
        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<Long, UsageStats>();
                    for (UsageStats usageStats : appList) {
                        mySortedMap.put(usageStats.getLastTimeUsed(),
                                usageStats);
                    }
                    if (mySortedMap != null && !mySortedMap.isEmpty()) {
                        currentApp = mySortedMap.get(
                                mySortedMap.lastKey()).getPackageName();
                    }
                }
    } else {
        ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> tasks = am
                        .getRunningAppProcesses();
                currentApp = tasks.get(0).processName;
    }

Add these permissions in to Manifest file (first one is for < API 21, second one for >= API 21).

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

As per getRunningTasks() docs:

This method was deprecated in API level 21. As of LOLLIPOP, this method is no longer available to third party applications: the introduction of document-centric recents means it can leak person information to the caller. For backwards compatibility, it will still return a small subset of its data: at least the caller's own tasks, and possibly some other tasks such as home that are known to not be sensitive.

an available but not best way is to use accessibility.

Declare an accessibility service in AndroidManifest xml file

<service
            android:name=".MyAccessibilityService"
            android:label="@string/accessibility_service_label"
            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
            <intent-filter>
                <action android:name="android.accessibilityservice.AccessibilityService" />
            </intent-filter>

            <meta-data
                android:name="android.accessibilityservice"
                android:resource="@xml/accessibility_service_config" />
        </service>

accessibility_service_config.xml file

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/accessibility_service_desc"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFlags="flagDefault|flagIncludeNotImportantViews"
    android:accessibilityFeedbackType="feedbackSpoken"
    android:notificationTimeout="100"
    android:canRetrieveWindowContent="true"
/>

store the activity name when window state changed

public class MyAccessibilityService extends AccessibilityService{
    public static String sActivityName;
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        // TODO Auto-generated method stub
        if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED){
            Log.d("activitytest", "onAccessibilityEvent with window state changed");
            sActivityName = event.getClassName().toString();
        }
    }

    @Override
    public void onInterrupt() {
        // TODO Auto-generated method stub

    }

}

The disadvantage is that you need to let users enable your accessibility service in Settings.

i have created a class that uses /system/bin/toolbox command to identify processes and then identifies visible application. Need to add identifies system apps with no UI and android launchers.

ProcessManager.java

Try this

public static boolean isForeground(Context context) {
    ActivityManager manager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
    List<ActivityManager.RunningAppProcessInfo> tasks = manager.getRunningAppProcesses();
    if(tasks.isEmpty())
        return false;

    for (ActivityManager.RunningAppProcessInfo task : tasks) {
        if(context.getPackageName().equalsIgnoreCase(task.processName)){
            return task.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
        }
    }
    return false;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!