I am creating a app lock application. How to get current running task in lollipop? getRunningTaskinfo method is deprecated in lollipop API, then how to overcome this problem?
- 126
- 15
- 2,656
- 2
- 16
- 24
-
You could use the UsageStatsManager to query for events (not usage stats), but as per documentation, the last minutes (actually seconds) are cut off to prevent non-system applications to know what application is currently running. – David Corsalini Jan 21 '15 at 12:00
8 Answers
try this:
ActivityManager mActivityManager =(ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE);
if(Build.VERSION.SDK_INT > 20){
String mPackageName = mActivityManager.getRunningAppProcesses().get(0).processName;
}
else{
String mpackageName = mActivityManager.getRunningTasks(1).get(0).topActivity.getPackageName();
}
we can get using UsageStats:
public static String getTopAppName(Context context) {
ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
String strName = "";
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
strName = getLollipopFGAppPackageName(context);
} else {
strName = mActivityManager.getRunningTasks(1).get(0).topActivity.getClassName();
}
} catch (Exception e) {
e.printStackTrace();
}
return strName;
}
private static String getLollipopFGAppPackageName(Context ctx) {
try {
UsageStatsManager usageStatsManager = (UsageStatsManager) ctx.getSystemService("usagestats");
long milliSecs = 60 * 1000;
Date date = new Date();
List<UsageStats> queryUsageStats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, date.getTime() - milliSecs, date.getTime());
if (queryUsageStats.size() > 0) {
Log.i("LPU", "queryUsageStats size: " + queryUsageStats.size());
}
long recentTime = 0;
String recentPkg = "";
for (int i = 0; i < queryUsageStats.size(); i++) {
UsageStats stats = queryUsageStats.get(i);
if (i == 0 && !"org.pervacio.pvadiag".equals(stats.getPackageName())) {
Log.i("LPU", "PackageName: " + stats.getPackageName() + " " + stats.getLastTimeStamp());
}
if (stats.getLastTimeStamp() > recentTime) {
recentTime = stats.getLastTimeStamp();
recentPkg = stats.getPackageName();
}
}
return recentPkg;
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
// TO ENABLE USAGE_STATS
// Declare USAGE_STATS permisssion in manifest
<uses-permission
android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" />
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
startActivity(intent);
- 838
- 9
- 18
-
This returns the process name instead of the package name. They're sometimes different. – Sam May 16 '15 at 03:15
-
This seems to use the base activity instead of the top activity for API 20-. Shouldn't it be the top activity? – Sam May 16 '15 at 03:16
-
1
-
@WenChao, note the bit in the code that says `.processName`. The default process name for an app's components is the app's package name. However, an app can specify a different process name for its components. The correct way to get the packages associated with a process is to use the `.pkgList` property. – Sam Nov 04 '16 at 22:06
-
@Sam I'm facing difficulties as you mentioned in first comment . got different name rather than package name above 21. Is there any work around ? – Tejas Pandya Jan 17 '18 at 07:50
-
@Tej, see https://stackoverflow.com/questions/3873659/android-how-can-i-get-the-current-foreground-activity-from-a-service for a number of options. But the simple answer is that this is not supported by Android and you shouldn't do it. – Sam Jan 17 '18 at 08:13
-
@Tej, oh, it looks like I found a workaround in [my second comment](https://stackoverflow.com/questions/28066231/how-to-gettopactivity-name-or-get-current-running-application-package-name-in-lo/28066580?noredirect=1#comment68113245_28066580). – Sam Jan 17 '18 at 08:14
Best solution of get Running app in API 21 or up is below try it. this work for me
private String retriveNewApp() {
if (VERSION.SDK_INT >= 21) {
String currentApp = null;
UsageStatsManager usm = (UsageStatsManager) this.getSystemService(Context.USAGE_STATS_SERVICE);
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<>();
for (UsageStats usageStats : applist) {
mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
}
if (mySortedMap != null && !mySortedMap.isEmpty()) {
currentApp = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
}
}
Log.e(TAG, "Current App in foreground is: " + currentApp);
return currentApp;
}
else {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
String mm=(manager.getRunningTasks(1).get(0)).topActivity.getPackageName();
Log.e(TAG, "Current App in foreground is: " + mm);
return mm;
}
}
- 189
- 1
- 5
-
About SDK_INT >=21 case, which of the apps there have their processes still alive ? – android developer Sep 21 '16 at 06:39
-
public static final String USAGE_STATS_SERVICE Added in API level 22 Use with getSystemService(Class ) to retrieve a UsageStatsManager for querying device usage stats. – Ahmad Shahwaiz Jul 26 '18 at 07:38
-
I used above code and applist is always null in my case..Android Version is 5.1, minSdkVersion 19, compileSdkVersion 28, targetSdkVersion 28...please how to solve this..?? – Bhavesh Moradiya Oct 27 '18 at 06:32
-
1run time permission for android.provider.Settings.ACTION_USAGE_ACCESS_SETTINGS solved problem – Bhavesh Moradiya Oct 27 '18 at 11:12
-
You can use the AccessibilityService to get current Running app. Accessibility Service provides the onAccessibilityEvent event.
Following is some sample code.
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
if (event.getPackageName() != null && event.getClassName() != null) {
Log.d("Foreground App", event.getPackageName().toString());
}
}
}
You can find more info about Accessibility Service here
- 961
- 7
- 16
- 314
- 3
- 6
-
Unfortunately it may be incorrect. e.g. launcher app can be triggered suddenly after appearing of the foreground app – Vlad Mar 28 '21 at 17:08
Are you sure? As I can see according to the latest Android docs, LOLLIPOP update doesnt allow you to know any info about other apps than your own!?
http://developer.android.com/reference/android/app/ActivityManager.html You can see that all those methods are deprecated!
- 560
- 3
- 18
according to this ; the following code worked perfectly for me :
MOVE_TO_FOREGROUND and MOVE_TO_BACKGROUND added in sdk 21 and deprecated in sdk 29
ACTIVITY_RESUMED and ACTIVITY_PAUSED added in sdk 29
public static String getTopPkgName(Context context) {
String pkgName = null;
UsageStatsManager usageStatsManager = (UsageStatsManager) context
.getSystemService(Context.USAGE_STATS_SERVICE);
final long timeTnterval= 1000 * 600;
final long endTime = System.currentTimeMillis();
final long beginTime = endTime - timeTnterval;
final UsageEvents myUsageEvents = usageStatsManager .queryEvents(beginTime , endTime );
while (myUsageEvents .hasNextEvent()) {
UsageEvents.Event myEvent = new UsageEvents.Event();
myUsageEvents .getNextEvent(myEvent );
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
switch (myEvent .getEventType()) {
case UsageEvents.Event.ACTIVITY_RESUMED:
pkgName = myEvent .getPackageName();
break;
case UsageEvents.Event.ACTIVITY_PAUSED:
if (myEvent .getPackageName().equals(pkgName )) {
pkgName = null;
}
}
}else {
switch (event.getEventType()) {
case UsageEvents.Event.MOVE_TO_FOREGROUND:
pkgName = myEvent .getPackageName();
break;
case UsageEvents.Event.MOVE_TO_BACKGROUND:
if (myEvent .getPackageName().equals(pkgName )) {
pkgName = null;
}
}
}
}
return pkgName ;
}
- 256
- 5
- 10
Try this.. This worked for me.
ActivityManager activityManager = (ActivityManager) getSystemService (Context.ACTIVITY_SERVICE);
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP)
{
String packageName = activityManager.getRunningAppProcesses().get(0).processName;
}
else if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP)
{
String packageName = ProcessManager.getRunningForegroundApps(getApplicationContext()).get(0).getPackageName();
}
else
{
String packageName = activityManager.getRunningTasks(1).get(0).topActivity.getPackageName();
}
- 236
- 2
- 11
-
6
-
Note that `.processName` isn't always going to be the package name of the process. – Sam Nov 04 '16 at 22:08
-
3I just did a quick Google search, and `ProcessManager` seems to be a deprecated class in the [`AndroidProcesses`](https://github.com/jaredrummler/AndroidProcesses) library. – Sam Nov 04 '16 at 22:12
@Manish Godhani's answer (https://stackoverflow.com/a/38829083/8179249) works very well, but you have to give the right permissions for this !
See the two first points of that answer : https://stackoverflow.com/a/42560422/8179249
It works for me (before adding permissions I was getting 'null' too), as shown below :
- 102
- 3
- 16
Can be achieved like this.....
ActivityManager am =(ActivityManager)context.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
ActivityManager.RunningTaskInfo task = tasks.get(0); // current task
ComponentName rootActivity = task.baseActivity;
rootActivity.getPackageName();//*currently active applications package name*
For lollipop:
ActivityManager mActivityManager =(ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE);
if(Build.VERSION.SDK_INT > 20){
String activityName =mActivityManager.getRunningAppProcesses().get(0).processName;
}
else{
String activityName = mActivityManager.getRunningTasks(1).get(0).topActivity.getPackageName();
}
for complete example check this out...
- 735
- 10
- 31
-
[getRunningAppProcesses](https://developer.android.com/reference/android/app/ActivityManager.html#getRunningAppProcesses()) comes with a warning of only using it when in debug mode – Clocker Nov 26 '16 at 00:58