When should I start and stop my notification service? - android

I don't want the notification service to be working while the user is in the application. As of right now I have it starting in the onCreate and onResume methods and stopping in the onPause method. Is that correct?
Also, is it sufficient to specify the intent and execute stopService(intent) to stop it? There isn't a direct relationship between the start and stop methods except they reference the same class.
Thank you for any help.

Here is the activity lifecycle.
As you will see, onCreate() and onResume() are called before the activity is created so you do not want to start your notification service there. You should stop it instead. It is a good idea to do it once in onResume() because it is the entry point of your activity.
onPause() is where user navigates away from the activity so it is where you will want to start the service again.

Related

how to auto start service after load all views in MainActivity?

I have a problem like the above question. I want to know when all views will load on MainActivity and after loading I will start running Service. Is there any way? Thank you.
You can start the service in onResume() of your MainActivity. Based on the documentation:
This is where the lifecycle components can enable any functionality
that needs to run while the component is visible and in the
foreground, such as starting a camera preview.
If lifecycle of your service is tied to that of Activity, then remember to call stopService() in onPause(). Otherwise, you have to do some condition checking beforestating the Service to avoid calling startService multiple times.

How to handle service stopped in background

My ex colleague developed a service which plays music in background. However if user wants to exit from program then application calls below code to stop service. Service stops but i cannot handle it while overriding onDestroy method
Activity realAct = context.getParent();
if (realAct == null) {
realAct = context;
}
ContextWrapper cw = new ContextWrapper(realAct);
cw.stopService(new Intent(cw, MyPlayerService.class));
edit:
Briefly, Activity Main starts Activity Sub then Activity Sub starts Service. Then i press back button so Activity Sub finishes. When i am in Activity Main I call above stopservice code. So onDestroy method of Service is not called
Try again to use method like that in code of your service :
#Override
public void onDestroy()
{
super.onDestroy();
//your code
}
It has to work !
Are you trying to stop the service when the user exits from application?
onDestroy is called when system needs to kill activities due to insufficient resources. Just because you pressed back on your app doesn't mean onDestroy gets called immediately.
But if you want to force close your app to have it automatically invoke onDestroy, call
finish()
on wherever you are exiting your application from.
If you want to invoke onDestroy upon user pressing back button to exit, Override onBackPressed() and invoke finish() from there.
But really, this is an antipattern so I'd recommend using onPause() instead.
Edit Upon OP Edit:
I think we need to have more details on how you are instantiating the service but here are some additional thoughts:
Have you overridden onDestroy properly and calling the super method?
If this is the case, the only other possibility I can think of is that you still have ServiceConnection objects bound to the service with BIND_AUTO_CREATE set. Until all of these bindings are removed, service will not get destroyed.
So make sure to do both:
unbindService(conn);
stopService(intent);

how to stop or finish activity from called service?

In my app I am required to Stop the activity(MyAct.java) when a service(BackgroundService.java) is called, and further i wish to continue this service(BackgroundService.java).please help?
Implement a started service, call startService(Intent service) in your activity(for instance, a button pressed) then call finish() immediately in your activity.
Check out here to see how to create a long running background service, even without need a activity to start the service.

android: AlarmManager and activity life cycle

I decided to write simple alarm clock (using AlarmManager). When alarm works out I want to show simple dialog with 2 buttons: OK and Snooze. So I have a question: what should I connect with my Pending Intent? I mean Service, Activity or BroadcastReceiver?
At present version I use BroadcastReceiver where I start Activity that shows the dialog. I start it with flag FLAG_ACTIVITY_NEW_TASK. In onStrat() method I start music service. When OK button's pressed I call finish() for activity and stop music. In OnPause() I call finish() also. I do it because if two alarms run simultaneously then according to activity life cycle method onPause() will be called. It works... but sometime the music starts for a few seconds then finishes....then start again and finishes and so on. Why? Thanks.
So I have a question: what should I connect with my Pending Intent? I mean Service, Activity or BroadcastReceiver?
Probably an activity in this case. Theme your activity to look the way you want (e.g., Theme.Dialog) rather than fussing around with a regular dialog box.
It works... but sometime the music starts for a few seconds then finishes....then start again and finishes and so on. Why?
It is impossible to answer this question with the information you have supplied, sorry.

