2

In our app we have a Service defined in this way

<service
    android:name="ServiceName"
    android:exported="false" />

When Activity's onCreate() is called, app starts this Service. And everything is fine, until it is moved to background for a long time. After moving app to foreground onCreate() is called again, and app tries to start Service but gets an error:

Caused by: java.lang.SecurityException: Not allowed to start service Intent { act=action_name cmp=app_bundle/service_name } without permission not exported from uid 10156

App crashes and after restart everything works again. I really can't get what is going wrong. Looks like Activity is started with new uid, but tries to interact with Service from another process with another uid (????).

Crash reproduces only on Asus phone, Android 6.0.0.

Onik
  • 19,396
  • 14
  • 68
  • 91
Ufkoku
  • 2,384
  • 20
  • 44

2 Answers2

1

Looks like Activity is started with new uid, but tries to interact with Service from another process with another uid (????)

I believe you've answered own question.

And everything is fine, until it is moved to background for a long time.

During the "long time" your app's process (with uid 10XXX assigned) that started the Service at first place could have been killed by the system. Your Service probably returned START_STICKY or a similar flag from its onStartCommand(), so when the app process was killed the Service started within a new process, with another uid assigned by the system.

Then, when you bring your app back to foreground, it runs within a brand new process (meaning with another uid assigned by the system). Within one of Activity's onCreate() you start the Service that has android:exported="false" and, since this time it is called from within another uid, a SecurityException is thrown (such a behavior might be your Asus-phone-specific only - I recommend to check the behavior with phones from other vendors).

Onik
  • 19,396
  • 14
  • 68
  • 91
-1

You should add a check if the service is already running in onCreate() so you won't have double entries for your service. This exception is caused by it I suppose.

One of the ways to check

I use the following from inside an activity:

private boolean isMyServiceRunning(Class<?> serviceClass) {
    ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (serviceClass.getName().equals(service.service.getClassName())) {
            return true;
        }
    }
    return false;
}

And I call it using:

isMyServiceRunning(MyService.class)

Src

Rainmaker
  • 10,294
  • 9
  • 54
  • 89
  • I will check it. But if you try to start a service, which is running, it will just handle an intent inside onStartCommand. I guess the problem here with android:exported="false", but it shouldn't exist. – Ufkoku Feb 22 '18 at 22:07