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 to keep a service alive in Flutter to run a socket io

I'm trying to create a service which will run a socket for receiver data when the app is closed.
According to this thread on Github Flutter should provide an abstraction for background execution, flutter doesn't have an abstraction that executes a code in the background, so I'm writing a native code.
The service opens up correctly, but as soon as the app is closed, it gets moved to cache services and after approximately 5 minutes it is ended.
I found this background_service MainActivity.java, but I'm not using the notification example contained in that repository. (The service contained in this repository also gets terminated once the app is closed.
The example plugin for this article as well.
I still don't have a concrete plan to make the socket connection in the service. I actually would like to call the socket_io_client function within the service, sort of like a callback, but I'm not sure if it will work.
So I just want to know if it is possible to keep the service running after the app is closed. If yes, how?
MainActivity.java
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "com.retroportalstudio.www.background_service";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent forService = new Intent(this, MyService.class);
forService.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(new MethodChannel.MethodCallHandler() {
#Override
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
if (methodCall.method.equals("startService")) {
startService(forService);
result.success("Service Started");
}
}
});
}
}
public class MyService extends Service {
// #Override
// public int onStartCommand(Intent intent, int flags, int startId) {
// return START_STICKY;
// }
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}

Does FusedLocation updates work as background service?

I have a class for using FusedLocationApi to send the location of user frequently to the server. All methods for getting location updates and communicating with server are set in this class except that when I want to run this class, I call a background service and then use this class inside it.
Uisng FusedLocationApi.requestLocationUpdates , the location is being sent to the server properly and I can see Toasts from this service. But when I check the Running services on android system, my application is not listed there.
My question is that why my service is not running anymore but the location is being updated? Is the FusedLocation Service is a background service itself? Do I need to call it frequently through a background service to keep it alive or I can call it inside the activity and let it continue running even after closing the app?
this is how I use the class inside my own service:
public class LocationService extends Service {
FusedClass mylocation=new FusedClass(this);
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getAction().equals("turnOn")) {
HandlerThread handlerThread = new HandlerThread("LocationThread");
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());
handler.post(new Runnable() {
#Override
public void run() {
mylocation.LocationStartPoint();
}
});
}
if (intent.getAction().equals("turnOff")) {
stopSelf();
}
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
//TODO for communication return IBinder implementation
return null;
}
EDIT: I use FusedLocationApi.requestLocationUpdates and onLocationChanged to get location updates from this API.

Android Background Service and Thread

I am developing android application using rabbit mq pub/sub technology. I want to listen incoming message in android background service. Can I run thread in android background service ?
public class MessagingService extends Service {
private Thread subscribeThread;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
subscribeThread = new Thread(new Runnable() {
#Override
public void run() {
//Connecting to server and listen incoming message.
}
});
subscribeThread.start();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
subscribeThread.interrupt();
}
}
Yes you can run new thread in Android Service.
Please see note in documentation here: http://developer.android.com/guide/components/services.html
Caution: A service runs in the main thread of its hosting process—the service does not create its own thread and does not run in a separate process (unless you specify otherwise). This means that, if your service is going to do any CPU intensive work or blocking operations (such as MP3 playback or networking), you should create a new thread within the service to do that work.
Hope this will help you.

Start a Service from another Service and pass-by-value

I've got a Service in my Android application. During onStartCommand, I pass the Service object to another class. Then, from there, there's a thread that after 30 seconds starts another Service. It is something like this:
public class FooService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
MyClass mc = new MyClass(this);
mc.testMethod();
stopSelf();
return START_NOT_STICKY;
}
}
And this is MyClass:
public class MyClass {
private Service service;
public MyClass(Service service) {
this.service = service;
}
public void testMethod() {
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(20*1000);
Intent intent = new Intent(service, BarService.class);
service.startService(intent);
}
catch (Exception e) {
// CATCH!
}
}
}).start();
}
}
Now, as you can see, in FooService I call stopSelf() wich destroys that Service object. By the way MyClass has got a copy of that Service that was passed by value. After 20 seconds, we can start BarService from MyClass. I've tested it and it works but I can't understand why! The way I wrote the code is dirty (for me). Is it correct to start another service from one that was destroyed? Thank you for your help.
I've tested it and it works but I can't understand why
It works today on the environments you tested in. It may not work in all environments (e.g., ROM mods) and may not work tomorrow (e.g., Android OS updates). A destroyed Context, such as your stopped service, should not be used for anything. It happens that presently you can still use it to call startService() later, but that behavior is not guaranteed.
Is it correct to start another service from one that was destroyed?
No. In this case, I fail to see why you need two services in the first place.
I've got a copy of that service
No, you do not.

Service stops when deploying android app (disapears from settings>>application>>RunningServices)

This is my situation: I have a service running and every time I deploy my app the service disappears from settings>>application>>runningService (therefore, the service is not running) how can I set it so that the service does not disappears?
I have tried to startForeground but it did not worked.
AndroidManifest:
<service
android:name=".service.PhoneCallInOutService"
android:enabled="true"
android:exported="false" >
</service>
This is how I start the service in my Activity:
chkCallsRecord.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
boolean isChecked = chkCallsRecord.isChecked();
updateBackgroundTasks(isChecked);
}
});
The method actually starting the service:
private void updateBackgroundTasks(boolean start) {
Intent serviceIntent = new Intent(getApplicationContext(),PhoneCallInOutService.class);
if (start) {
getApplicationContext().startService(serviceIntent);
} else {
getApplicationContext().stopService(serviceIntent);
}
}
And here is the service:
public class PhoneCallInOutService extends Service {
private TelephonyManager telephonyMgr;
private PhoneCallStateListener pcsListener;
private OutgoingCallReceiver ocReceiver;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
// Listener
pcsListener = new PhoneCallStateListener(getApplicationContext(),appDto);
telephonyMgr = (TelephonyManager)getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
telephonyMgr.listen(pcsListener, PhoneStateListener.LISTEN_CALL_STATE);
// Receiver
ocReceiver = new OutgoingCallReceiver(getApplication());
IntentFilter intentF = new IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL);
getApplicationContext().registerReceiver(ocReceiver, intentF);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
// Listener
telephonyMgr.listen(pcsListener, PhoneStateListener.LISTEN_NONE);
// Receiver
getApplicationContext().unregisterReceiver(ocReceiver);
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
Thank you very much in advance.
If by deploy you mean you try to launch new build of your app, then this is actually normal and expected behaviour. By deploying new build you replace old code (incl. service code) therefore it have to be killed first to avoid any crashes and other oddities. So your old iteration of app is completely killed. Then new app is installed and most often auto-launched. Your data create by the app usually stay, but it's also normal.
EDIT
For security reasons you are not allowed to re-launch itself after being updated. User has to to this. As for "he/she may assume the service is still there running, which is not true", use notification of type "On Going" to indicate running service

Categories

Resources