Alternative/replacement of Firebase Jobdispatcher - android

recently came back to some Android dev, and since Nougat it seems that Firebase JobDispatcher isn't possible to be triggered more than once every 15 mins, which isn't applicable in our use case, we need to be able to push & pull data to our webservice at least once per minute.
What should/can I be using instead? I haven't been able to find a solid replacement yet, been looking into SyncAdapter, IntentService and what I've found they aren't really best applicable in this use case.
Thanks in advance.

You can use basic Service
public class YourWebService extends Service {
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
#Override
public void onCreate() {
super.onCreate();
Runnable runnable = new Runnable() {
#Override
public void run() {
//your code here
//web request, data push, something else
}
};
//your code will be executed every 60 seconds
scheduler.scheduleAtFixedRate(runnable, 0, 60, TimeUnit.SECONDS);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
You can start your service from activity
startService(new Intent(YourActivity.this, YourWebService.class));
And you have to register your service in manifest.xml
<service
android:name=".YourWebService" />

Related

How do I stop my thread and will my service stop too if I do?

I'm currently working on my first android app and I've run into a problem.
My app is supposed to be counting in the background using a Service and I'm creating a new thread to handle that. If I don't stop the thread in my Service's onDestroy() method, my phone gives me the message "Unfortunately, (my app) has stopped." every time I close the app. I need to stop it somehow, and I tried to do it using :
while(!Thread.currentThread().isInterrupted()){
**my code**
}:
And then interrupting it in the onDestroy() method.
It works, but it makes my app count extremely fast, so I would like to know if it can be done any other way that does not change the functionaliy of my code.
Also, since my thread gets stopped in the onDestroy method, I guess my service stops as well. Is there any way to keep my service running even when my app has been closed?
Here's my code:
public class CounterService extends Service {
private Handler handler;
private int time = -1;
private boolean isActive;
private Intent timeBroadcaster;
private Runnable counter;
private Thread serviceCounter;
#Override
public void onCreate(){
super.onCreate();
handler = new Handler();
timeBroadcaster = new Intent();
timeBroadcaster.setAction("EXAMPLE_BROADCAST");
counter = new Runnable() {
#Override
public void run() {
isActive = ((PowerManager) getSystemService(Context.POWER_SERVICE)).isInteractive();
if (isActive) {
handler.postDelayed(this, 1000);
time += 1;
} else {
if (time > 5) {
//log
}
time = 0;
handler.postDelayed(this, 1000);
}
timeBroadcaster.putExtra("counter", time);
sendBroadcast(timeBroadcaster);
}
};
serviceCounter = new Thread(counter);
serviceCounter.start();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy(){
//serviceCounter.interrupt();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
Is there any way to keep my service running even when my app has been closed?
you can use sync adapter which runs in background even app is stoped.
https://developer.android.com/training/sync-adapters/creating-sync-adapter.html

How to run background service after every 5 sec not working in android 5.1?

I need to call a background service every 5 seconds, but I am facing a problem in Android 5.1 (Lollipop): it automatically considers the interval time 1 minute.
Please help me to run a background service every 5 sec.
Since the minimum interval for alarms is one minutes on Android 5.1, You can tweak your service to repeat job every 5 seconds:
public class MyService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy(){
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
startJob();
}
});
t.start();
return START_STICKY;
}
private void startJob(){
//do job here
//job completed. Rest for 5 second before doing another one
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//do job again
startJob();
}
}
The above code ensures one job is completed before it executes another job, hence its a cleaner approach. But if your requirement does not need to ensure completion of one job before executing another job, you can use the code below:
public class MyService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy(){
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
while(true){
startJob();
Thread.sleep(5000);
}
}
});
t.start();
return START_STICKY;
}
private void startJob(){
//do job here
}
}
And finally, you can start service by calling startService(); from your activity thread. By this, you are bypassing AlarmManager restriction. Hope it helps...
In Android 5.1, they appear to have set a limit, where low polling periods are rounded up to 60000ms (one minute). Repeat intervals higher than 60000ms are left alone.
For timing operations (ticks, timeouts, etc) it is easier and much more efficient to use Handler.
So if you want to achieve your goal you have to use handler to do that in android 5.1.
Refer this link
https://developer.android.com/reference/android/app/AlarmManager.html#setRepeating(int, long, long, android.app.PendingIntent)
I don't see a problem
Either you let the service run all the time and let it wait 5 seconds b4 new tasks are being processed
Or you start every minute a thread which does every 5 seconds the tasks you want...and comes to a halt after a minute maybe just kill, initialize new one it and start it right away

Non-sticky service with interval task

