I have background activity in which I'm listening to Gps Location. Above it I have map activity.
How can I notify the map activity when an event occurred in the background after the activity already started?
I guess that this kind of question already been answered, but I tried googeling with many key words with no success, so sorry if it is duplicate. I'll appreciate references to other answer as well.
Thanks.
You probably shouldn't use an activity to perform a background task, it is extremely inefficient. I would recommend using a Service and communicate with Intents and a BroadcastReceiver. Services are designed to perform these kinds of operations.
You could also use an AsyncTask and communicate with the main thread with a Handler.
(All links are to the Android documentation for your reference)
You can use a broadcast to pass your data in an Intent (which is the main unit of communication between components in the Android platform). Check out the docs for BroadcastReceiver, it does a good job of spelling it out.
Also, worth noting, if your sender and activity are in the same process, you can use a LocalBroadcastManager to avoid IPC overhead.
Related
I have a background service doing some work - retrieving user location by interval (launched with startService). As soon special condition reached I'd like to do the following:
If application is in foreground then start specific activity.
If application is not in foreground or closed then show the notification that will start required activity on tap.
I know how to show notification and how handle intent from server with broadcast receiver for example. But how can I determint if my application is in foreground? Or may be you can suggest complete better solution?
I determint if my application is in foreground
There's couple of ways to find out what is in front, but I actually prefer to track this myself (as this helps me apply additional logic if needed). Plus it's pretty simple task. To make this happen you need static int based counter somewhere (you can use your Application object if you have one, or have it elsewhere, does not really matter). In each Activity's onResume() you increment the counter by one, and in onPause() you decrement it by one. If counter equals 0 then none of your activities is in foreground so from your perspective you are in background and you post notification. For simplicity I always do that in my ActivityBase class all my activities extend.
If you do not want to track it yourself, you can use ActivityManager to see what's currently in foreground:
public boolean isAppInForeground() {
ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> services = am.getRunningTasks(Integer.MAX_VALUE);
return (services.get(0).topActivity.getPackageName().toString()
.equalsIgnoreCase(getPackageName().toString()));
}
but this requires <uses-permission android:name="android.permission.GET_TASKS" /> entry in your Manifest, so not always welcome.
An alternative to Marcin's answers is to bind and unbind your Activities to the Service. This will allow communication between the Service and Activity whilst that binding exists, and the Service will know if an Activity that is capable of handling the scenario is currently available - e.g. you may not want to launch the Activity directly if the user is in the middle of some important process (like accepting the T&Cs / EULA or something), so the Service can tell the Activity that an event has happened, but the Activity can respond to the event correctly.
I am new to Android and I have a kind of design question. So I understand that it is recommended to use Fragments. I also understand that an Activity "owns" a Fragment.
So my question is the following:
Assume we want to make a long running background call e.g. HTTP to a server.
The results should be displayed in the UI.
So what is the best/standard practice?
1) Should the object doing the long running calls be "owned" by the Activity and the results send back to the Activity and then from the Activity to the Fragment so that the UI is updated?
2) Or should the object doing the long running called be "owned" by the Fragment and the results are send back to the Fragment for the UI to be updated? So the Activity is completely unaware of this?
Neither, IMHO. The object doing the long running should be managed by a Service, where you are using WakeLock (and, if needed, WifiLock) while the long-running HTTP operation is running. An IntentService might be a good candidate, as you need a background thread anyway.
The service, in turn, can use some sort of in-process event bus (LocalBroadcastManager, greenrobot's EventBus, Square's Otto, etc.), to let the UI layer know about any significant events that occurred from that HTTP operation. Whether the activity or the fragment is the one to subscribe to the events on the bus depends on what needs to happen for the event. If a fragment's widgets need to be updated, the fragment would subscribe. If the mix of fragments change, or some other activity-level UI change is needed, the activity would subscribe.
All of this assumes that by "long running" you mean something taking over a second or so.
For the long running task it's recommended to implement a sticky Service that contains a thread for the ServerSocket listener. Next I'd recommend to process requests by dedicated Thread's which are managed by a thread pool (check for instance this example).
In order to display results in your activity there are several approaches possible:
send a local broadcast from your service or thread which gets processed by registered BroadcastReceiver's which are part of your UI component (either Fragment's or Activity's)
bind your Service to the Activity (which might contain further fragments) and propagate information to containing fragments. There are three ways to go.
Note: In this post it's being said it's better to bind to the Application
pass data via Intent or a SQLiteDatabase
What I like and prefer is using local BroadcastReceiver's but this is just my personal preference.
It depends on your requirements, what might be the best solution.
I'm using a variation of the design recommended by #CommonsWare. I have an ApiClient class that listens to the event bus for requests to invoke API methods asynchronously. Any parameters that are needed for the API call go into the bus request message.
The ApiClient uses Retrofit to make the async API call, and posts a 'result message' containing the result to the event bus on success, and an 'error message' if there's an error. Each API call has it's own triplet of bus messages - xxxRequest, xxxResponse, xxxError.
So, when an Activity or a Fragment (or other, non-ui class) wants to invoke the api, it registers to the bus for the xxxResponse and xxxError messages, and then posts an xxxRequest message to the bus.
The only potential down-sides are:
The ApiClient is a singleton, and is owned by the Application class, just so that it doesn't get garbage collected.
You wind up with a large number of Message classes - I deal with this by putting them into their own package.
I have the following design:
Activity/FragmentA upon a user action starts an AsyncTask to fetch a set of data.
While the AsyncTask is running, a progress indicator is displayed to the user.
When the AsyncTask finishes its task and fetches the resultset, it saves it in a singleton class serving as a shared datamodel.
When FragmentA is notified that the AsyncTask has finished (LocalBroadcastReceiver) then it start ActivityB/FragmentB which takes the set of results from the shared singleton and displays them in a ListView.
This works but since I am a newbie in android I am trying to understand and learn best practices.
E.g. I see a small delay from the time the progress bar is dismissed to the time the UI of ActivityB/FragmentB is displayed (during this latency the UI of ActivityA/FragmentA is still visible).
Also I think that somehow if the fetch of the items was done from FragmentB instead of FragmentA would make FragmentB "autonomous"
Overall can someone please help me understand how could I have implemented this differently using better/standard practices in android and the pros/cons of each approach?
Fragments
Fragments are small part of the activity which has their own life cycle, which provides developer more flexibility to deal with UI. Fragments has nothing to do with background processes.
Now your main question is about the background processes.
AsyncTask
This is nothing but the bit better version of thread with some predefined callbacks, when u need to perform some network operation which will take not more than 20 seconds, and after that it refreshes the UI, its better to use asycntask. Do not use Services (Avoid complexity, Keep it simple). You can use some third party library also.
IntentService
Now IntentService are better version of service, the main purpose of IntentService is to avoid performing long running operations on mainthread and provide queueing system to the developer. You should use services if you do not need user interaction while running long running operations (e.g syncing app with the server at the end of every day).
So for conclusion
User Interaction + short running network operation = AsyncTask
No User Interaction + long running network operation = IntentService + Broadcast Receiver to notify UI of needed
Is there some sort of onTerminate() method where I can do some cleanup (I want to clear some SharedPreferences) when my Android app is terminating?
I have an Activity that is keeping a running average of a few numbers, that I'm storing in a SharedPreference. I want this average to last while the app is running (the user can move between different activities) so I can't clear it on onDestroy() for that particular activity. I need to be able to clear it once the app is about to quit.
How can I do this?
I've not tried this, but here's what I would do:
As Alex mentioned in the comment to original question, use a Service to share the app-wide state between Activities.
Whenever you move between Activities, bind to the service from the "new" activity, and unbind from the "old" one. Check this to understand how to coordinate activities.
If you follow this properly, you can ensure that at least one Activity is always bound to the Service as long as your app is running; and that all Activities are unbound when the app is no longer running - at which point your service's onDestroy() is called. This is where you perform your cleanup.
So android doesn't really have a concept of an app being "finished". Unfortunently there is nothing synonymous to "onTerminate()". Is there some criteria by which you can decide when to clear your running average?
Use SharedPreference.Editor to remove the preferences, and commit. Here's a link for you: http://developer.android.com/reference/android/content/SharedPreferences.Editor.html
I'm developing an android app (if you want more info http://www.txty.mobi) and I am having some problems with dialogs management. I'm quite new to Android so the way I'm doing things completely wrong. If the case please just say so pointing me to the right documentation to follow.
Background:
The main blocks of the app so far are one activity and one Service (which derives from IntentService).
The actvity needs to interact with the service in just two occasions: start/stop the service. The intent service will self regulate its lifetime using the AlarmManager.
A typical flow when clicking on start/stop:
1) the activity on its onResume registers a broadcast receiver to events sent by the service (unregisters it in the onPause)
2) the activity starts a indeterminate progress dialog
3) the activty sends a single shot alarm event (either start or stop) which will be send **straight away to the service
4) the service does what it needs to do to start
5) the service emits a broadcast event basically saying "done"
6) the activity receive this event and gets rid of the dialog.
The Problem:
The activity can lose its foreground status let's say if the user switches focus or a call is received, so the onPause method is called (at this point the activity could even be killed by the system to claim memory). obviously if this is the case the activity will never receive its broadcast event because the receiver has been unregistered. This will leave the app in the awkward situation, when the activity is brought again to the front, of having a dialog that you can't kill nor will never get rid of.
The (possible??) solution:
The way I am handling this now (apart for keeping the broadcast receiver in place) is by creating a utility class that uses preferences to keep track of which operations are being executed and their status:
Activity
- in the onResume using my utility class gets the list of operations the activity is waiting for
- check their status
- if they are completed perform some actions accordingly (in my case get rid of dialog!)
- delete the operation from the preferences.
- just before asking for a operation to the service it saves it to the preference using my utility class.
Service
perform operation and save state of the operation to the preference using my utility class.
emit broadcast.
Disasters happen!
Now this saves me in a normal situation, but if a disaster happens (i.e. with the task killer app you kill everything) the service might be killed before it can save the status of the operation I am stuck as before (the activity will think the operation is still going on so it won't touch the dialog). So as for now I add a Dismiss button to very dialog just in case :)
Now all of this looks too complicated for what I think should be a fairly common thing to do. That's why, as said at the beginning of the post, I might (very likely!) be completely wrong.
Any ideas? Apologies if this question has been asked already, I looked around but didn't find anything. Please point me to any resource online explaining this.
Thanks and sorry for the lenghty post :P
Luca
Have you tried using a StickyBroadcast? This caches the latest broadcast, so it can be received onResume. Please see this post.