how to callback into various activities from a android library - android

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.

Related

Android - Determine App Launches and Total Time as Top Activity

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.

Is there a way to create a controlling instance that controls several activities of my app?

I work on a project that has several developers.
We work on one rather large app.
Every developer has several activities that can be seen as sub-apps of the whole main-app.
I do realize, that this may not be the best design, but it exists and we have to handle it somehow.
Now the main issue is, that we need a master, that is always active and checks I/Os etc and that can give out status changes to every sub-app/activity. Something like "we just lost internet connection" etc.
Right now, that master is a singleton, that is first instantiated by the launcher activity and that every activity/sub-app can register to by passing the appropriate interfaces depending on what updates the activity would like to receive.
This is working, however it doesn’t feel right, because the singleton needs context to access system resources to determine system stati like internet or gps. Should the singleton be killed by OS, than a simple "getInstance" wouldn’t do much good, because the singleton would somehow need to acquire a context. I've read about extending the Application class and creating a static member context there, but this variable had to be volatile AND its possible that it returns null if the entire app is in some restart-after-crash/kill state. It doesn’t feel safe.
In addition, there should also be a possibility that the master somehow opens a user-dialog to display warnings etc to the user. Those warnings should look the same across the entire app and no dev should have to worry about when or why it suddenly pops up. Right now, those messages appear as custom toasts that overlay everything. Of course they require context and if the app is about to close there could be a problem.
All in all, that’s the mess we are in and I’m looking for a solution.
So how do I create a safe master object or activity (or even service ?!) that can pass info to different activities and post warnings etc (and Maybe even has the ability to close activities or at least order them to close themselves without the need to register a can_close interface).
It should be that safe, that if after a crash android only restarts the activity that was active it somehow manages to also be restarted or at least have/give the same info as before.
Every idea is welcome but total overhauls of the app are just not possible (lack of time and manpower)
Here are a few ideas:
Create a Service component for all the monitoring you need to do.
If I understand correctly, this service will be required only if
some of the activities are running. So you can make it a bound
service. Let all activities bind to this service when they start
and unbind when they close. The service will be started when the
first activity binds.
Create a base class for all your activities. You can write all the common code here. e.g. the code to bind to and exchange messages
with the master service. This class can also contain utility methods
for notifying user etc. So all activities will use the same method
for notification.
For user notifications, you could either use Status Bar Notification or create a Fragment which can capture, aggregate
and display the notifications. You can have a common menu item
implemented in the base Activity class to show/hide this Fragment.
If you use Status Bar Notification, make sure you use one aggregated
notification for your app. Otherwise, the different activities might
create a clutter in the status bar.
I guess that one solution would be to create a service that serve as the master.
You will have to make it run independently of the different activities (but don't forget to manage own to shut it down neatly if the app is no longer used, you don't want to kill your clients battery).
A service can't act on the interface though, so you will probably need to broadcast messages to the activities to order them to open a dialog.
A final thought : Toasts are ok but popup that block the interface are very bad, especially on a mobile device.

How can I pass an event from Application to Activity in Android?

I've got a little gap in my knowledge here and I want to make sure I do it right before writing all the wrong code.
I have an Android app that extends Application to set up some core functions for a TCP client. There are a few different Activity screens that should interact with Application. What I'm stuck on, is what to do when a data packet is received by Application. I want to relay it to the currently-visible Activity, whatever it is.
Coming from a C# background, I'd just create an Event in the Application, and simply subscribe to that event when an Activity is created. But I'm getting confused with Java Listeners, Handlers, ...
What's the best way to go about that? Should I be doing a Service instead? (But I don't really care if the TCP connection is killed when the app is not shown.)
I would go with a LocalBroadcastManager (documentation) approach.
Create one of those puppies in your Application class, and register/unregister your Activity objects in onStart and onStop. See Context.registerReceiver. Note that this requires using Intents, which might be too restrictive/heavy-weight for your application; packing/unpacking data can be a chore.
Alternatively, you don't have to use any specific android class to do it--just keep track of what Activity your program is in by calls to your Application in onStart and onStop. Might help clean your code if you make all of your activities-of-interest extend a subclass of Activity that contains this logic.

Android StartActivtyForResult() from a Service

