Empty (or fill) Recent Apps List - java

I have developed a baby app where I need to lock all keys and ways out of the app, in order to be able to hand over the phone to my daughter. I used the "replace home screen" method to capture the home key, and that works great. All other hard keys (except power button, but that's not an issue since it's not easily pressed anyway) are locked. But the often discussed long press of home key is still launching the recent apps and offers a way out (which of course the daughter finds almost instantly).
I have seen other apps in market (toddler lock and more) work around this by emptying the recent apps list (or filling it with an icon that leads back to the baby app), but I have no idea of how to accomplish this. Anyone have a solution? How do I fill the recent apps from my app? Toddler lock even resets the recent apps after the lock-app is exited.

You could create an activity in your application that does nothing, and start it with an intent with the FLAG_ACTIVITY_NEW_TASK flag set. Fire this intent however many times you need to fill the history (my Incredible has 8 spots). For repopulating the history, look into ActivityManager.RecentTaskInfo.getRecentTasks (int maxNum, int flags)
See Documentation
It looks like you need to hold the GET_TASKS permission
The intents that originally fired those apps are stored as baseIntent, so you should be able to store them yourself(don't forget the extras), and re-fire them in order to repopulate the history list.
This is a hack, but it should work
Edit: After playing with this a little, it looks like you would need to have 8 different activities for this method to work, which is not realistic.

You need to do what is described in Mobius's post, but also set android:taskAffinity="" on the dummy activity elements in the android manifest file.

Related

Why is resolveInfo.loadLabel () so ridiculously slow?

In my home screen replacement app, I have to get a list of all installed apps to put them inside the app drawer. Hence, the following method gets run on every app;
public static App fromResolveInfo (Context context, PackageManager pacMan, AppManager appManager, ResolveInfo resInf)
{
String label = resInf.loadLabel (pacMan).toString ();
String packageName = resInf.activityInfo.applicationInfo.packageName;
String activityName = resInf.activityInfo.name;
App app = new App (context, appManager);
app.setLabel (label);
app.setPackageName (packageName);
app.setActivityName (activityName);
AppIcon icon = null;
if (appManager.isIconPackLoaded ())
icon = appManager.getIconPack ().getIconForApp (app);
if (icon == null)
icon = appManager.getIconPack ().getFallbackIcon (resInf.loadIcon (pacMan));
app.setIcon (icon);
return app;
}
The problem is that there is a bottleneck here, and it's not he loading of the icons as I had originally anticipated. The first line of the method (String label = resInf.loadLabel (pacMan).toString ();) can take up anywhere between 0 and 250 milliseconds (on a relatively high-end device). On older devices, this becomes a real issue.
In my tests, I have noticed that when a slower device is multitasking and for some reason the app drawer has to be reloaded, it can take up to 30 seconds for this action to be completed (on all of the installed apps).
Caching could offer a potential solution for this, but then what if the name of an app changes (which occasionally happens)? I'd have to take the labels from the cache, and then loop over all of the apps in a separate thread and correct the labels where they have changed. This may offer a solution, but it seems more like a dirty hack than an actual good solution.
Is there any faster way to get the label of an app's activity? Also, why does it take so ridiculously long for Android to get an app's label, and/or is there anything that I can do about it?
You can get label as:
String label = (String) resInf.activityInfo.applicationInfo.loadLabel(pacMan);
If you compare Android source code for those two methods you will notice the one from applicationInfo has less code to execute. Maybe the bottleneck sits in the extra code. I personally never compared execution times for those as I never observed such issue.
To answer the original question "why?" ... As others have noted, the issue is that the label is localized, meaning it is read from resources -- from the app APK files, based on locale. But to me, this by itself doesn't explain the effect.
I have been developing an app that looks at installed apps, and on a 4-core armeabi-v7a system with some 150 apps, just getting a list of app labels alone takes around 10 seconds. It's painful.
I assumed it was using the ClassLoader to read resources from something like class files -- which can be very fast indeed -- hundreds of class files can be processed almost instantly on modern systems. Well, I don't think it uses the ClassLoader any more. But in principle...
A hundred or so little files should take much less than 10 seconds to process. That by itself couldn't account for the lag I see.
So I followed the calls down, through the creation of Resources objects, the opening of Assets, to finally retrieving that one label String. What I saw was layer upon layer upon layer of synchronized code. And all that is being called anew for each app label. Now, there is something that can make Java grind to a halt.
Of course it doesn't matter much if you're just fetching a single label. But it adds up, when you're fetching all of them.
I hoped to get to the bottom of it, and find something that I could call within one synchronized loop. But at the bottom of the android-29 source, within yet another synchronized block, I found a call to the SDK-specific nativeGetResourceValue(). That is, there is no way somehow re-roll that to be more efficient, and also run on other SDKs.
On the other hand... the OS can display lists of apps sorted by label very quickly. This means it maintains a table of app labels somewhere. Do we have access to that?
If there is some approach to obtain a list of app labels more quickly, I would love to hear it. (No, I don't need to hear about making my own cache -- which I might do anyway.)

How to store and read user usage data of my application in Android using java?

I have created a an application for a project - it's very basic... what I would like to do next is see how users are using my application e.g. buttons pressed, which page is viewed the most, for how long etc.
I am new to java and I do not understand how I can implement such thing; I have an idea but do not know whether it is efficient;
I would add a counter for each of the buttons in my app, whenever a button is pressed the counter increases by 1 and so on and so forth;
To see how long a user stays on a page, I could add a timer when the user enters the page, timer starts and stops when user exits.
...
Would something like this is viable and efficient? are there better ways of implementing such algorithm.
Not sure if there are, I searched but couldn't find any, does google offer such service like they do for websites with google analytic.
I am sorry, I've no to show this, as I haven't actually starting doing it. Wanted to get a grasp of it before I do and find out whether it is the correct strategy.
I would really appreciate your help.
https://developers.google.com/analytics/devguides/collection/android/v4/
Analytics for android apps maybe its what u are looking for
Start here: http://www.google.com/analytics/mobile/
https://developers.google.com/analytics/devguides/collection/android/v4/
You could also go with that you stated already, and add those values to an array. Just note that this will require you to turn on some permissions which might make your app unpalatable for some individuals.

How/Where to implement onItemClick handlers with several fragments

I am currently a student taking a Mobile Device Applications development class and am getting stuck on my final project, an Address Book style app. I have used the example from our book (Dietel's Android for Programmers An App-Driver Approach, Volume 1, Second Edition) as the basis and have been editing code from there. The biggest thing I want to change/enable is to allow the user to select different fields within the contact (address, email, etc) and pass an Intent that will open Maps when address is selected, eMail when email is selected and so on. Where I am lost is where to place my listener and declare it. Our book and subsequent searches are not really clearing this up at all. I understand the onItemClick call, but am not sure where to place it, within MainActivity.java or the DetailsFragment.java, which is all the code to handle anything that happens when the contact is open and displayed. I feel like I can put it all within the DetailsFragment.java but have a nagging suspicion that I am missing something. I have not had the time to edit and test this yet as I am actually heading out for work in a minute but I thought I could maybe get a better understanding or maybe even better links to read to learn from as my Google search doesnt seem to address what I am looking for. Also, not sure if it matters or not, but I am not using a ListView at all and everything I find tries to force a ListView use. Thank you guys for your help/consideration and time.

Since when is the phone charging/discharging

I wanted to learn more about the Android Services / Broadcasts, so I started a simple project, to create a battery monitoring app. It turned out pretty good, I'm using it for a few days now, but I want to add a new function: to show since when is the phone charging/discharging.
First I thought that I would create two static fields in my BoradcastReciever extension class, where I get and publish the data about the battery, one for the actual state (charging/discharging), and one for the time, when the change in state happened. This way, I could just subtract from the current time the last change, and know exactly since when is the phone charging/discharging.
But there is a problem with this solution: It won't show the correct data at first, when a user starts the app. I wouldn't make a big deal of it, but I saw that Android tracks this data somewhere, because inside my phone settings I found this information, so why take the hard way.
So my question is: is there an easy way to get from the Android system the date/time (no matter what format) of the last charging state change?
I looked at the BatteryManager reference but there are no constants named after what I seek, and which I could use, to get the information from the Intent of my receiver.
The Android OS tracks the connect/disconnect of a power source, but does not make this data accessible to apps. You have to record this all yourself, using intent filters.
The two intent filters to use are android.intent.action.ACTION_POWER_CONNECTED and android.intent.action.ACTION_POWER_DISCONNECTED; with these, you can monitor when the power source is connected and disconnected.
You can find information about this process explained incredibly clearly here. Another blog describing the process can be found here.

How to implement an Android detail notification?

This has probably been asked before, but I can't find a good way of implementing it. I'm trying to write a program that manages a form of messages, and these messages are received from an external data source. This all works. However, the problem comes when I try to notify the user: I would like to have the notification jump directly to the message when it is touched, but this seems to mess up the back stack. This is probably best explained by example:
I open up the message list, the main activity, and browse for a while.
I hit home and go into another app (let's say Music).
A new message is received. A notification comes up, which I touch. The message detail view is displayed.
Now I hit Back. What I want to have happen is that I return to Music, but unfortunately, Back sends me to the message list, and then hitting Back will return me to music.
The both the list and the detail activities are marked as "singleTop", and the exact flags that I use for the notification Intent are:
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_SINGLE_TOP
I figure if the Messaging application can do this, why can't I?
I have found one way to do this, but it's still not ideal:
Change the detail activity to have a different task affinity from everything else.
Add android:launchMode="singleTop" and android:excludeFromRecents="true" to the detail activity's manifest entry.
(Optional) Modify the list activity to open the detail activity with FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET. (This makes the task more like the built-in messaging app.)
The only fault to this scheme is that switching back over to the app will always go back to the list activity, but at least it is consistent. If someone else has a better way to do this, I'd love to hear it.

Categories

Resources