Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Get the stack (array) of currently opened applications

Tags:

java

android

Is there any way to get the list of the currently running or opened android applications, so that I can found the last application running in the device. Thanks

like image 668
lRadha Avatar asked Jul 12 '26 01:07

lRadha


1 Answers

I was working on an emoji keyboard from fast few days. It take me three days to get the foreground application package name to send the emoji images, as whenever I want to send the images it just popups the intentchooser to choose one of the application those can handle the images as extras.

All the tutorials and links does not work for me as google deprecated the getRunningTasks() method that was used to get the currently running applications.

Then I got an idea to get the stack of the currently running applications on the device using ResolveInfo, but it did not work too.

Finally, I found a new class introduced in API 21 named UsageStatsManager which worked for me. This github link provide how to use this class to get the running applications packagename.

Below is my code how I got the package name application running on the top:

public class UStats {
    public static final String TAG = UStats.class.getSimpleName();
    @SuppressLint("SimpleDateFormat")
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("M-d-yyyy HH:mm:ss");

    public static ArrayList<String> printCurrentUsageStatus(Context context) {
        return printUsageStats(getUsageStatsList(context));
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public static ArrayList<String> printUsageStats(List<UsageStats> usageStatsList) {
        HashMap<String, Integer> lastApp = new HashMap<String, Integer>();
        for (UsageStats u : usageStatsList) {
            lastApp.put(u.getPackageName(), (int) u.getLastTimeStamp());
            /*Log.d(TAG, "Pkg: " + u.getPackageName() + "\t" + "ForegroundTime: "
                    + u.getTotalTimeInForeground() + "\t" + "LastTimeStamp: " + new Date(u.getLastTimeStamp()));*/
        }
        Map<String, Integer> sortedMapAsc = sortByComparator(lastApp);
        ArrayList<String> firstApp = new ArrayList<>();
        for (Map.Entry<String, Integer> entry : sortedMapAsc.entrySet()) {
            String key = entry.getKey();
            //Integer value = entry.getValue();
            firstApp.add(key);
            /*System.out.println("package name: " + key + ", time " + new Date(Math.abs(value)));*/
        }

        return firstApp;
    }

    // To check the USAGE_STATS_SERVICE permission
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public static List<UsageStats> getUsageStatsList(Context context) {
        UsageStatsManager usm = getUsageStatsManager(context);
        Calendar calendar = Calendar.getInstance();
        long endTime = calendar.getTimeInMillis();
        calendar.add(Calendar.MINUTE, -1);
        long startTime = calendar.getTimeInMillis();

        Log.d(TAG, "Under getUsageStateList");
        Log.d(TAG, "Range start:" + dateFormat.format(startTime));
        Log.d(TAG, "Range end:" + dateFormat.format(endTime));

        List<UsageStats> usageStatsList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, startTime, endTime);
        return usageStatsList;
    }

    // Sort the map in the ascending order of the timeStamp
    private static Map<String, Integer> sortByComparator(Map<String, Integer> unsortMap) {
        List<Map.Entry<String, Integer>> list = new LinkedList<>(unsortMap.entrySet());

        // Sorting the list based on values
        Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
            public int compare(Map.Entry<String, Integer> o1,
                               Map.Entry<String, Integer> o2) {
                return o2.getValue().compareTo(o1.getValue());
            }
        });

        // Maintaining insertion order with the help of LinkedList
        Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
        for (Map.Entry<String, Integer> entry : list) {
            sortedMap.put(entry.getKey(), entry.getValue());
        }
        return sortedMap;
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
    @SuppressWarnings("ResourceType")
    private static UsageStatsManager getUsageStatsManager(Context context) {
        UsageStatsManager usm = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
        return usm;
    }
}

Then I simply get the ArrayList of the application package names, using the below code:

ArrayList<String> sortedApplication = UStats.printCurrentUsageStatus(SimpleIME.this);
Log.d("TAG", "applicationList: " + sortedApplication.toString());

Don't forgot to add the permission:

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

and the below code to check that our application has the permission to get the other applications status:

if (UStats.getUsageStatsList(this).isEmpty()) {
    Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
    Toast.makeText(MainActivity.this, "Enable Usage Access for YOUR_APP_NAME to use this app", Toast.LENGTH_LONG).show();
    startActivity(intent);
}

The above code will open a access setting page to enable our application to get the other application usage stats (for once).

Hope this will help.

like image 196
lRadha Avatar answered Jul 13 '26 15:07

lRadha



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!