First I'm sorry for my english that is not so good :).
I am facing a problem to develop my app.
That is a general architecture scheme of my solution.
http://i.stack.imgur.com/ooTmE.png
To be quick, the app has to decode code bare but with two possible ways:
using exernal device (The constructor provides a sdk containing an android Service to communicate with the device),
use the camera of the mobile using the library Zxing which is possible to manage it with intent.
The goal of my own service is to manage some business code and make transparent the choice of the tool for the user.
I believed that was a good solution but I wanted to implement it and I had different problems.
My main trouble is that I cannot execute StartActivityForResult inside the service.
Do somebody have any suggestions for my problem whether a change in the architecture or a solution for the main problem?
#Laurent' : You have totaly right my service acts as an API adapter.
I will try to make the expected behaviour more clear.
I have an app that needs to recognize (real) objects which have QR codes on their top. This recognition action will be done several times by the user during the life of the app.
The user chooses to launch the recognition by clicking on a button (or otherwise but he knows that the recogntion will start). So no notification is needed.
The thing is he doesn't choose the way to do the recogniton. It is why, as you said, I implement an adapter.
The adapter chooses between :
Camera mobile or external device. The first is an activity coming from the Zxing library. The second one is a service that manages the external device. This service provides an interface to get back result.
One more thing, I need that my whole implementation (adapter and co) can be re-used by other apps that will also need to do recognition.
So my thought was to implement a service as an adapter to answer my two conditions (make transparent the choice for the user - and make the recognition available for other apps).
I hope you understand my problematic.
Given your architecture, your MyOwnService must act as an API adapter : it should provide a unified scanning API and address each external service specificities transparently.
Your expected behaviour is not clear enough to provide a solution that suits your needs but here are a few remarks that can be of some help.
Passive scanning:
Even if there are some workarounds : no activity should be launched from a service (not directly). Never. Bad. Services are background stuff, the most they will be permitted is to hint users with Notifications (this is point 2 of Justin excellent answer).
As a consequence there's nothing as a 'popup Activities' (and that's good!). If you need to continuously scan for barcodes, even when your activity is not run, then the only way to warn users is by using status bar notification.
Active scanning:
Inside your own activity you can bind to your wrapper service and make it start scanning for codebars. When it finds one it has to message your activity. Your Activity message handler has complete access to the UI to inform the user of your findings.
You selected Active Scanning in your edit, your problem is therefore to find a way for your service to actively notify your main application (the one that started the active scanning) that a new item has been scanned successfully.
You do NOT do this by starting a new activity (remember: this is bad) but you can bind to a service and/or use Messages between the wrapper service and the application.
I advice you take the time to read (and more time to comprehend) this android developer article on BoundServices and especially the part about Messengers.
A full example of Two Way Messaging between a Service and an Activity can be found in the following android examples : Service & Activity
Warning: designing robust, full blown AIDL-based services is a tough job.
Two ways you could solve this problem.
1) Have MyOwnService do a callback into MainActivity telling it to launch your ScanActivity.
- This is a better approach if MyOwnService's task is only going to be running while MainActivity is running and if the user would expect the ScanActivity to come up automatically.
2) Have MyOwnService create a notification that will let the user access the ScanActivity.
- This is a better approach if MyOwnService's task might be running longer than the life span of MainActivity. That way, you can let the user know, unobstrusively, that they might want to access the ScanActivity.
So finally I changed my architecture.
I make the choice to delete myOwnService and to create an intermediate activity that will be my API Adaptater.
This activity will have a dialog.theme to look like a dialog box indicating that a recognition is under execution.
If the recognition uses the external device this activity will stay at the foreground otherwise the camera activity will start (Being managed by the intermediate activity).
Thank to that I can manage my result from the intermediate activity and do not have an android strange architecture, keeping my business code for the recognition outside my main app.
Service was not the good choice.
Thanks a lot for you help and your time.

Alternative for UIAppDelegate in Android, a common code which will be called before any activity

We are building a security mechanism in our Android App, for which we need to ensure that we ask user for password every time they enter the app (even when it is running in background). For this I had to write the checks in all onRestart of every activity.
Looking for something similar to iPhone's AppDelegate where the code will be called before the activity and I can handle it in central place.
Let me know if more info is required.
The way i've done it in an app with similar functionality was the following:
Create a BaseActivity class
Overwrite the OnStart() here and implement your security
Extend all activities that need this with the BaseClass
This way you'll have a central place to do your security mechanisms.

Categories

Resources