Android Geofencing dosen't trigger IntentService - java

I'm building a mobile application with which I'll be able to test working of geofencing on Android phones. I have an application that uses GoogleApiClient for FusedLocationApi.requestLocationUpdates. I'm getting all the updates which I show on the map in my MapFragment. I then try to add the geofences with GeofencingClient.
private void addGeofenceList() {
mGeofencingClient.addGeofences(getGeofencingRequest(), getGeofencePendingIntent())
.addOnSuccessListener(this, new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.wtf(TAG, "addGeofences() - succesfully added");
}
})
.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.wtf(TAG, "addGeofences() - failed to add");
}
});
}
This code is executed and I get back that they were succesfully added. But when I'm on the location where the geofence should trigger it dosen't call the IntentService. I also add the IntentService:
private PendingIntent getGeofencePendingIntent() {
if (mGeofencePendingIntent != null) {
return mGeofencePendingIntent;
}
Intent intent = new Intent(this, GeofenceService.class);
return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
I also create a GeofencingRequest where I set the initial trigger when entered.
private GeofencingRequest getGeofencingRequest() {
GeofencingRequest.Builder builder = new GeofencingRequest.Builder()
.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
.addGeofences(mGeofenceList);
return builder.build();
}
And this is where I create the ArrayList<Geofence> mGeofenceList in which I add all the geofences:
public void createGeofenceList() {
GeofenceList geofences = new GeofenceList();
ArrayList<GeofenceModel> geofenceList = (ArrayList) geofences.returnGeofences();
for (GeofenceModel geofence : geofenceList) {
mGeofenceList.add(new Geofence.Builder()
.setRequestId(geofence.getREQ_ID())
.setCircularRegion(
geofence.getLocation().latitude,
geofence.getLocation().longitude,
geofence.getRadius()
)
.setExpirationDuration(geofence.getExpire())
.setTransitionTypes(geofence.getTransition())
.build());
}
addGeofenceList();
}
My whole projects is on GitHub. All the help will be appreciated!

In your manifest replace your service declaration which is
<service android:name="services.GeofenceService" />
to this
<service android:name="services.GeofenceService"
android:exported="true"/>
Basically you should mark your service as exported so Android OS can invoke your IntentService

Related

Why does foreground service stop working when device go into sleep mode

I want to create an app that is constantly checking for location change and put the current location in the firebase (e.g. an app for runners).
Unfortunately the foregroundservice is being stopped or paused every time the device go into sleep mode.
For starters I wanted to create a foreground service that is continuously writing information to the base (that would be a time stamp or a simple string) every second.
After some time it just stops writing to firebase without calling stopself().
The service is working fine on the emulator (even if put to sleep), but stops when tested on a real device – in my case Huawei, Android 8.1.0.
What should I do to force service to run in every state of the device?
My MainActivity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Intent intent = new Intent(this, MyService.class);
intent.putExtra("action", "start");
startForegroundService(intent);
}
else {
Intent intent = new Intent(this, MyService.class);
intent.putExtra("action", "start");
startService(intent);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Intent intent = new Intent(this, MyService.class);
intent.putExtra("action", "stop");
startForegroundService(intent);
}
else {
Intent intent = new Intent(this, MyService.class);
intent.putExtra("action", "stop");
startService(intent);
}
}
}
MyService:
public class MyService extends Service {
int i =0;
private String CHANNEL_ID = "2345";
#Override
public void onCreate() {
super.onCreate();
}
public MyService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground(1000, createNotification());
String action = intent.getExtras().getString("action");
switch (action){
case "start":
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
myfunction();
handler.postDelayed(this, 1000);
}
};
break;
case "stop":
stopfunction();
break;
}
handler.postDelayed(runnable, 1000);
return START_NOT_STICKY;
}
private void stopfunction() {
stopSelf();
}
private void myfunction() {
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("locations");
myRef.child("location").setValue(i);
i++;
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return null;
}
#RequiresApi(Build.VERSION_CODES.O)
private void createChannel(){
NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, getString(R.string.infoTxt),
NotificationManager.IMPORTANCE_HIGH);
channel.setShowBadge(false);
channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
notificationManager.createNotificationChannel(channel);
}
private Notification createNotification(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
createChannel();
}
Intent notificationItent = new Intent(this, MainActivity.class);
notificationItent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(this, 0, notificationItent, 0);
return new NotificationCompat.Builder(this, CHANNEL_ID)
.setColor(ContextCompat.getColor(this, android.R.color.background_dark))
.setContentIntent(intent)
.setSmallIcon(R.drawable.ic_launcher_background)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setOnlyAlertOnce(true)
.setContentTitle("GPS Location")
.build();
}
}
I've tried everything: service, foreground service, broadcast receiver, jobSheduler, WorkerManager – nothing helped. Then I found it’s a new HUAWEI feature called “power-intensive app monitor “. It kills every app that runs in the background for a long time unless user gives special permissions to it.
The path to do this:
Settings -> Security & privacy -> Location services -> recent location requests: YOUR APP NAME -> Battery -> uncheck Power-intensive prompt, App launch: Manage manually: check all three positions: Auto-launch, secondary launch, run in background.
I don’t know is there a way to do this programmatically. I think the best way is to create a sort of help activity and explain the user what to do if application won’t work.
Foreground services generally should be used for task which require user attention such as visual processes.
use Background service instead

