Lollipop: Get top activity name - android

How to get top activity name in Lollipop?
((ActivityManager)getSystemService(Context.ACTIVITY_SERVICE)).
getRunningTasks(1).get(0).topActivity
is not longer available for Lollipop:
* #deprecated As of {#link android.os.Build.VERSION_CODES#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 retu rn 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.
Calling from onResume in MyActivity
MyApplication.getInstance().saveCurentActivity(MyActivity.this)
saveCurentActivity(Activity a) {
this.activityName = a.getClass().getSimpleName();
}
is no good idea, because MyApplication can be destroyed on error (for example, NPE).

This code is working for me.
ActivityManager activityManager = (ActivityManager) context.getSystemService(Activity.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfo = activityManager.getRunningTasks(1);
String currentTopActivity = taskInfo.get(0).topActivity.getClassName();
It will give TopActivity.

This worked for me:
long end = System.currentTimeMillis();
long INTERVAL=2000;
long begin = end - INTERVAL;
if (Build.VERSION.SDK_INT >= 21) {
UsageStatsManager us = (UsageStatsManager) MyServices.this.getSystemService(Context.USAGE_STATS_SERVICE);
UsageEvents usageEvents = us.queryEvents(begin, end);
while (usageEvents.hasNextEvent()) {
UsageEvents.Event event = new UsageEvents.Event();
usageEvents.getNextEvent(event);
if (event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
Log.e("event", "timestamp : " + event.getTimeStamp());
Log.e("event", "package name : " + event.getPackageName());
Log.e("event", "Class name : " + event.getClassName());
//You can find activity name as Class name
}
}
}

I'm not familiar with the original API you are using, but you can track Activity life-cycle changes in your app, using an ActivityLifecycleCallbacks that could be registered via Application.registerActivityLifecycleCallbacks. It would get notified whenever an Activity is created, started, resumed, etc. You might be able to track the current Activity using the onActivityResumed and onActivityPaused hooks.

Related

Time of Android phone on first boot after unboxing?

What will be the display time and date on first boot after unboxing android device if it is not connected to internet connection or without sim? On what basis the time and date is setup by default?
On the first boot, android will set the system time with Build.TIME. And Build.TIME is get from system prop ro.build.data.rtc, which is the time when the image is build. Some factory test will be executed in factory, so it will have been boot some times. It may not be the first boot when user unbox the phone, and boot it.
This is done by AlarmManagerService.java#onStart.
#Override
public void onStart() {
mInjector.init();
...
synchronized (mLock) {
mHandler = new AlarmHandler();
mConstants = new Constants();
...
// We have to set current TimeZone info to kernel
// because kernel doesn't keep this after reboot
setTimeZoneImpl(SystemProperties.get(TIMEZONE_PROPERTY));
// Ensure that we're booting with a halfway sensible current time. Use the
// most recent of Build.TIME, the root file system's timestamp, and the
// value of the ro.build.date.utc system property (which is in seconds).
final long systemBuildTime = Long.max(
1000L * SystemProperties.getLong("ro.build.date.utc", -1L),
Long.max(Environment.getRootDirectory().lastModified(), Build.TIME));
if (mInjector.getCurrentTimeMillis() < systemBuildTime) {
Slog.i(TAG, "Current time only " + mInjector.getCurrentTimeMillis()
+ ", advancing to build time " + systemBuildTime);
mInjector.setKernelTime(systemBuildTime);
}

Using UsageStatsManager to get the foreground app

I'm trying to use UsageStatsManager to get the foreground app on a Nexus 5 with Marshmallow. I remember it used to work, but for some reason I'm getting null strings for package/class names now.
Here's my implementation
public String[] getForegroundPackageNameClassNameByUsageStats() {
String packageNameByUsageStats = null;
String classByUsageStats = null;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
UsageStatsManager mUsageStatsManager = (UsageStatsManager)getSystemService("usagestats");
final long INTERVAL = 1000;
final long end = System.currentTimeMillis();
final long begin = end - INTERVAL;
final UsageEvents usageEvents = mUsageStatsManager.queryEvents(begin, end);
while (usageEvents.hasNextEvent()) {
UsageEvents.Event event = new UsageEvents.Event();
usageEvents.getNextEvent(event);
if (event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
packageNameByUsageStats = event.getPackageName();
classByUsageStats = event.getClassName();
Log.d(TAG, "packageNameByUsageStats is" + packageNameByUsageStats + ", classByUsageStats is " + classByUsageStats);
}
}
}
return new String[]{packageNameByUsageStats,classByUsageStats};
}
For some reason, it doesn't go into the while loop, i.e. usageEvents.hasNextEvent() is false. Because of this, it returns null package/class names.
Any idea what I'm doing wrong?
Thanks.
OK, so I found that once I set the interval to 10000 instead of 1000, it works. Apparently a 1s interval is too small.
I am using this myself. I think the usage stats will only be updated when an app comes to foreground. So if the foreground app got to the foreground (and stayed) before your 'begin' timestamp then you will not get it. :(
On the other hand when you use a long time ago you will get a giant list where you only need the highest time to determine the foreground app.
So what I do is I create 3 different times: 1min ago, 1 hour ago and 12 hours ago.
When I get an empty list on 1min I repeat request with 1h and so on. That way I get foreground most of the time. But I never get it to work ALL of the time.
I really miss the old way of just asking the package manager which app is foreground (prior to android 5), the new way is a bit messy.

How to prevent my application to get cached value of TimeZone.getDefault()?

I am using TimeZone.getDefault() to set the timezone of Calendar class:
Calendar cal = Calendar.getInstance(TimeZone.getDefault());
Log.i("TEST", cal.get(Calendar.HOUR) + ":" + cal.get(Calendar.MINUTE));
However, when users change the timezone of their device from Setting, my application represents the time using the former timezone until they force stop (from App info settings) the application and restart it.
How could I prevent the caching of getDefault()?
It's not pretty, but you could potentially call setDefault(null) to explicitly wipe the cached value. As per the documentation, this will only affect the current process (that is, your app).
Having nulled out the cached value, the next time you call getDefault(), the value is reconstructed freshly:
/**
* Returns the user's preferred time zone. This may have been overridden for
* this process with {#link #setDefault}.
*
* <p>Since the user's time zone changes dynamically, avoid caching this
* value. Instead, use this method to look it up for each use.
*/
public static synchronized TimeZone getDefault() {
if (defaultTimeZone == null) {
TimezoneGetter tzGetter = TimezoneGetter.getInstance();
String zoneName = (tzGetter != null) ? tzGetter.getId() : null;
if (zoneName != null) {
zoneName = zoneName.trim();
}
if (zoneName == null || zoneName.isEmpty()) {
try {
// On the host, we can find the configured timezone here.
zoneName = IoUtils.readFileAsString("/etc/timezone");
} catch (IOException ex) {
// "vogar --mode device" can end up here.
// TODO: give libcore access to Android system properties and read "persist.sys.timezone".
zoneName = "GMT";
}
}
defaultTimeZone = TimeZone.getTimeZone(zoneName);
}
return (TimeZone) defaultTimeZone.clone();
}
You should probably combine this with a broadcast listener for ACTION_TIMEZONE_CHANGED and only null out the default value if you receive such a broadcast.
Edit: come to think of it, a neater solution would be to extract the newly set time zone from the broadcast. From the broadcast documentation:
time-zone - The java.util.TimeZone.getID() value identifying the new time zone.
You can then simply use this identifier to update the cached default:
String tzId = ...
TimeZone.setDefault(TimeZone.getTimeZone(tzId));
Any subsequent calls to getDefault() will then return the correct/updated time zone.

Launch most recent app

I'm working on a productivity app and I would like to be able to launch the users most recent app when a gesture is detected, however, I can't figure out why this code below isn't launching my most recent app.
ActivityManager m = (ActivityManager)context.getSystemService(ACTIVITY_SERVICE);
RecentTaskInfo task = m.getRecentTasks(1, 0).get(0);
startActivity(task.baseIntent);
I also have this permission in my manifest
android.permission.GET_TASKS
Thank you for any help as to why this isn't working
RecentTaskInfo task = m.getRecentTasks(1, 0).get(0);
Since you are setting max number of results to 1, you are getting your own task with get(0). To get the result you are looking for, try setting the max # of results to 2 and use the second task from the returned list:
ActivityManager m = (ActivityManager)context.getSystemService(ACTIVITY_SERVICE);
RecentTaskInfo task = m.getRecentTasks(2, 0).get(1);
startActivity(task.baseIntent);
Below code works for me to get recent 30 apps:
private static final int MAX_TASKS = 30;
final ActivityManager am = (ActivityManager)
mContext.getSystemService(Context.ACTIVITY_SERVICE);
final List<ActivityManager.RecentTaskInfo> recentTasks =
am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE);

What i am doing wrong to get the UID

I saw similar types of posts here.But i am not getting this right.To get the UID of running process i wrote
ActivityManager mgr = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
List<RunningAppProcessInfo> processes = mgr.getRunningAppProcesses();
String text = "All Process:\n";
for (int i = 1; i <= processes.size(); i++)
{
String s;
s = processes.get(i - 1).processName.toString();
text += "Process:" + i + s + ":UID:" + android.os.Process.getUidForName(s) + "\n";
}
But after completion of loop what i am getting in the string text is all UID value as -1.I put GET_TASKS permission in manifest file.Why i am not getting the UID.Please help.I need this UID to kill the process.
To kill the process i used killBackgroundProcess Method of ActivityManager.It needs package name not the UID
Please see this answer by #seanhodges for reference.
Reading the whole thread might be helpful too.

Categories

Resources