What do you do when you want to track whether a particular application has been launched on Android?
METHOD 1: POLLING TASK LIST REGULARLY
Unless the application that you want to monitor gives specific broadcast intents when it launches, the only way is to regularly poll the running task list and get the topmost activity off of that list — that would be the foreground app. So, you could, in theory, have a background service running every 5 seconds, polling the running task list in order to achieve this. (Remember 5 seconds is too low and Alarm Manager is probably not the right thing for it as 1: its not exact timing based and 2: system will move things around for timers less than 1 minute — so your alarm won’t be launched that often all the time.)
In your activity, you could create the following method to create a 1 minute timer with AlarmManager. This would create a broadcast intent. Don’t forget to call the method!
private void setAlarm(){ private static final long timeInMillis = TimeUnit.MINUTES.toMillis(1); AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(this, MyAlarm.class); PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0); alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(), timeInMillis, pendingIntent); }
Now, you would create a MyAlarm broadcast receiver such that when the AlarmManager fires the broadcast intent every 1 minute, you will catch it on your receiver and process it. Note that you will need to declare the broadcast receiver on the manifest file.
public class MyAlarm extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // code to check the task list. } } }
We have the code for the repeated 1 minute call setup! Next, we put together the code to check the task list.
String topPackageName = null; if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) { ActivityManager am = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE); ActivityManager.RunningTaskInfo foregroundTaskInfo = am.getRunningTasks(1).get(0); topPackageName = foregroundTaskInfo.topActivity.getPackageName(); }else{ UsageStatsManager usage = (UsageStatsManager) this.getSystemService(Context.USAGE_STATS_SERVICE); long time = System.currentTimeMillis(); List<UsageStats> stats = usage.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000*1000, time); if (stats != null) { SortedMap<Long, UsageStats> runningTask = new TreeMap<Long,UsageStats>(); for (UsageStats usageStats : stats) { runningTask.put(usageStats.getLastTimeUsed(), usageStats); } if (runningTask.isEmpty()) { topPackageName="None"; } topPackageName = runningTask.get(runningTask.lastKey()).getPackageName(); } } Log.e("Task List", "Current App in foreground is: " + topPackageName);
Put the code above in the onReceive method of the MyAlarm broadcast receiver that we created earlier and that’s all setup.
You will need to add the following permissions to the manifest file.
<uses-permission android:name="android.permission.GET_TASKS" /> <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions"/>
Downside to this method is that it does not seem to work 100% of the time. I noticed that sometimes it would return launcher as the foreground app even though there’s Chrome running on the top. So, use it with caution. The next method although very reliable, cannot be used if you’re going to put your app on PlayStore. :)
METHOD 2: USING ACCESSIBILITY SERVICE
Like I mentioned above, you won’t be able to go very far with this method if you’re trying to put your app on Play Store. This is because this method makes use of AccessibilityService, a service that’s meant to be used by Accessibility related applications only. So we are kind of misusing it. But, depending on your use case, this might still be useful to you!
What are we doing? We are using AccessiblityService to listen to a particular event i.e. WINDOW_STATE_CHANGED event. So whenever a window state change occurs on the phone, our Service will get a callback or sort of a broadcast. We can then narrow down to the application’s package name, and see which application is on the foreground. That means we won’t need to poll the task list regularly like in Method 1.
The method is explained in detail over here on StackOverflow.
Thank you!
PS. None of the codes above were originally written by me. They have been put together by copying off of StackOverflow and other websites.
No related posts.