I want the service to start automatically when the phone boots up. But it doesn't run. I also created a foreground service so that the main activity can run in the background.
public void onReceive(Context context, Intent intent) {
if("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())){
Intent tempService = new Intent(context, MainActivity.class);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
context.startForegroundService(tempService);
}else{
context.startService(tempService);
}
}
}
I tried to execute the method in the main activity after executing the class called myService, but I can't do that. You need another way.I tried to execute public void onreceive in the code below, but I couldn't find a way in the end.
private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {
#Override
public void onReceive() {
//my code
}
};
I am having a problem with my service not starting under android Oreo.
I have an Alarm manager who schedules a service at a specific time of the day. I have a BootCompleted Broadcast receiver who resets the alarm if the user rebooted their phone.
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
new AlarmHelper(context).setAlarm(timeInMillis); // i get timeInMilis from SharedPref
}
}
I have an AlarmReceiver which starts the service when the alarm manager awakens.
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Constants.ACTION_SET_REPETITIVE_ALARM)) {
if(!isMyServiceRunning(context, PostReportsService.class)){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(background);
}else{
context.startService(background);
}
}
}
}
Device above and below Oreo both reach context.startService(background) (or context.startForegroundService(background)), but only devices above Oreo actually start the service.
This only happens after the device is rebooted, otherwise the service works for both under and above Oreo. Is there anything specfic i could do to resolve this.
Turns out the device I was testing on has power saving mode on that disabled the service on reboot.
It's mine BroadcastReciever class. The class working on Boot phone status.
Code ;
public class BroadCastRecieverBoot extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent ıntent) {
if(Intent.ACTION_BOOT_COMPLETED.equals(ıntent.getAction()))
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(new Intent(context, MyService.class));
context.startForegroundService(new Intent(context, GPSTracker.class));
} else {
context.startService(new Intent(context, MyService.class));
context.startService(new Intent(context, GPSTracker.class));
}
}
}
}
I get This Error ;
android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground()
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1792)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6523)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:857)
It doesn't work on Android Oreo now. I don't know what is the mistake of that.
According to official document of Android 8.0 Background Execution Limits
Android 8.0 introduces the new method
startForegroundService() to start a new service in the foreground.
After the system has created the service, the app has five seconds to
call the service's startForeground() method to show the new service's
user-visible notification. If the app does not call startForeground()
within the time limit, the system stops the service and declares the
app to be ANR.
So, make sure you have started ongoing notification by calling startForeground (int id, Notification notification) in the onCreate() method of your service.
Note: Apps targeting API Build.VERSION_CODES.P or later must request the permission Manifest.permission.FOREGROUND_SERVICE in order to use this API.
I want to start service only when device is unlocked. I've tried this code but it didn't work.Can somebody explain me what do I do wrong?And what should I do?
if( myKM.isKeyguardLocked()==false) {
startService(intent);
Log.i("Point ","5");
} else {
Log.i("Point ","6");
stopService(intent);
}
You can have a Broadcast Receiver for ACTION_USER_PRESENT
No you can check in onReceive (Context context, Intent intent) as below -
if(intent.getAction().equals(Intent.ACTION_USER_PRESENT)){
// device unLocked
}
I have a Service and BroadcastReceiver in my application, but how do I launch the service directly from the BroadcastReceiver? Using
startService(new Intent(this, MyService.class));
does not work in a BroadcastReceiver, any ideas?
EDIT:
context.startService(..);
works, I forgot the context part
Don't forget
context.startService(..);
should be like that:
Intent i = new Intent(context, YourServiceName.class);
context.startService(i);
be sure to add the service to manifest.xml
use the context from the onReceive method of your BroadcastReceiver to start your service component.
#Override
public void onReceive(Context context, Intent intent) {
Intent serviceIntent = new Intent(context, YourService.class);
context.startService(serviceIntent);
}
Best Practice :
While creating an intent especially while starting from BroadcastReceiver, dont take this as context.
Take context.getApplicationContext() like below
Intent intent = new Intent(context.getApplicationContext(), classNAME);
context.getApplicationContext().startService(intent);
try {
Intent intentService = new Intent(context, MyNewIntentService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intentService );
} else {
context.startService(intentService );
}
} catch (Exception e) {
e.printStackTrace();
}
It's better to use ContextCompat:
Intent serviceIntent = new Intent(context, ForegroundService.class);
ContextCompat.startForegroundService(context, serviceIntent);
Because a receiver's onReceive(Context, Intent) method runs on the main thread, it should execute and return quickly. If you need to perform long running work, be careful about spawning threads or starting background services because the system can kill the entire process after onReceive() returns. For more information, see Effect on process state To perform long running work, we recommend:
Calling goAsync() in your receiver's onReceive() method and passing the BroadcastReceiver.PendingResult to a background thread. This keeps the broadcast active after returning from onReceive(). However, even with this approach the system expects you to finish with the broadcast very quickly (under 10 seconds). It does allow you to move work to another thread to avoid glitching the main thread.
Scheduling a job with the JobScheduler
developer.android.com