9

My project requires an android foreground service to run continuously (even after the application is destroyed). To this effect I have the following code snippets:

build.gradle

implementation fileTree(dir: 'libs', include: ['*.jar'])
//noinspection GradleCompatible
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:design:28.0.0'
implementation 'com.google.android.gms:play-services-maps:16.1.0'
implementation 'com.google.android.gms:play-services-places:16.0.0'
implementation 'com.google.android.libraries.places:places:1.1.0'
implementation 'com.google.android.gms:play-services-location:16.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.google.android.gms:play-services-ads:17.2.0'

Manifest permissions

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

MainActivity.java

@Override
public void onCreate() {
    Intent intent = new Intent(getApplicationContext(), MyService.class);
    if (!isMyServiceRunning(MyService.class, MainActivity.this)) {
        intent.setAction(MYConstants.ACTION_START_GPS_SERVICE);
        intent.setAction(MyConstants.ACTION_START_GPS_SERVICE);
        startService(intent);
        Log.i(TAG, "MyService call made.");
    }
}

MyService.java

public class MyService extends Service {
       @Override
       public void onCreate() {
           super.onCreate();
           if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
               startServiceWithNotification();
           } else{
               startForeground(9999, new Notification());
           }
       }

       @Override
       public int onStartCommand(Intent intent, int flags, int startId) {
            super.onStartCommand(intent, flags, startId);
            return START_STICKY;
       }

       @Override
       public void onTaskRemoved(Intent rootIntent){
          stopMyService();
          Intent broadcastIntent = new Intent(this, MyBroadcastReceiver.class);
          sendBroadcast(broadcastIntent);
       }

       @Override
       public void onDestroy() {
           stopMyService();
           super.onDestroy();
      }

      @Override
      public IBinder onBind(Intent intent) {
           // Used only in case of bound services.
           return null;
     }

     void stopMyService() {
          stopForeground(true);
          stopSelf();
     }

     @RequiresApi(Build.VERSION_CODES.O)
     void startServiceWithNotification() {
        String channelId = "com.mypackage.myapp";
        String channelName = "Your Service";

        NotificationChannel chan;

        chan = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_NONE);
        chan.setLightColor(Color.BLUE);
        chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
        NotificationManager mNotificationManager = (NotificationManager) 
               getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.createNotificationChannel(chan);


        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, 
              channelId);

        Notification notification = notificationBuilder.setOngoing(true)
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setContentTitle("App is running in background")
            .setPriority(NotificationManager.IMPORTANCE_MIN)
            .setCategory(Notification.CATEGORY_SERVICE)
            .build();
        startForeground(10000, notification);
    }
}

MyBroadcastReceiver.java

@Override
public void onReceive(Context context, Intent intent) {
    Intent intent =  new Intent(context, MyService.class);
    intent.setAction(MYConstants.ACTION_START_GPS_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        context.startForegroundService(intent);
        Log.i(TAG, "MyService call made.");
    } else {
        context.startService(intent);
    }
}

This Application is working as expected, the foreground service runs fine doing what it is intended to do even after the app is destroyed, but I consistently see a Warning as an IllegalArgumentException while running the application. The exception is attached below:

D/EGL_emulation: eglMakeCurrent: 0xdda12a20: ver 3 0 (tinfo 0xdda81230)
W/System: A resource failed to call close. 
W/ConnectionTracker: Exception thrown while unbinding
   java.lang.IllegalArgumentException: Service not registered: ll@85f600c
       at android.app.LoadedApk.forgetServiceDispatcher(LoadedApk.java:1731)
       at android.app.ContextImpl.unbindService(ContextImpl.java:1755)
       at android.content.ContextWrapper.unbindService(ContextWrapper.java:735)
       at ce.b(:com.google.android.gms.dynamite_measurementdynamite@201817068@20.18.17 (100700-0):1)
       at ce.a(:com.google.android.gms.dynamite_measurementdynamite@201817068@20.18.17 (100700-0):5)
       at lm.A(:com.google.android.gms.dynamite_measurementdynamite@201817068@20.18.17 (100700-0):10)
       at kx.a(:com.google.android.gms.dynamite_measurementdynamite@201817068@20.18.17 (100700-0):3)
       at dx.run(:com.google.android.gms.dynamite_measurementdynamite@201817068@20.18.17 (100700- 
          0):2)
       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
       at java.util.concurrent.FutureTask.run(FutureTask.java:266)
       at iv.run(:com.google.android.gms.dynamite_measurementdynamite@201817068@20.18.17 (100700- 
         0):15)
 W/.myapp: Reducing the number of considered missed Gc histogram windows from 186 to 100
 W/System: A resource failed to call close. 

Can someone help me out in understanding why this exception is consistently being thrown and how can I resolve this??

mang4521
  • 742
  • 6
  • 22
  • 2
    That does not seem to be coming from your code and does not seem to have much to do with your app. Are you using Play Services libraries? – CommonsWare Jun 05 '20 at 14:35
  • @CommonsWare , I am utilizing android **GPS_SERVICE** (not sure if this is considered to be a Play Service) and I have updated all the Permissions I currently am making use of in my manifest file. Would this information help (I honestly am quite new to Android programming)? – mang4521 Jun 05 '20 at 14:54
  • "not sure if this is considered to be a Play Service" -- no. In your module's `build.gradle` file, if you have dependencies that are in the `com.google.android.gms` group, you are using Play Services. Or, you might have dependencies from others that are in turn using Play Services dependencies. – CommonsWare Jun 05 '20 at 14:57
  • @CommonsWare I have updated my gradle dependencies and as mentioned by you, I did find a couple of **com.google.android.gms** dependencies. How do I go about fixing this? I was of the assumption that **com.google.android.gms** dependencies were necessary to use the system GPS_SERVICE. – mang4521 Jun 05 '20 at 15:08
  • If by `GPS_SERVICE`, you are referring to `LocationManager`, you do not need Play Services for that. Search your Java code for `import` statements referring to classes whose fully-qualified names start with `com.google`. Those are from Play Services. – CommonsWare Jun 05 '20 at 15:18
  • @CommonsWare Yes, these are some of the imports that I currently am making us of: _import com.google.android.gms.location.FusedLocationProviderClient; import com.google.android.gms.location.LocationAvailability;_ This is used to access LOCATION info and is quite an important component of my project. Is there a way to avoid these exceptions and continue using Play services?? – mang4521 Jun 05 '20 at 16:52
  • 1
    Play Services logs stuff all the time, including a lot of internal exceptions that they handle. Unless your app is crashing, I would not worry about them. – CommonsWare Jun 05 '20 at 16:59
  • My app is working as expected without any crashes. With what you have suggested, I can proceed with nothing to worry about. Thanks a lot for your help and your patience @CommonsWare, appreciate it. – mang4521 Jun 05 '20 at 17:05
  • See also https://stackoverflow.com/questions/63047174/adding-an-admob-causes-an-error-that-does-not-exist-error-java-lang-illegalar – caw Nov 13 '20 at 19:21
  • I am a simple person - I see an answer by @CommonsWare and I just do it – nibbana Dec 09 '20 at 16:16

1 Answers1

11

As suggested by @CommonsWare in the comments above, the exceptions observed here are being logged by Play Services which is quite common and isn't a consequence of the application. Unless the exceptions are causing serious problems (such as the app crashing), such exceptions must not be considered as a pain point.

mang4521
  • 742
  • 6
  • 22