My question is as follows:
I started my intentService from my main Activity. This intentService does some audio processing with audioRecord.
However, when I need to start another activity in my application (recording video in this case), i need to stop the intentService in the background (because it is hogging the audio resource).
Is there a way to stop the intentService from the main activity?
You can use stopService() from your main activity like this:
stopService(new Intent(yourMainActivity.this,yourIntentService.class));
use the same pre-declared intent which you used to start the IntentService and call
stopService(intent);
if you create a new intent and use it to stop the service, the service will not respond to it until its finishes processing the previous intent.
but it should be noted that this will not immediately stop the service. So a workaround to this is to have a Global boolean variable. When its set to true the processing within the service will carry out, and when you want to end it set the boolean variable to false from your activity. and then you can stop the service from within itself by calling
stopSelf();
Related
I don't know if this is possible, but I would like to do the next:
Imagine an app with 2 activities: MenuActivity and OtherPurposeActivity.
So, on the onCreate method of Menu I had run the Service. In the same Activity (Menu), I can easily "connect"(Edit: communicate) with this Service with no problems.
Then, I click the only button there is on MenuActivity, which starts OtherPurposeActivity. Here comes the question:
How can I connect to the Service I had run on MenuActivity? Is it possible? (I hadn't called stopService).
Thanks in advance.
Edit: Code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
/* Execute service */
Log.d("SERVICE", "Launching service");
Intent msgIntent = new Intent(MenuActivity.this, ServerProcessingService.class);
msgIntent.setAction(ServerProcessingService.ACTION_STATUS);
startService(msgIntent);
/* Connection to the IntentService */
IntentFilter filter = new IntentFilter();
filter.addAction(ServerProcessingService.ACTION_STATUS);
//filter.addAction(ServerProcessingService.ACTION_CONTROL);
rcv = new ProgressReceiver();
registerReceiver(rcv, filter);
}
So I can handle the communication with the ProgressReceiver class. But, what if I open another activity, and this service still running? Can I access to it?
How can I connect to the Service I had run on MenuActivity?
Another activity that wants to communicate with the service can use exactly the same method as MenuActivity. startService() will only start the service if it is not already running, and then send the intent to onStartCommand() in all cases, so it is all right to call start service from multiple activities.
As a commenter pointed out, if your activity requires ongoing communication with a service, you should bind to it.
Is it possible? (I hadn't called stopService).
An IntentService will stop itself if it has no work to do, so it doesn't matter that you did not stop it explicitly. If the service needs to continue running, don't use an intent service.
To be on the same page I will describe briefly how I understood your dilemma.
You have an IntentService perfroming some operation which provides at the end some results. You are starting this process in one activity(asynchronously of course) and switch immediately to another one. Now, you are not sure whether service will finish the work before you switch to second Activity and result will be lost.
Basically, approach with BroadcastReceiver would be a good choice but if you won't register on time the data will be lost and service will end it's work. You could let the service to store the result before it ends, in DB, file or even in memory(depending on data type). When your second Activity start you can check if there is data waiting for you, if not you can wait for BroadcastReceiver to deliver it.
You could also use Otto library which is far more advanced solution than BroadcastReceiver. It allows to return to registered observer(Activity) the last result and what is more important it will allow your service to check if any observer received the message. If not you could only then store last result.
I have an android application which starts a service in the main activity with this command:
bindService(new Intent(ctx, MyService.class), _connection, Context.BIND_AUTO_CREATE);
The main activty does excatly nothing with this service (thats why I didnĀ“t provide the code for the Service connection). The idea is that the main activity handels the service lifetime!
It "stops" the service with this code after the user clicks the "close" button of my app:
if (_service != null) {
unbindService(_connection);
}
//Some cleanup here ...
System.exit(0);
I know at this point that no other activity is binded to the service cause every activity is called from the main activity and they unbind from the service at "onStop".
So the problem is that my Service wont call "onDestroy" when the user closes the app!
When I remove the "System.exit(0)" line it will close normally!
How can I make sure that the service is closed properly in this situation?
EDIT:
Ok I read this discussion: Is quitting an application frowned upon?.
Now I rebuild my activities. I have one activity that calls the service with startService, after that it binds the service. When the activity is destroyed it calls unbindService.
The service itself returns START_STICKY in onStartCommand to make it harder to kill it. It calls stopSelf when all work is done.
Now I have the problem that I get the ServiceConnectionLeaked message if the binding still exists! Whats about that? How could I prevent this?
Use finish() instead of System.exit(0)
I am able to stop my ServiceA(it is started using AlarmManager) when an IntentService is running by sending a broadcast from IntentService to broadcast receiver. I want to Start the same ServiceA again after my IntentService finished his work.
Ex-I have Service SrvA,IntentService IntSrvB and BroadcastReceiver MyBcr.When my IntSrvB running i am able to stop SrvA.My problem is How to Restart SrvA again when my IntSrvB finish his work.
Note-ServA is started using AlarmManager.
EDIT: Based on your code, you can pass your variables myIntent & myIntent2 into your IntentService class - you can then use them to recreate exact replicas of the pending intents used with the AlarmManager.
Please note that it looks like you set an Alarm for each intent that repeats once "NOW" and then at intervals after that. You then implicitly start the service again i.e. you start the service twice "NOW". That looks like a mistake - look at the docs for the AlarmManager.setRepeating() method.
Original answer below...
Put this into your IntentService:
#Override
protected void onHandleIntent(Intent intent)
{
try
{
// STOP SERVICE
// DO YOUR WORK HERE
}
finally
{
// START SERVICE
}
}
You already have the code to stop the service. You can take the "start service" code from your BroadcastReceiver and put it in the finally block.
I would not recommend overriding onDestroy() in general on Android.
NOTE: I don't think this is the best way to design your app, but I'm answering your question. Personally, I would have a method in my main Service that is able to disable & enable its functionality - and then call that method instead of starting & stopping the service.
I want to stop my Service after a user defined time (choosen in a activity).
Now I want to start the timer in the service, but I cant use static timer because I have to stop the service (stopService(), stopSelf() are non-static methods.
Is there a simple way to do it?
(Now I used a handler with a runnable which checks if a variable is set to true and then starts the timer)
Use AlarmManager. Call set() on an AlarmManager, supplying the time when you want your service to stop and a getService() PendingIntent that will send a command to your service. In onStartCommand(), when you receive the Intent command from the PendingIntent, call stopSelf().
Hi
i've got a kind of a dumb problem. Im trying to display a notification from a service. When an activity starts i call the startService like so:
Intent myIntent = new Intent(getApplicationContext(),notif_service.class);
startService(myIntent);
the service calculates something and should display the notification and then stop. the code is as follows:
if (limit_time_value == 2 && start >= 6300000 && notif_past)
{
notif_past=false;
showNotification();
stopSelf();
}
There are two ways that this service can be stopped, ether from itself with stopSelf() or from a button in my activity with
Intent myIntent = new Intent(getApplicationContext(),notif_service.class);
stopService(myIntent);
the problem is that even when i stop the service the notification is shown after the specified time passes. I tried to stop the setvice with Binding it and than calling onDestroy() in which I cancel the notification and again call stopSelf(). Again the notification is shown.
What am I doing wrong? Do I misunderstand how notifications or services work?
You do not indicate precisely where you are performing the work shown in your second code snippet above.
If that work is being done in onStart() or onStartCommand(), that work is being performed on the main application thread, and therefore once it starts it blocks all other main application thread work, such as stopService() and onDestroy().
If that work is being done on a background thread you create, unless you are terminating that background thread, that thread will continue to completion, regardless of whether the service is destroyed. You will need to arrange to terminate the thread yourself.
Call the instance of the NotificationManager class which you have called inside the showNotification() function.
For example, I have used:
NotificationManager nm=(NotificationManager)this.getSystemService(this.NOTIFICATION_SERVICE);
nm.notify(1,builder.build());
If you have done something like this to create your notification, use the same instance to cancel it by calling cancel() function and passing the notificationId (in this case 1).
For example:
nm.cancel(1);
Here 1 denotes the notificationID which you have provided while creating it.