I am just newbie to android,please help a little. i am trying to use JobService or com.firebase.jobdispatcher.JobService in my android application but as far as i studied i see that the JOB SERVICE runs on Main Thread and as long as application is running either in background or forground it keep doing its schedule work.
But the issue is i want to do Get users location lets say after every 30 minutes even if the application is removed from application tray. i am confused in following points
If i run a sticky service it does not give me scheduling
If i use Job Service it gives scheduling but terminates as application is
closed.
Is there any way to run a service which run even after application is killed and do schedule tasks as well?
you can use AlarmManager link
Create Your Server class :
public class MService extends IntentService {
public MyTestService() {
super("MService");
}
#Override
protected void onHandleIntent(Intent intent) {
// Your firebase task
}
}
then your broadcast
public class MReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent in = new Intent(context, MService.class);
context.startService(in);
}
}
finally
Intent intent = new Intent(getApplicationContext(), MReceiver.class);
final PendingIntent pIntent = PendingIntent.getBroadcast(this, MReceiver.REQUEST_CODE,intent, PendingIntent.FLAG_UPDATE_CURRENT);
long firstMillis = System.currentTimeMillis();
AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, firstMillis, AlarmManager.INTERVAL_HALF_HOUR, pIntent);
Related
Previously I was using IntentService to send data to the server periodically. However, since Android O limiting background task and processes I am moving towards JobIntentService.
My Activity code to schedule an alarm
Intent intent = new Intent(BaseActivity.this, EventBroadcastReceiver.class);
// Create a PendingIntent to be triggered when the alarm goes off
final PendingIntent pIntent = PendingIntent.getBroadcast(this, EventBroadcastReceiver.REQUEST_CODE,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Setup periodic alarm every half hour
long firstMillis = System.currentTimeMillis(); // alarm is set right away
AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, firstMillis,
AlarmManager.INTERVAL_HALF_HOUR, pIntent);
And my Service is as follows
public class EventAnalyticsService extends JobIntentService {
#Override
protected void onHandleWork(#NonNull Intent intent) {
// Perform your task
}
#Override
public void onCreate() {
super.onCreate();
}
}
Receiver for this code is
public class EventBroadcastReceiver extends BroadcastReceiver {
public static final int REQUEST_CODE = 12345;
#Override
public void onReceive(Context context, Intent intent) {
Intent myIntent = new Intent(context, EventAnalyticsService.class);
context.startService(myIntent);
}
}
However this is not working for Android O when app is in background and if I use context.startForegroundService(myIntent); to start my service it is throwing exception as Context.startForegroundService() did not then call Service.startForeground()
JobIntentService is there mostly for a service that will be invoked from the UI, such as a service to perform a large download, initiated by the user clicking a "Download!" button.
For periodic background work, use JobScheduler and a JobService. If you need to support older than Android 5.0, use a suitable wrapper library (e.g., Evernote's android-job), one that will use JobScheduler on newer devices and AlarmManager on older devices.
Alternatively, stick with AlarmManager, but use a foreground service.
I have some existing code that spawns a service intent which does a bunch of stuff in the background. This code does work...
Intent serviceIntent = new Intent(context, APMService.class);
serviceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startService(serviceIntent);
My question is: how to change this to use the AlarmManager.setInexactRepeating(...) methods?
I have changed the above code to this:
Intent serviceIntent = new Intent(context, APMService.class);
serviceIntent.putExtra("STARTED_BY", starter);
serviceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//Set up recurring alarm that restarts our service if
// it crashes or if it gets killed by the Android OS
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pi = PendingIntent.getService(context, 0, serviceIntent, 0);
//am.cancel(pi);
am.setInexactRepeating(
AlarmManager.ELAPSED_REALTIME_WAKEUP //wake up the phone if it's asleep
, cal.getTimeInMillis()
, 10000
, pi);
And I have added these permissions to AndroidManifest.xml...
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<uses-permission android:name="com.android.alarm.permission.WAKE_LOCK"/>
My understanding is that this is supposed to start the service immediately and then try to restart it again every 10 seconds. But this code isn't working properly.
Using this new code, the service never starts at all and I cannot see why not. To complicate matters the debugger never seems to attach to the app in time to see what's going on.
Can anyone see what I'm doing wrong?
Put AlarmManager code under onDestroy() function of service to schedule start of service as below:
#Override
public void onDestroy() {
/**
* Flag to restart service if killed.
* This flag specify the time which is ued by
* alarm manager to fire action.
*/
final int TIME_TO_INVOKE = 5 * 1000; // try to re-start service in 5 seconds.
// get alarm manager
AlarmManager alarms = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AutoStartServiceReceiver.class);
PendingIntent pendingIntent = PendingIntent
.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
// set repeating alarm.
alarms.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() +
TIME_TO_INVOKE, TIME_TO_INVOKE, pendingIntent);
}
And handle starting of your service in AutoStartServiceReceiver as below:
public class AutoStartServiceReceiver extends BroadcastReceiver {
private static final String TAG = AutoStartServiceReceiver.class.getSimpleName();
#Override
public void onReceive(Context context, Intent intent) {
// check broadcast action whether action was
// boot completed or it was alarm action.
if (intent.getAction().equals(AppConstants.ACTION_ALARM_INTENT)) {
context.startActivity(new Intent(context, YourActivity.class));
// handle service restart event
LockerServiceHelper.handleServiceRestart(context);
}
}
}
Kindly note that, your service will not restart if you stop it manually from settings-apps-running apps-your app.
Your service is not starting because of AlarmManager.ELAPSED_REALTIME_WAKEUP, while it should be using AlarmManager.RTC_WAKEUP
If you want to run every 10s keep in mind that above API 21 alarm intervals below 60s are rounded up to 60s.
Also, consider using WakefulIntentService
https://github.com/commonsguy/cwac-wakeful
i have repeating service which runs every 5 minutes as long as the app is installed, but some times my service stops or gets killed, how do i make it fail safe and restart the service if it gets killed by the OS.
This is how im starting my repeating service.
Intent serviceIntent = new Intent(context, SyncService.class);
final AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
long interval = 60000; // 5 Mins - 1000*60; 1 sec=1000, 1min sec = 60*1000=60000
final PendingIntent pending = PendingIntent.getService(context, 0, serviceIntent, 0);
alarm.setRepeating(AlarmManager.RTC ,System.currentTimeMillis(), interval, pending);
and this is my service:
public class SyncService extends IntentService {
public SyncService() {
super("SyncService");
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent intent) {
SyncToServer();
}
}
IntentService always gets killed when work is done. If you want a long running service use the basic service instead: http://developer.android.com/reference/android/app/Service.html
I've been struggling with this for a couple of days. What I want to do is run a service periodically, about 2-3 minutes apart. I have an Activity that is responsible for the interface and setting up the first alarm.
The alarm is configured by a BroadcastReceiver which looks like this:
public class Receiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String message = "Alarm worked";
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
setAlarm(context);
}
public void setAlarm(Context context){
AlarmManager am = (AlarmManager) context.
getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, Receiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context,
0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent dailyUpdater = new Intent(context, DiscoveryService.class);
context.startService(dailyUpdater);
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
+ (1000 * 30) , pi);
}
}
I've tried using setRepeating for AlarmManager, but it still has the same effect. What happens is that the AlarmManager works how it should, it fires an Intent which the receiver gets and executes onReceive periodically, as it should. However, it executes the service only the first time. After the first time, the alarms still go off, but the service is not executed.
I read some threads from people with similar problems, and one of them mentioned that PendingIntent lasts for only one send. Thus, I opted out to setting the alarm every time so I can set pendingIntent flag for updating every time.
I tried making my service an intentService, which is fine, but then my bluetooth scanner inside the service does not work because intentService thread terminates without waiting for my bluetooth discovery to finish.
Anyone have any idea what can help me?
Here is part of my service:
public class DiscoveryService extends Service {
public void onCreate() {
super.onCreate();
Toast.makeText(this, "MyAlarmService.onCreate()",
Toast.LENGTH_LONG).show();
findEverything();
}
}
EDIT: This is the code that I currently have.
public void onReceive(Context context, Intent intent) {
String message = "Alarm worked";
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
Intent dailyUpdater = new Intent(context, DiscoveryService.class);
context.startService(dailyUpdater);
}
public void setAlarm(Context context){
// get a Calendar object with current time
AlarmManager am=(AlarmManager)context.
getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, Receiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
(1000 * 30) , pi);
}
What happens is that the AlarmManager works how it should, it fires an Intent which the reciever gets and executes onReceive periodically, as it should. However, it executes the service only the first time. After the first time, the alarms still go off, but the service is not executed.
You are calling startService() once when you are scheduling the alarm. You are not calling startService() at all from your BroadcastReceiver. Yet you are scheduling the alarm via the BroadcastReceiver. Hence, when the alarm goes off, the service will not be sent a command, because you are not sending it a command.
I read some threads from people with similar problems, and one of them mentioned that PendingIntent lasts for only one send.
That is only if you use FLAG_ONE_SHOT.
Anyone have any idea what can help me?
Call startService() from your onReceive() method, instead of from your setAlarm() method. Also, add in all the WakeLock management logic, since you are using a _WAKEUP alarm and you are not able to use my WakefulIntentService.
I have an update service that starts at boot. The thing is I want it to make a check and then wait for a period of time and restart itself. I did this with alarm clock when my service was tied to an application but now it is independent and I only use a broadcast receiver to start it at boot. The problem is that now for some reason I can't integrate my alarm clock with it.
I only have my UpdateService class and my broadcastreceiver class.My code so far in the broadcastreceiver is this, but I want to put the alarm clock here to say schedule the service to start every 30 seconds. I really need this.
#Override
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, UpdateService.class);
context.startService(startServiceIntent);
}
Any suggestions are welcome. Thanks in advance.
I found the answer to my problem:
private boolean service_started=false;
private PendingIntent mAlarmSender;
#Override
public void onReceive(Context context, Intent intent) {
if(!service_started){
// Create an IntentSender that will launch our service, to be scheduled
// with the alarm manager.
mAlarmSender = PendingIntent.getService(context,
0, new Intent(context, UpdateService.class), 0);
//We want the alarm to go off 30 secs from now.
long firstTime = SystemClock.elapsedRealtime();
// Schedule the alarm!
AlarmManager am = (AlarmManager)context.getSystemService(context.ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
firstTime,30*1000, mAlarmSender);
service_started=true;
}
}
Eventually,my problem was that I didn't get the context right as follows:
(AlarmManager)getSystemService(ALARM_SERVICE);
changed to
(AlarmManager)context.getSystemService(context.ALARM_SERVICE);