How to deal with background geofencing in 2022?

Here is the situation:
When a user creates a Geofence, I save it to backend and I register a Geofence with the OS. But whenever my app restarts I fetch geofences from my backend and reregister them with the OS again, since they keep disappearing.
I have two classes MainActivity and FormActivity. Both of these activities register Geofences, so I have extracted the actual registration to an ordinary POJO Geofences.java
Here is the problem:
Now the strange thing is, triggers are only received when a map activity is on the screen. I do have a map activity in my app, but it doesn't even have to be my map-activity, even if I launch google maps geofence triggers start firing.
What am I doing wrong?
Geofences.java:
public class Geofences {
private final String TAG = Geofences.class.getSimpleName();
private final float RADIUS = 150.0F; //meter
private boolean success = false;
private final int LOITERING_IN_MILLISECONDS = 30000;// 30 seconds
public boolean doGeofenceStuff(GeoTemp newTemp, String geofenceId, PendingIntent pendingIntent, GeofencingClient geofencingClient) {
Geofence geofence = createGeofence(newTemp, geofenceId);
GeofencingRequest geofencingRequest = createGeofenceRequest(geofence);
geofencingClient.addGeofences(geofencingRequest, pendingIntent)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
success = true;
Log.i(TAG, "onComplete: DEBUG-Message: Geofence has been added.");
} else {
success = false;
Log.i(TAG, "onComplete: Geofence could not be added");
}
}
}); // handle error here
return success;
}
// Create a Geofence
private Geofence createGeofence(GeoTemp geoTemp, String geofenceId) {
long expiration = getExpirationForCurrentGeofence();
if (expiration < 1) {
Log.e(TAG, "createGeofence: Can't create Geofence, since expiration is less than zero");
return null;
}
Log.d(TAG, "createGeofence");
return new Geofence.Builder()
.setRequestId(geofenceId)
.setCircularRegion(getLat(), getLong(), RADIUS)
.setExpirationDuration(expiration)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_DWELL | Geofence.GEOFENCE_TRANSITION_EXIT)
.setLoiteringDelay(LOITERING_IN_MILLISECONDS)
.build();
}
// Create a Geofence Request
private GeofencingRequest createGeofenceRequest(Geofence geofence) {
Log.d(TAG, "createGeofenceRequest");
return new GeofencingRequest.Builder()
.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_DWELL)
.addGeofence(geofence)
.build();
}
}
This POJO Geofences.java is then used by two of my activities:
MainActivity:
public class MainActivity extends AppCompatActivity {
private static String TAG = "MainActivity";
private final int GEOFENCE_REQ_CODE = 0;
private GeofencingClient geofencingClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
geofencingClient = LocationServices.getGeofencingClient(this);
getCurrentTemps();
}
private void refreshGeofence(GeoTemp temp, String id) {
new Geofences().doGeofenceStuff(temp, id, createGeofencePendingIntent(), geofencingClient);
}
private void getCurrentTemps() {
List<GeoTemp> currentGeofences = getUpdatedList();
currentGeofences.forEach(geoTemp -> {
refreshGeofence( geoTemp, id);
});
}
private PendingIntent createGeofencePendingIntent() {
Log.d(TAG, "createGeofencePendingIntent");
Intent intent = new Intent(this, LocationAlertIntentService.class);
return PendingIntent.getService(
this, GEOFENCE_REQ_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}
There is one more activity which uses Geofences.java to register geofences with the operating system.
Update:
I have found out that, if any other app (including mine) requests for location lock, geofence triggers fire. I need them to fire in the background.
I had similar issue when working with geofencing in android.
This happens due to background restrictions added in Android Oreo and later.
OS does not allow your app to start service when it is in background so you won't receive geofence trigger.
To handle this:
Add broadcast receiver to receive intent. (This receiver will get
geofence alert even when app is in background)
Replace service with JobIntentService. (This will use OS JobSchedular
and run even with background restrictions)
Get broadcast from pending intent instead of service.
Checkout this sample project for further clarifications.

Ranging and monitoring stops after a while even with foreground service

I am using altbeacon library to scan for beacons. I am using a android 8.1 OnePlus 3T. The ranging and monitoring stops after 5 minutes even though I am using a foreground service.
I can see an active notification but detection does not work.
This is my code
This is the main application class
#Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
startBeacon();
Notification.Builder builder = new Notification.Builder(this);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentTitle("Scanning for Beacons");
Intent intent = new Intent(this, MainApplication.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT
);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(NotificationChannelId, "Beacons Scanning",
NotificationManager.IMPORTANCE_DEFAULT);
channel.setShowBadge(true);
channel.setSound(null, null);
channel.setLightColor(Color.BLUE);
NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
assert mNotificationManager != null;
mNotificationManager.createNotificationChannel(channel);
builder = new Notification.Builder(this,
NotificationChannelId);
} else {
builder = new Notification.Builder(this);
}
builder.setContentIntent(pendingIntent);
beaconManager.enableForegroundServiceScanning(builder.build(), 456);
beaconManager.setEnableScheduledScanJobs(false);
beaconManager.setBackgroundBetweenScanPeriod(0);
beaconManager.setBackgroundScanPeriod(1100);
Log.d(TAG, "setting up background monitoring for beacons and power saving");
// wake up the app when a beacon is seen
Region region = new Region("backgroundRegion",
null, null, null);
regionBootstrap = new RegionBootstrap(this, region);
backgroundPowerSaver = new BackgroundPowerSaver(this);
Intent MyIntent = new Intent(this, MainActivity.class);
this.startActivity(MyIntent);
}
private void startBeacon() {
beaconManager = BeaconManager.getInstanceForApplication(getApplicationContext());
//BeaconManager.setRegionExitPeriod(5000); //5 seconds
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(ALTBEACON));
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(EDDYSTONE_TLM));
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(EDDYSTONE_UID));
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(EDDYSTONE_URL));
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(IBEACON));
}
#Override
public void didEnterRegion(Region region) {
System.out.println("did enter region");
if (!beaconManager.isBound(this)) {
beaconManager.bind(this);
}
try {
beaconManager.startRangingBeaconsInRegion(new Region("myRangingUniqueId", null, null, null));
} catch (RemoteException e) {
e.printStackTrace();
}
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
getNewandOldBeacons(MainApplication.ListofBeacons, "Entry");
}
}, 1000);
}
#Override
public void didExitRegion(Region region) {
System.out.println("did exit region");
try {
beaconManager.stopRangingBeaconsInRegion(new Region("myRangingUniqueId", null, null, null));
} catch (RemoteException e) {
e.printStackTrace();
}
getNewandOldBeacons(MainApplication.ListofBeacons, "Exit");
if(beaconManager.isBound(this)) {
beaconManager.unbind(this);
}
}
#Override
public void didDetermineStateForRegion(int i, Region region) {
}
#Override
public void onBeaconServiceConnect() {
beaconManager.setRangeNotifier(new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
if (beacons.size() > 0) {
MainApplication.ListofBeacons = beacons;
}
}
});
}
In MainActivity I simply ask for permissions for ACCESS_COURSE_LOCATION and ACCESS_FINE_LOCATION. The app is in React Native, this is the android native code.
Based on logs provided offline, this appears to be caused by a Qualcomm driver or firmware problem in the OnePlus' bluetooth stack. This is shown in the following log excerpt:
10-08 16:01:04.710 22646-22666/? E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 240)
10-08 16:01:04.711 22646-22666/? E/BtGatt.GattService: Exception: android.os.DeadObjectException: Transaction failed on small parcel; remote process probably died
10-08 16:01:04.718 781-781/? I/vendor.qti.bluetooth#1.0-ibs_handler: DeviceWakeUp: Writing IBS_WAKE_IND
Unfortunately, there is probably nothing you can do to prevent this. When the phone gets into this state, you might try turning bluetooth off and back on to see if it clears the condition (this is the equivalent of a 'reset'). If so, then you might be able to use the Android Beacon Library's BluetoothMedic class to automate turning bluetooth off/on when the problem comes up. But this is clearly an imperfect solution at best.

