I have implelemented the START_STICKY command but the service is killed after a few hours. What I want to do is keep a service running always in the background and restart even when the device is rebooted. Can I restart the service in the onDestroy method like this? or is there a more convenient approach to it?
#Override
public void onDestroy() {
Stop();
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Intent i= new Intent(getApplicationContext(), MyService.class);
startService(i);
}
For ensuring that your service is running even after some hours of starting it, then you will have to use AlarmManager which will run recurringly for a specified periodicity even if the app is killed. What will you do is register a PendingIntent for the AlarmManager to fire which will be received by a BroadcastReceiver and in the BroadcastReceiver you will check that if your Service is running or not. If running, do nothing and if not then start the service.
What I want to do is keep a service running always in the background and restart even when the device is rebooted.
In order to do this you will have to give this permission in the manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
and then you will have to make a custom BroadcastReceiver which will check for an intent to be fired which is Action.BOOT_COMPLETED.
You should declare your BroadcastReceiver to catch the above mentioned intent in the Android Manifest like this:
<receiver android:name="com.example.MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Now either you can initialise your AlarmManager in BroadcastReceiver class or you can write the code to start the service straightaway.
Info on AlarmManager can be found here.
Disclaimer:
Starting from Android O, Google will stop supporting Unbound Background Service and calling startService() will become Illegal(Android will throw IllegalStateException) when calling this function.
Related
In my app, I'm trying to start a service on phone boot. But it's not responding at all.
public class ServiceStarter extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent pushIntent = new Intent(context, AppServices.class);
context.startService(pushIntent);
}
}
}
In the manifest, I did this.
<receiver android:name=".ServiceStarter" android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" tools:ignore="BatteryLife" />
</intent-filter>
</receiver>
Inside the service AppServices.class
onCreate {
Toast.makeText(getAppContext(),
"Phone booted", Toast.length_long).show(); //just for test
andMyOtherCodeAsWell();
}
But it's not working at all, can anyone help me with the issue?
SOLVE working after 15 secs of the boot even the app is not running in the background(manually cleared by user).
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
Check your API version. Oreo behaviour changes - If you attempt to call startService() when your application is not in the foreground then an IllegalStateException will be thrown.
Docs :
Context.startForegroundService() method starts a foreground service.
The system allows apps to call Context.startForegroundService() even
while the app is in the background. However, the app must call that
service's startForeground() method within five seconds after the
service is created.
so call:
context.startForegroundService() in your BroadcastReceiver and promote your service to a foreground service within 5 seconds of it starting by showing a notification i.e.: startForeground(NOTIFICATION_ID, notification);
Also make sure you have the correct permissions:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
You can try to put a breakpoint inside the BroadcaseReceiver and then send BOOT_COMPLETED broadcast via adb with the following command:
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED -p com.example.package
(Don't forget to change com.example.package to your package name).
This way you can check and see if your broadcast receiver is getting called.
I wont start service at specific time everyday and also start when the device boot complete.
For example.. at 13.00 Pm everyday the service started and show a Toast ("Service started").
not only that, but the service has to start also at boot complete but if you are not the 13.00 pm should not show the toast but must started
For boot complete define receiver for ACTION_BOOT_COMPLETED
Start service at boot complete
For Specific time, use AlarmManager
Start Service At Specific Time
public class onBootComplete extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
//Do your task here
}
}
}
And in Manifest declare this..
<receiver
android:name=".onBootComplete"
android:enabled="true"
android:exported="true" >
<intent-filter android:priority="500" >
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Add this permission:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
For timed actions use AlarmManager
This class provides access to the system alarm services. These allow
you to schedule your application to be run at some point in the
future. When an alarm goes off, the Intent that had been registered
for it is broadcast by the system, automatically starting the target
application if it is not already running.
check this link ,it will help you How to repeat notification daily on specific time in android through background service
Hello I am running a background service to check in my server if there is a new data.
But if I kill the App, the background service also dies.
If I run the background service on it;s on process, the system kill it after it has run a couple times.
Manifest
<service
android:name=".backgroundSerive"
android:enabled="true"
android:exported="false"/>
Option 2
<service
android:name=".backgroundSerive"
android:process=":my_process"
android:enabled="true"
android:exported="false"/>
MainAActivity - Starting the service
Intent i = new Intent(this, backgroundSerive.class );
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startService(i);
Service
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
...start runnable
return START_STICKY;
}
I try both option, The service keeps getting killed.
Any advice. To make my server always run.
thank you
You need to call startForeground() from within the service, to lower the chance of Android actually killing it. Please check out this sample for an example implementation.
startForeground function sends the service to foreground, so android system considers this operation as a foreground task. Which is very less likely to be killed.
If you have choosen the services destroy action as START_STICKY it would get destroyed but right after it destroyed it should be reinitialized with a null intent.
You may consider using Alarm for such event.
Since alarms are running in an internal process they reduce the app overhead, yet they provide recurring checks.
I have the following problem: I send in regular interval GPS data from the mobile to a server. In fact I want this background service only running as long the user is willing to submit data. There should be some sort of confirmation dialog that from now on data are submitted and then these submissions should be active - event if the App is shutdown meanwhile - until the user again confirms that data should be no longer sended:
Here is my current entry in the AndroidManifest.xml:
....
<receiver
android:name="ch.bbcag.jumpin.app.receiver.gps.ConnectivityReceiver"
android:process=":gps_process" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
<receiver
android:name="ch.bbcag.jumpin.app.service.LocationUpdaterService"
android:process=":gps_process" />
<service
android:name="ch.bbcag.jumpin.app.service.LocationUpdaterService"
android:process=":gps_process" />
....
GcmIntentService.java:
public class ConnectivityReceiver extends BroadcastReceiver {
private static final int EXEC_INTERVAL = AppConstants.GPS_REPEAT_SECONDS * 1000;
private final static String TAG = "ch.bbcag.jumpin.app.receiver.gps.ConnectivityReceiver";
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Received event");
final AlarmManager alarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
final PendingIntent wakeupIntent = PendingIntent.getService(context, 0,
new Intent(context, LocationUpdaterService.class),
PendingIntent.FLAG_UPDATE_CURRENT);
final boolean hasNetwork = !intent.getBooleanExtra(
ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
if (hasNetwork) {
context.startService(new Intent(context,LocationUpdaterService.class));
Calendar now = Calendar.getInstance();
now.add(Calendar.SECOND, AppConstants.GPS_REPEAT_SECONDS);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, now.getTimeInMillis(), EXEC_INTERVAL, wakeupIntent);
} else {
alarmManager.cancel(wakeupIntent);
}
}
}
The problem with this approach is that event the user is not using the App events are sent to the server. A simple solution would be in the class LocationUpdaterService to check in preferences if app should really send events. But the fact stays that LocationsUpdaterService is called regularly even if I don't use it (and Android wastes time to call this service).
How I can figure this out? Articles? Code examples are welcome!
How I can figure this out?
Only schedule your alarms when you need them. If you no longer need them, cancel the alarms.
Also, if you are going to use RTC_WAKEUP, either use WakefulBroadcastReceiver or my WakefulIntentService, otherwise your alarms will not be reliable.
Also also, your manifest is malformed. Either ch.bbcag.jumpin.app.service.LocationUpdaterService is a <receiver> or it is a <service>, but it cannot be both.
And also also also, dump the android:process=":gps_process" unless you have a clear understanding of why you are using it and its costs to you and the users.
I just have to read the documentation from Google to get aware how things are really working:
1) I don't want to start the Alarm when the device boots:
Solution:
(AndroidManifest.xml)
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver android:name=".SampleBootReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
Notice that in the manifest, the boot receiver is set to
android:enabled="false"
This means that the receiver will not be called unless the application explicitly enables it. This prevents the boot receiver from being called unnecessarily. Once you have started the your App you can:
ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
From this point on the GPS locations are send in regular intervals to the server. Once you have done this, the next time the receiver will start on boot up. This is what i want to prevent.
2) Prevent automatically starting BootReceiver from boot:
For this purpose I'm looking for a possibility to get the shutdown event of the Android system:
<uses-permission android:name="android.permission.DEVICE_POWER" />
<receiver android:name=".ShutdownReceiver">
<intent-filter>
<action android:name="android.intent.action.ACTION_SHUTDOWN" />
</intent-filter>
</receiver>
public class ShutdownReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP);
}
}
This has the effect that next time the mobile boots it will not start automatically the SampleBootReceiver until you explicitly specify this with the code:
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
3) Conclusions:
a) Once your App is started the Receiver is activated: GPS coordinates go in regular intervals to the server
b) In your App you can make a setting to terminated the receiver or to enable it.
c) Finally if the handy shut down it's time to remove the receiver.
d) The next time you can restart with a)
I want to write some kind of background-live-ticker app for sports-web-services...
I would like my app to be able to call the TIME_TICK all the time.
Btw: I also tried to use the AlarmManager, but the problem is the same.
But now my problem...
I use a Receiver with a Service for the execution part.
The Receiver is called every minute correctly after register.
But every night the service is terminated and will never be called again.
On Android 2.x everything works fine but Android 4.x will stop the Receiver every day...
Is there any posibility to keep the app alive on Android 4.x?
The Reveiver is registered in my Main-Activity:
registerReceiver(new MyReceiver(), new IntentFilter(Intent.ACTION_TIME_TICK));
Manifest-entries:
<service android:name="de.pepdev.MyService" />
<receiver android:name="de.pepdev.MyReceiver">
<intent-filter>
<action android:name="android.intent.action.TIME_TICK" />
</intent-filter>
</receiver>
Receiver-class:
public class MyReceiver extends BroadcastReceiver
{
public static long nextExecTime = 0;
public static Calendar currentTime = Calendar.getInstance();
#Override
public void onReceive(Context context, Intent intent)
{
currentTime = Calendar.getInstance();
if(nextExecTime <= currentTime.getTimeInMillis())
{
Intent service = new Intent(context, MyService.class);
context.startService(service);
}
}
}
I also tried to use the AlarmManager, but the problem is the same
AlarmManager is a far better answer than ACTION_TIME_TICK, particularly if you let the user configure the polling frequency (including an option for "never poll, please, as I like my battery and bandwidth usage to stay low").
Please feel free to ask a separate StackOverflow question regarding whatever problems you feel your are experiencing with it.
But every night the service is terminated and will never be called again
Android can and will terminate your process at any point, either by user request or due to old age.
Manifest-entries:
The <receiver> is pointless, as you cannot register for ACTION_TIME_TICK via the manifest.