Assume the following code:
public class MyApplication extends Application {
#Override
public void onCreate()
{
super.onCreate();
getApplicationContext().startService(new Intent(getApplicationContext(), MyService.class););
}
}
public class MyService extends IntentService {
private Handler mLoadContactsHandler;
public MyService() {
super(MyService.class.getName());
myHandler = new Handler();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_NOT_STICKY;
}
#Override
protected void onHandleIntent(Intent intent)
{
int delay = intent.getIntExtra("delay", 1000 * 60 * 5);
myHandler.postDelayed(updateTask, delay);
}
private Runnable updateTask = new Runnable() {
public void run() {
Thread thread = new Thread()
{
public void run()
{
... some task ...
}
};
thread.start();
myHandler.postDelayed(this, 1000*60*15);
}
};
}
Would this service keep running even if I exit the app? (Exit as in closing the app using back-button)
I mean, the service is never really finished. How can I make the service quit if the app has been shut down. Of course, I would like it to finish what it's doing.
Edit. I want the service to keep running on its interval as long as the app is running.
Would this service keep running even if I exit the app? (Exit as in closing the app using back-button)<p>
Yes, it would keep running unless android kills it, which it does few times a day.
How can I make the service quit if the app has been shut down. Of course, I would like it to finish what it's doing.<p>
AFAIK, one can know when an activity/service is destroyed but cannot know when an app is destroyed(reason being android likes to keep applications alive in memory, so there is no fixed time). So , I would suggest you to call stopSelf(); as the last line in the run() method of your thread. That will stop your service after your thread has finished the task at hand.
public void run()
{
// ... some task ...
stopSelf();
}
Use IntentService instead so that the Android system will manage it (Like stopping the service when completed etc).

Android - how to run a task via “handler” periodically within a service-intent (worker-thread)

My question is Android related:
How do I run a task every 20 seconds within an intentservice ?
Problem is, I have to init some classes which will be used in the Handler "run" process.
It works one time - but then the service stops & the application crashes when the handler-loop starts again after 20 seconds (probably because of the classes that got eliminated when the service stopped?). So maybe the solution is to get the service to stay running as long as the Handler runs or to throw away the code and do it right ?
Hope, someone can help me.
public class Fadenzieher extends IntentService{
private Handler handler = new Handler();
private Runnable timedTask = new Runnable(){
#Override
public void run() {
// My functions get called here...
// class1member.getDBWorkdone();
handler.postDelayed(timedTask, 20000);
handler.obtainMessage();
}};
public Fadenzieher() {
super("Fadenzieher");
}
#Override
protected void onHandleIntent(Intent intent) {
// SOME INITIALISING
// I have to init some vars & functions here that
// will also be used inside the handler loop
// Class1 class1member = new Class1();
// class1member.startUpDB();
handler.post(timedTask); }
Thank you very much in advance!!!
---- So this is the updated code now (14. nov. 2011)
public class Fadenzieher extends Service{
private static final long UPDATE_INTERVAL = 60000;
Context context = this;
private Timer timer = new Timer();
DbHelper dbHelper;
public void onCreate(){
dbHelper = new DbHelper(context);
runTheLoop();
}
protected void runTheLoop() {
timer.scheduleAtFixedRate(new TimerTask(){
#Override
public void run() {
dbHelper.dosomethings();
Toast.makeText(context, "CALL", Toast.LENGTH_LONG).show();
}}, 0, UPDATE_INTERVAL);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Starte Service“, Toast.LENGTH_SHORT).show();
return super.onStartCommand(intent,flags,startId);
}
public void onDestroy() {
super.onDestroy();
dbHelper.close();
Toast.makeText(this, "Stoppe Service“, Toast.LENGTH_LONG).show();
}
// We return the binder class upon a call of bindService
#Override
public IBinder onBind(Intent arg0) {
return mBinder;
}
public class MyBinder extends Binder {
Fadenzieher getService() {
return Fadenzieher.this;
}
}
}
The whole application crashes immediately.
How do I run a task every 20 seconds within an intentservice ?
That is not an appropriate use of IntentService. Use a regular Service, please.
It works one time - but then the service stops & the application crashes when the handler-loop starts again after 20 seconds
IntentService shuts down when onHandleIntent() returns, which is why this is breaking for you. Use a regular Service, please.
Also:
Please allow the user to configure the polling period
Make sure that this service will shut down when the user no longer wants it to be running

Use IntentService to perform a repeated tasks

I have to perform a repeated tasks (download data from internet) in a Service. I did the task with the following code:
public class MyService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mHandler.post(mTask);
return START_STICKY;
}
private final Runnable mTask = new Runnable() {
#Override
public void run() {
downloadData(url);
mHandler.postDelayed(this, mDelay);
}
};
#Override
public void onDestroy() {
mHandler.removeCallbacks(mTask);
}
}
If I want to use an IntentService instead a service and move mHandler.post(mTask); to onHandleIntent the code is executed only 1 time because then the IntentService is killed.
#Override
public void onHandleIntent(Intent intent) {
mHandler.post(mTask);
}
Can I prevent this and make the IntentService running?
If the service overall will not be around very long, and if mDelay is short (a minute or less), you may just want to stick with your original implementation.
If mDelay is long, you should use AlarmManager, so your service is only in memory while it is doing work. In that case, the AlarmManager alarm is handing the periodic repeat.

Resources