Android Request to server before application compeletly closed

I have just one Activity , when user close the application (from os clear list of recent apps) I want to send a request to my server api and change user status.
so I make IntentService and call it in my onDestroy() method of activity, but it dosn't work. how do it? is there any way else to do this(send request to server before application killed compeletly)?
my code :
Activity:
#Override
protected void onDestroy() {
Intent intent = new Intent(this, MakeOfflineIntentService.class);
intent.putExtra(Variables.INTENT_TOKEN, Token);
intent.setAction("ACTION_MAKE_OFFLINE");
startService(intent);
super.onDestroy();
}
and in my IntentService:
public class MakeOfflineIntentService extends IntentService {
private static final String ACTION_MAKE_OFFLINE = "ACTION_MAKE_OFFLINE";
private static final String EXTRA_TOKEN = Variables.INTENT_TOKEN;
public MakeOfflineIntentService() {
super("MakeOfflineIntentService");
}
public static void startActionFoo(Context context, String param1) {
Intent intent = new Intent(context, MakeOfflineIntentService.class);
intent.setAction(ACTION_MAKE_OFFLINE);
intent.putExtra(EXTRA_TOKEN, param1);
context.startService(intent);
}
#Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_MAKE_OFFLINE.equals(action)) {
final String param1 = intent.getStringExtra(EXTRA_TOKEN);
retrofitBaseInformationChange(param1,Variables.OFFLINE,1);
}
}
}
private void retrofitBaseInformationChange(final String Token, final int online, int vehicle){
RetrofitCallServer retrofitCallServer = new RetrofitCallServer(WebServiceUrls.RETROFIT_INFORMATION_CHEETAH_MAN);
OnCallBackRetrofit onCallBackRetrofit = retrofitCallServer.getResponse();
Call<OBRbaseInfromationChange> call = onCallBackRetrofit.askBaseInformationChange(Token,online,vehicle);
call.enqueue(new Callback<OBRbaseInfromationChange>() {
#Override
public void onResponse(Call<OBRbaseInfromationChange> call, Response<OBRbaseInfromationChange> response) {
/*response gotten maybe success or not*/
if (response.isSuccessful()){
OBRbaseInfromationChange obr = response.body();
if(obr.code == 200){
Log.i(Variables.APP_TAG,"BaseInformationChange successful");
}
else{
Log.i(Variables.APP_TAG,"BaseInformationChange error code: "+obr.code);
}
}// end if response successful
else {
Log.i(Variables.APP_TAG,"BaseInformationChange not Successful: "+response.code());
}
}
#Override
public void onFailure(Call<OBRbaseInfromationChange> call, Throwable t) {
/*our request not sent or conversion problem*/
Log.i(Variables.APP_TAG,"onFailure BaseInformationChange: "+t.getMessage());
}
});
}
// end retrofitBaseInformationChange()
}
and finally here is in my manifest:
<service
android:name=".Services.MakeOfflineIntentService"
android:exported="false"
android:stopWithTask="false"/>
Have you tried to return START_STICKY in the onStartCommand override?
After you sent your request you can then call stopService to stop yourself.
As far as I know, even sticky services might be "recreated" when you kill the app. So maybe, an Intent is not the best way to use here.
I'd go with SharedPreferences here:
The onCreate of your app sets the key "app_offline" to "false"
The onDestroy sets this key to "true" and starts the service
The service is START_STICKY and when it finds the "app_offline" as true, sends its request, updates "app_offline" to false (resets it) and then performs a self-shutdown.
Something like that.
Hope this helps, cheers, Gris
thanks for Grisgram answer, I solve the issue and paste my code here for more complete answer :
I make a variable in SharedPreferences name IS_APP_CLOSED.
when application open in onCreate :
saveL.saveInLocalStorage(Variables.IS_APP_CLOSED,false);
startServiceToMakeOffline();
method startServiceToMakeOffline() is :
private void startServiceToMakeOffline(){
Intent intent= new Intent(this, MakeOfflineService.class);
startService(intent);
}
in onDestroy of this activity :
#Override
protected void onDestroy() {
saveL.saveInLocalStorage(Variables.IS_APP_CLOSED,true);
super.onDestroy();
}
and here is my service class :
public class MakeOfflineService extends Service {
private boolean isAppClosed = false;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
loadInfoFromLocalStorage();
if(isAppClosed){
askServer();
}
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void loadInfoFromLocalStorage() {
SharedPreferences prefs = getApplicationContext().getSharedPreferences(Variables.CHEETAH_NORMAL, 0);
isAppClosed = prefs.getBoolean(Variables.IS_APP_CLOSED, false);
prefs = null;
}
// end loadInfoFromLocalStorage()
private void askServer() {
//TODO: request server than when result gotten:
stopSelf();
}
}
and here is my manifest :
<service
android:name=".Services.MakeOfflineService"
android:stopWithTask="false"/>

