Does FusedLocation updates work as background service? - android

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.

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;
}
}

Background Service not working on 7+ android version

I want to show local notification in an Android app that i am working. notification are based on network transaction completed in background.
I have tried service, intent service, jobservice etc but nothing is working when the app is closed.please share some working code for the reference.....
//Here is my service----
public class JobSyncFAQ extends Service {
private Message msg;
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
public JobSyncFAQ() {
}
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message msg) {
// here is my stuff
stopSelf(msg.arg1);
}
}
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("JobSyncFAQ", Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
mServiceHandler.removeCallbacks(mServiceLooper.getThread());
mServiceLooper.quit();
Intent intent = new Intent(getApplicationContext(),JobSyncFAQ.class);
sendBroadcast(intent);
}
//and in my receiver
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, JobSyncFAQ.class));
}
please note - i am facing this issue only for N+ version
When you "close" your app (i. e. you swipe it away on the recent apps screen), you don't actually close the app, you only close the underlying activity. In most cases, this corresponds to the app being closed, but if you have a background service running, the service is not terminated. This is for a good reason: YOu still want to receive WhatsApp messages, even when WhatsApp is closed. Hence, WhatsApp starts a background service to check for new messages, even when the app is closed.
For that reason, you need to notify your background service about the fact that it should cancel its task.
I developed a media application that uses a MediaBrowserService which is connected to a MediaController. Therefore, I can do the following in my activities onDestroyMethod:
MediaControllerCompat mediaControllerCompat = MediaControllerCompat.getMediaController(getActivity());
if (mediaControllerCompat != null)
mediaControllerCompat.getTransportControls().stop();
This tells the MediaBrowserService to stop and quit.
Edit: Since you use a generic service, you need to call stopService:
stopService(new Intent(MyActivity.this, JobSyncFAQ.class));

Android: How do I communicate to a STICKY Service if the app is alive or not? Is there an Android built-in way of doing that?

I created a service that get the user location even if the app is killed. The service is running perfectly and it get's the location correctly even if the app is killed. Which is the optimal/safer way to detect if the app is still alive to send the location either to main activity(If the app is alive or running on the background) or to a backend(if the app is killed)?. This is what I have so far(I'm checking the permissions on the main activity if someone wants to know, that's why I disabled them here):
#SuppressWarnings("MissingPermission")
public class GPSService extends Service {
private LocationListener listener;
private LocationManager locationManager;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
listener= new LocationListener() {
#Override
public void onLocationChanged(Location location) {
//To transfer the data to the main activity I use broadcast receiver in the main activity, using an intent filter location_update
Intent intentSendLocationMainActivity = new Intent("location_update");
Log.d("Location-update",location.getLongitude()+" "+location.getLongitude());
intentSendLocationMainActivity.putExtra("coordinates",location.getLongitude()+" "+location.getLongitude());
//I need to differentiate here if the app is killed or not to send the location to main activity or to a server
sendBroadcast(intentSendLocationMainActivity);
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
Intent activateGPSIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
activateGPSIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(activateGPSIntent);
}
};
locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
//noinspection MissingPermission, listen for updates every 3 seconds
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,3000,0,listener);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("ClearFromRecentService", "Service Started");
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("ClearFromRecentService", "Service Destroyed, Removing update location listener");
//unregistering the listener
/*if(locationManager != null){
locationManager.removeUpdates(listener);
}*/
}
public void onTaskRemoved(Intent rootIntent) {
Log.e("ClearFromRecentService", "END");
//here you can call a background network request to post you location to server when app is killed
Toast.makeText(getApplicationContext(), "Warning: App killed", Toast.LENGTH_LONG).show();
//stopSelf(); //call this method to stop the service
}
}
And in the manifest file I have
<service
android:name="applicatives.GPSService"
android:exported="false"/>
I came up with a possible solution, set an "isAlive" boolean on the onResume() and on the onStop() methods of the mainActivity and then use that to commnunicate to the service that the app is dead or alive.....
1) Is there a built-in way of checking that?
2) In case there isn't, will that boolean suffice?
Sorry, I still don't get your architecture (see discussion in comments). In any case, even if the app is "running", it could be in the background, which means that even if you sent data to the app, the user wouldn't necessarily see it. In my opinion your architecture is flawed.
I would use a bound Service. Have your Activity bind to the Service. If the Activity is no longer running (ie: it finished, or Android killed the process hosting the Activity), your Service will get a call to onUnbind(). In this case you know that the Activity is "dead".
From the question and comments I can digest the following requirements:
If MainActivity is in a "started" state (i.e. state between onStart() and onStop()), which means that it is visible to the user (but might be obscured by e.g. dialog), data need to be sent to that Activity.
If MainActivity is in "stopped" state (i.e. state before onStart() or after onStop()), which means that it is not visible, data need to be sent to backend (reason doesn't matter).
If the above requirements is what you need, then the scheme is as follows:
Implement bound service
Service has addListener(SomeListener listener) and removeListener(SomeListener listener) methods
MainActivity implements SomeListener
MainActivity (or any other Activity or Fragment or Service) binds the service in onStart() and registers itself as a listener when the service is connected (onServiceConnected() called)
MainActivity unregisters from listening to the service in onStop() and unbinds
Whenever new data available, Service checks whether there are any listeners registered and either notifies all the listeners, or sends data to backend if there are none
You can play with this scheme in order to tailor it to your exact needs.

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.

Stopping an intent service which is doing a timertask in android

I am using intent service to periodically send queries to my server to check if there are any updates. In the intent service there is a timer task, which queries the server every 3 seconds, This starts running when the application is closed.
Now when the user again comes back in to the application I want to stop the service.
How should I do this? how can an intent service which is doing timertask be stopped form another activity?
Please give suggestions for Intent Service because that is what I am using.
Maybe it will be better to use just service instead of IntentService.
public class UpdateService extends Service {
public class LocalBinder extends Binder {
public void startUpdates() {
// start updateThread if it not started, or
// notify about resuming probes
}
public void stopUpdates() {
// make updateThread to wait, until startUpdates
// called again.
//
// REMEMBER this method can be called when startUpdates didnt called.
}
}
// For simplicity we will use local binder.
private final IBinder binder = new LocalBinder();
#Override
public IBinder onBind(Intent intent) {
return binder;
}
private Thread updateThread = new Thread() {
#Override
public void run() {
while (true) {
// Do updates. Sleep/awake managment.
}
}
};
}
Just bind to service (with AUTO_CREATE_FLAG) and start updates when you are need.
When your activity shows just bind again to service and make it stop updates.
First of all,IntentService cannot be stopped.It will stop itself only after it has completed all the tasks present in its queue.Hence,IntentService should not be used here.

Categories

Resources