Is there a way to get the Intent, or any other information about how the app was launched (BroadcastReceiver,Service,Activity), within the Application, without adding code to all the class that can lunch the app (keep in mind that there are library class that I can't override.
I couldn't find anything within the Context interface, that could retrieve any data about that.
I thought about using a class loader, and query somehow what classes have been loaded to memory.
Is there a way to get the Intent, or any other information about how the app was lunched (BroadcastReceiver,Service,Activity), within the Application, without adding code to all the class that can lunch the app (keep in mind that there are library class that I cant override.
On API Level 14+, your Application can call registerActivityLifecycleCallbacks(), after which it will be called for all lifecycle methods on activities within your app. Using that, you can call getIntent() on the Activity that is supplied to your callback.
However:
That is only for API Level 14+
That is only for activities, not other components
Since onNewIntent() is not included in the callbacks, you can only readily get the original Intent that started the activity, not any Intent that caused an existing instance to come back to the foreground, if that matters
Related
I am writing a simple Android library. I have a couple of methods that I would like executed when certain activity events happen - like after activity got loaded or when the activity gets paused.
One way I could think of was to create a class that extends activity, and write my methods there, and then have "target" activities extend that class. This was all methods get called
But if the end user is extending some other activity already, this method won't work. Is there a better alternative?
If you need only provide support back to API 14 or higher, you might be able to make use of the application level activity lifecycle callbacks - see the Application.ActivityLifecycleCallbacks interface for details.
To make use of this you need to register an instance of this interface with an Application instance, using the registerActivityLifecycleCallbacks method. One way to get that would be to have the developer using your library initialise your library by passing their Application instance to it. This is what I do in an SDK that I maintain, and it seems to work nicely.
I am working on a solution or code that can be embedded inside of an Android APK to track how many times the app has been launched and how long the app has ran for. I know one way to do this is using the ActivityLifecycleMethods in API 14 and in lower versions of Android having code placed in all Activity Lifecycle events or by providing a base Activity class.
1) Is there a way to hook the ActivityLifecycleMethods without the developer having to make any changes to their code outside of dropping additional code into their App?
I believe this answer is no because even with an Enum Singleton it is not loaded until it is referenced. Also the Enum Singleton will go away once the activity is changed since a different class loader is used when activities change.
If I wanted to keep the Enum Singleton around would it be possible to store a reference to the applicationContext and thus it wouldn't be removed when the Activity changes? Is that what google means by
"There is normally no need to subclass Application. In most situation, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), the function to retrieve it can be given a Context which internally uses Context.getApplicationContext() when first constructing the singleton." on http://developer.android.com/reference/android/app/Application.html
2) I am not a fan of this solution for older API versions. It seems very likely developers could forget to modify their Activity Lifecycle methods or forget to inherit from the created BaseActivity. Are there any other unique solutions for these older platforms? Is there any other approaches that can be done to determine when an activity isn't running? Could any of the following work:
a) User a class loader to ensure the base activity with the proper metrics are always used
b) Implement some type of heart beat. Will a timer stop working if the app is paused or killed? Is there some other way? Could the ActivityManager be used?
You have many Analytic Agents like Flurry to do that.
When ever you want to track an event, you will add it to flurry and inturn it syncs with server after specific time.
You may use the same logic.
Better create a library file with following features:
Start Application
End Application and report time to db.
Track a specific event count and update to db.
Sync the data to server you like to.
Call appropriate events from your app.
There are many examples of taking a screenshot using a reference to the current activity. However, in my case, I need to take a screenshot of an activity which comes from an external SDK (but still within my app). For obvious reasons I don't have a reference to that activity object within my code. I saw solutions using Instrumentation and UiDevice, but they seem to work only when implementing a testing application using the TestCase framework, while I need it to work in a normal application.
Is there another way?
Well, if anyone finds this question useful, here's the answer I found:
In your activity or service, call getApplication().registerActivityLifecycleCallbacks(), passing it an object that implements the Application.ActivityLifecycleCallbacks interface. That object will get a callback on every activity's onCreate/onStart etc. with a reference to the Activity object, from which you can get the view and take a screenshot. You can identify that it's an activity from an external SDK by its package name.
NOTE: Application.ActivityLifecycleCallbacks is only available since API level 14 (a.k.a. ICS).
I’ve written a library for Android, upon initialising the library I register for call backs for location updates, subscription status changes, library status changes and various other updates...
Originally, I wanted all these updates to call back to a controller in my android UI app, and then for the controller to launch activity A, pass on the messages from the controller to activity A and so on. Or launch activity B for signing up for a subscription and forward messages to this etc
However, it appears that there isn’t a way to achieve this - Because each activity is in isolation? Unless I’m mistaken?
So what are my options here? It sounds like I either have to use one activity for the whole app and swap the UI’s which after looking into it doesn’t appear to be the way to go?
I did try to subclass Application, which worked and gave me access to my library from an activity – but I want it the other way around. Is this possible? would wrapping the library in a service achieve what I want to do?
You could use broadcasts and send them from your library. Each of your activities would have to register a BroadcastReceiver in their onResume() method and unregister it in their onPause() method. This would be comparatively easy when you use a common base class for your activities. You could then send commands from your library to whatever activity is currently active.
I want know i pass a variable via Intent to another activity and that activity changes that variable, will it reflect in original activity without passing back the intent.
If answer is no then is it better to use global variable using application then passing intent and getting back data. in my program, i am having round 5+ activities and all of them need to access a list of class objects.
any recommendations apart from above
Create your own extension of Application to store the state of your app and share data between the different activities that make up your app. The Application acts as the context for your whole app and Android guarantees there will always only be one instance across your app. Hence it works similar to defining your own Singleton, but using Application will allow Android to take control of the life cycle of your shared data and basically do the memory management for you.
To summarize:
Create your own subclass of Application.
Specify that class in the application tag in your manifest.
After this you will be able to safely cast the result of all call to getApplication() (from an Activity instance) and getApplicationContext() (from any Context instance) to the subclass you defined in step #1. This means you can use any getter/setter method defined in your application extension to store/retrieve data.
Have a read here for more details.