EventListener for Power Button press in a Service

I want to listen the power key event in the service.
How can in do that ?
Currently I am working with an app, where I need to listen the power button for some events, from a service which is running in a background, even when the app is killed or stopped.
Somehow I can manage to get it.
But when I kill/stop the app, the service is getting stopped.
How can i overcome this ?
Currently the code i am using this :
Service Class:
public class SampleService extends Service
{
SettingContentObserver mSettingsContentObserver;
AudioManager mAudioManager;
private ComponentName mRemoteControlResponder;
private Intent intent;
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.v("StartServiceAtBoot", "StartAtBootService -- onStartCommand()");
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
#Override
public void onStart(Intent intent, int startId) {
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if (!screenOn) {
Toast.makeText(getApplicationContext(), "On", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Off", Toast.LENGTH_SHORT).show();
}
}
public void onCreate()
{
mSettingsContentObserver = new SettingContentObserver(this,new Handler());
getApplicationContext().getContentResolver().registerContentObserver
(android.provider.Settings.System.CONTENT_URI, true, mSettingsContentObserver );
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mRemoteControlResponder = new ComponentName(getPackageName(),
StartAtBootServiceReceiver.class.getName());
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new StartAtBootServiceReceiver();
registerReceiver(mReceiver, filter);
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
public void onDestroy()
{
getApplicationContext().getContentResolver().unregisterContentObserver(mSettingsContentObserver);
}
}
BroadcastReceiver Class:
public class StartAtBootServiceReceiver extends BroadcastReceiver
{
static boolean wasScreenOn;
private boolean screenOff;
public void onReceive(Context context, Intent intent)
{
if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF))
{
wasScreenOn = false;
Toast.makeText(context, "Power Off", Toast.LENGTH_SHORT).show();
}
else if(intent.getAction().equals(Intent.ACTION_SCREEN_ON))
{
wasScreenOn = true;
}
Intent i = new Intent(context, SampleService.class);
i.putExtra("screen_state", screenOff);
i.setAction("com.example.antitheft.SampleService");
context.startService(i);
//
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Intent i1 = new Intent();
i1.setAction("com.example.sampleonkeylistener.MainActivity");
context.startService(i1);
}
}
}
given above is the sample code and i have created AndroidManifest.xml files also with user's permission but i cannot get the app continue service if it is killed or stopped.
Thanks in Advance.
#Override
public void onDestroy() {
super.onDestroy();
startService(new Intent(this, SampleService.class));
}
This is one way to ensure that service will never stop even user want to destroy it.
This is one Just ONE of ways to achieve what you are trying to achieve.
Secondly, you can try and run service in "foreground" by using startForeground().
Also, make sure that in you return "START_STICKY" (which you are doing in the sample code that you shared and I trust that you are also doing in App's code too :) ) in Services's onStartCommand().
This will ensure that If this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then leave it in the started state but don't retain this delivered intent. Later the system will try to re-create the service.
And you may find some additional pointers/hints to make sure your service is not stopped at below link.
How can we prevent a Service from being killed by OS?
Just pick and choose the approach that best suits YOUR Need/implementation.

Categories