Stopping and starting a Service based on application state

I have a Service which tracks the location of the user. Currently, the Service boots when the application starts and stops when the application terminates. Unfortunately, if users keep the application in the background, the Service never stops and drains battery.
I would like the Service to stop when my application is not in the foreground. I was hoping the Application class would let me Override onPause and onResume handlers, but it does not have them. Is there another way I can accomplish this?
I haven't tested this yet, but it looks like if you use Context#bindService() (instead of Context#startService()), the service should stop when no more activities are bound to it. (see Service lifecycle).
Then use onPause()/onResume() in each activity to bind/unbind from the service.
Alternatively, you could add a pair of methods on your service which tell it to start/stop listening for location updates and call it from each activity's onResume()/onPause(). The service would still be running, but the location updates wouldn't be draining the battery.
Reading all the above answers I would suggest Simply add a boolean global flag for each activity & put it in your onResume & onPause & also while launching an Activity Something like this
public void onPause()
{
super.onPause();
activity1IsResumed = true;
}
&same for onResume
& similarly when launching a new Activity
startActivityForResult(myintent ,0);
activity2IsResumed = true;
activity1IsResumed = false;
then in your Service simply check
if(activity1IsResumed || activity2IsResumed || activity3IsResumed)
{
//your logic
}
else
{
//another logic
//or dont run location tracker
}
& you are done!
You should override the onPause and onResume methods on your Activity. If you have multiple activities you may want to have a common base class for them and put the start/stop logic into the base class.
I have not tried this approach but I think you can override the home key of android device by using KeyEvent.KEYCODE_HOME and you can use stopService(Intent) to stop your service and when again application resumes, you can write startService(Intent) in the onResume() method of your Activity.
This way I think your service will only stop when user explicitly presses home button to take application in the background and not when he switches from one activity to another.
What I would suggest is overriding the onPause/onReume methods as others have said. Without knowing more about the flow of your application and interactions between Activities, I can't give much more information beyond guesswork.
If your Activities are persistent, however, my recommendation would be to utilize the Intents better when switching between Activities.
For instance, each Activity should have a boolean "transition" flag. So, when you move from one Activity to the next, you set up an Intent extra:
intent.putExtra("transition",true);
Followed in the receiving Activity by: (in onCreate)
intent.getBooleanExtra("transition",false);
This way, for each Activity that launches, you can know whether it has come from another Activity, or if it has been launched from a home screen launcher. Thus, if it gets a true transition, then onPause should NOT stop the service--that means you will be returning to the previous Activity after it returns. If it receives no "transition" extra, or a false transition, then you can safely assume there is no Activity underneath it waiting to take over for the current one.
On the first Activity, you will simply need to stop the service if you are switching to another Activity, which you should be able to figure out programmatically if one Activity is started from another.
It sounds like the real problem is how to only stop the service when you go to an activity that isn't one of your own? One way would be to in your onPause method to stop the activity. Do this for all your activities. Then override your startActivity method. And in here do a conditional test to confirm that you are purposefully navigating to one of your own. If your are set a flag to true.
Now go back to your on pause overridden method. And only stop your service if the flag is not equal to true. Set the flag to false.
All events that navigate away will close your service. Navigating to your own will leave it intact.
Do the overriding in a base class that all your activities extend.
Writeen in my andolroid. Will post ezaple later.
Try using the Bound Services technique to accomplish this.
Bound Services | Android Developers
You can use bound services in a way such that the service will stop when no activities are bound to it. This way, when the app is not in the foreground, the service will not be running. When the user brings the app back to the foreground, the Activity will bind to the service and the service will resume.
Create methods registerActivity() and unRegisterActivity() in your Application object and implement first method in all you acts onResume() and second in acts onPause().
First method add activity to List<Activity> instance in your app object, unRegisterActivity() checks size of list in every call if==0 stopService();.

Categories

Resources