I start an Intent Service this way:
Intent MyIntentService = new Intent(this, clsMyIntentService.class);
MyIntentService.putExtra("Command", Command1);
startService(MyIntentService );
....
Sleep and do some work
....
Intent MyIntentService = new Intent(this, clsMyIntentService.class);
MyIntentService.putExtra("Command", Command2);
startService(MyIntentService );
My problem is that the IntentService does not receive anything until everything is done.
And when it starts receiving the order is wrong because Command2 is received before than Command1 (right before).
Any help with this?
Implement your service as an IntentService Type, it has it's own worker thread to avoid blocking the UI and it queues the requests to start it so your commands will be executed in the correct order.
check these links for more info:
http://developer.android.com/reference/android/app/IntentService.html https://developer.android.com/training/run-background-service/create-service.html
Related
Found an interesting observation with foreground service, if we stop the service immediately right just after start foreground service we get this error as Context.startForegroundService() did not then call Service.startForeground(). Doesn't matter whether we start notification from onCreate or onStartCommand of service.
Intent intent = new Intent(this, MyService.class)
startForegroundService(intent);
stopService(intent);
But if I add a delay then it's working as expected, any thought on this ?
Intent intent = new Intent(this, MyService.class)
startForegroundService(intent);
new Handler(Looper.getMainLooper()).postDelayed(() -> stopService(intent), 0);
In order to get rid of this error this is how I fixed
I didn't found any proper documentation on developer website but this is what
I did in order to solve Context.startForegroundService() did not
then call Service.startForeground() issue.
If we want to stop foreground service do not call outside the service
class using stopService(intent) instead create an intent action,
start the foreground service then stop the service using stopSelf from
service onStartCommand.
Intent serviceIntent = new Intent(context, MyService.class);
serviceIntent.setAction(ACTION_STOP_SERVICE);
ContextCompat.startForegroundService(context, serviceIntent);
Starting a service is not synchronous and the service is not up and running when the start call returns. Think of it as posting a message to your main thread looper queue that get processed later.
Now your Handler approach is also doing the same kind of thing to postpone the execution - post a runnable to the main thread looper queue. It gets processed after the previous messages in the queue have been processed, so there's some Service startup lifecycle code that has been executed before the stopService() is invoked.
I'm using service to run Bluetooth in background,but i don't no how to send data from another activity to service
Service and other activities work in the same process
To start a Service, use following statement:
Intent intent = new Intent(context, Service.class);
// intent put some extra
startService(intent);
Calling this statement firstly, Service call onCreate() method and onStartCommand().
Not firstly, Service just call onStartCommand().
You can check if it is called firstly by extra in intent.
So you can send data with the same method startService(Intent intent).
Service works in another process
use [bindService](https://developer.android.com/reference/android/content/Context.html#bindService(android.content.Intent, android.content.ServiceConnection, int)) and AIDL
It is suggested that make service and other activities work in the same process when your target is not complex.
I am bit new to android. I would like to know how to communicate with a foreground started service.
So, I got a Foreground service with a notification.
This notification has a (X) button to stop the service.
The service got a Static broadcastreceiver.
public static class NotificationStopButtonHandler extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"Close Clicked",Toast.LENGTH_SHORT).show();
Log.i(LOG_TAG, "In Closed");
// imposible to do context.stopForground(true) or
// to call any other private coded by me
}
}
So my question is :
Is BroadcastReceiver is the best way ?
If it is : How I can communicate with the service to call stopForeground in the broadcastReceiver ?
Thanks in advance for your responses.
Same question like mien... But I would like to know which are the other solution than broadcastReceiver. thx
In your notification you will have a PendingIntent for the X button. I presume you have built that PendingIntent with
PendingIntent.getBroadcast(/* ... */);
What you can do instead is to create a PendingIntent for your service
Intent intent = /* intent for starting your service */;
intent.putExtra("STOP_FOREGROUND", true);
PendingIntent.getService(context, requestCode, intent, flags);
and in the intent you pass to the PendingIntent you would add an extra (STOP_FOREGROUND). When this intent is fired, your service will get called in onStartCommand(). Here you check the intent and if it contains your extra, you know you're expected to call stopForeground.
Instead of broadcasts, you can use PendingIntent with an Intent to the Service and tell the Service to shut down. You assign the PendingIntent to the close button action and/or to the notifications onDelete call when you build the notification.
Assuming that you're starting the Service with the notification, you can put commands in the Intent to tell the service to stop itself. Service#onStartCommand will be called on the service with the new Intent. The service checks for the shutdown call and calls stopSelf() when done.
Basically, the reason this works is because there can only be one Service started. Every subsequent attempt to start the service will send the intent to Service#onStartCommand, but it will not restart the Service. Thus, this is a way you can send commands to the service through means outside of binding. Plus it's way cleaner than using broadcasts.
I 'm writing a backgroud app only can use service.
I'use BroadcastReceiver start service. Sometimes it works well, but some sometimes it doesn't work.
I know the reason is BroadcastReceiver exec liftcycle is 10 seconds, so use it start a long time task will not be end.
Intent i = new Intent();
i.setClass(context, RegisterService.class);
context.startService(i);
What should I do if I want to execute a long time task only use BroadcastReceiver and service?
Make sure your service is not executing on the main thread. Consider using an IntentService, it does the right thing out of the box.
If I create a Service like this:
Intent intent = new Intent(context, MyService.class);
context.startService(intent);
Can you please tell me how can my code else where get the instance of that service class that I start?
And if i start Service, does that class runs in its own thread?
Thank you.
You have to bind to the service.
And the service is started asynchronously, but any code that's run in the service is run on the main thread. In fact, everything in android is run on the main thread unless you specifically create another thread.