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.
Related
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 have made the Intent service and designed it in such a way that it has capability of restart itself if killed by the OS , but if it is stopped by user it must have stop.
Every thing was going good. But Problem occured when I tried to implement message handler and Binding techniques.
What I have done
My sole purpose was getting the status from the service (which in my case is intent service) and update my views. For this I have implemented Message handler and start to bound the service .
I am binding my service in such a way
//This is my interface to get specific call back in activity
mReceiver = new DownloadResultReceiver(new Handler());
mReceiver.setReceiver(ListSuitClass.this);
serviceIntent = new Intent(DownloadService.ALARM_SERVICE);
serviceIntent.setClass(ListClass.this, DownloadService.class);
serviceIntent.putExtra("receiver", mReceiver);
serviceIntent.putExtra("requestId", 101);
startService(serviceIntent);
}
if (!mIsBound) {
bindService(serviceIntent, mConnection, BIND_DEBUG_UNBIND);
mIsBound = true;
}
Problem
I want to stop the service by stop button , But it stop for a while and starts over again .
I do not know what I am doing wrong , And what is starting again the service.
Please help me in stopping the service.
Note: I am running my service in a separate process.
As per the code, mIsBound might be the local variable of Activity. When you stop your activity and restart it, it will have the default value of boolean i.e. false and so bindService is called again and again. What you need to do is either make it static variable or store the service bind status in SharedPreferences and read value from it.
My Android application is activating a service that call an 'Activity.
On mainActivity:
startService(new Intent(getBaseContext(),MyService.class));
And then on service:
public int onStartCommand(Intent intent,int flage,int startId){
// Toast.makeText(this, "Yes please", Toast.LENGTH_LONG).show();
Intent mIntent=new Intent(MyService.this,trackingActivity.class);
mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(mIntent);
return START_STICKY; }
At the end of trackingActivity this line is written (Again):
startService(new Intent(getBaseContext(),MyService.class));
That's creates a lot of Services. Is there a better way to create a background service that repeats itself always without creating each time a new Service ?
I tried to do a while loop inside the Activity :
while(true){
Actions on activity
}
But with no success.
Context.startService(Intent) does not create a new Service for each call.
If there is already a matching service running, it passes the intent to that running service, but does not create a new one each time.
See the Android Developer Docs for Context.startService(Intent):
If this service is not already running, it will be instantiated and
started (creating a process for it if needed); if it is running then
it remains running.
Every call to this method will result in a corresponding call to the target service's onStartCommand(Intent, int, int) method, with the intent given here.
There is similar information in the Android Developer Docs about Starting a Service:
[When starting a service using an intent] the startService() method returns immediately and the Android system
calls the service's onStartCommand() method. If the service is not
already running, the system first calls onCreate(), then calls
onStartCommand().
...
Multiple requests to start the service result in multiple
corresponding calls to the service's onStartCommand(). However, only
one request to stop the service (with stopSelf() or stopService()) is
required to stop it.
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
I have tried to start a service and bind to the service in my Activity's onCreate() method. When I try to call a function from service like commSessionManagerService.startCommandUpperM() afterwards, a NullPointerException occurs. Here is the code that I use to start the service and bind to it:
Intent startIntent = new Intent(this, CommSessionManagerService.class);
startService(startIntent);
Intent bindIntent = new Intent(this, CommSessionManagerService.class);
bindService(bindIntent, conn, Context.BIND_AUTO_CREATE);
If I move the function startCommandUpperM() to onStartCommand() in the CommSessionManagerService, the onCreate method will take several seconds to complete. As a related note, I have a created and started a thread in the startCommandUpperM() function.
This is because your Service is actually bound on the UiThread. As onCreate also runs on UiThread, your call to bindService result in Handler.post(Runnable) be called on the main thread's handler.
So when bindService returns, the Service isn't already bound.
To circumvent this problem, you should put your code using your Service inside ServiceConnection.onServiceConnected().