4

Applications targeting Android O have a couple of new rules when using services, one of them is that we can't start services while the application is in background.

One of the requirements to be a default SMS application is: (from the Telephony.java javadoc)

* <li>In a service, include an intent filter for {@link
* android.telephony.TelephonyManager#ACTION_RESPOND_VIA_MESSAGE}
* (<code>"android.intent.action.RESPOND_VIA_MESSAGE"</code>) with schemas,
* <code>sms:</code>, <code>smsto:</code>, <code>mms:</code>, and <code>mmsto:</code>.
* This service must also require the {@link
* android.Manifest.permission#SEND_RESPOND_VIA_MESSAGE} permission.
* <p>This allows users to respond to incoming phone calls with an immediate text message
* using your app.</p></li>
* </ul>

You can see my problem... because ACTION_RESPOND_VIA_MESSAGE needs a service with permission SEND_RESPOND_VIA_MESSAGE if we receive a phone call while the application is in background and the user rejects the call with a text message the service will fail to start.

1237-6018 W/Binder: Binder call failed.
                    java.lang.IllegalStateException: Not allowed to start service Intent { act=android.intent.action.RESPOND_VIA_MESSAGE dat=smsto:xxxxxxxxx cmp=APP_PACKAGE_NAME (has extras) }: app is in background uid null

Any idea how to fix this issue?

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
duffyduck
  • 91
  • 5
  • 1
    As [docs](https://developer.android.com/about/versions/oreo/background.html) say, you should now start a [foreground](https://developer.android.com/reference/android/content/Context.html#startForegroundService(android.content.Intent)) service. – M. Prokhorov Jan 11 '18 at 11:01
  • I'm not the one that starts the service, is the native phone app. Are you saying that the native phone app should call startForegroundService? That actually makes sense. In that case there is nothing to do on my side except wait for the phone app to update there code to match the latest android oreo guidelines. – duffyduck Jan 11 '18 at 12:29
  • I was initially under the impression that it's your app that tries to start the service. Native phone app is not the subject to changes you are talking about, because at the time when user might choose to answer with an SMS, the phone app is supposed to be in foreground. At which point your app should also be considered a foreground app, because it falls under `Another foreground app is connected to the app, either by binding to one of its services or by making use of one of its content providers`. So, what does actually happen? – M. Prokhorov Jan 11 '18 at 12:35
  • Again, what you are saying makes sense. The complete use case is, i'm the default sms app, my app is running in background (no services / tasks running), i receive a native call and answer with a message. Looking at logs i can see that the system is trying to start my service but it's failing with java.lang.IllegalStateException: Not allowed to start service Intent { ... }: app is in background uid null (note that my app doesn't crash). I'm starting to think this maybe a device issue, i'm using a OnePlus 3 – duffyduck Jan 11 '18 at 13:09
  • Can you test with another device? Or an emulator? You could send the same intent from test app. – M. Prokhorov Jan 11 '18 at 15:01
  • observed that `microsoft sms organizer` is working fine even after this limitation, whereas some other apps are not. – Rahul Tiwari Nov 28 '18 at 14:06

1 Answers1

1

This shouldn't be the case with stock android, as default implementation does not call SMS App to reject calls with message and usage SmsManager instead.

reference from RespondViaSmsManager.java in AOSP oreo

/**
 * Reject the call with the specified message. If message is null this call is ignored.
 */
private void rejectCallWithMessage(Context context, String phoneNumber, String textMessage,
                                   int subId, String contactName) {
    if (TextUtils.isEmpty(textMessage)) {
        Log.w(RespondViaSmsManager.this, "Couldn't send SMS message: empty text message. ");
        return;
    }
    if (!SubscriptionManager.isValidSubscriptionId(subId)) {
        Log.w(RespondViaSmsManager.this, "Couldn't send SMS message: Invalid SubId: " +
                subId);
        return;
    }

    SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(subId);
    try {
        smsManager.sendTextMessage(phoneNumber, null, textMessage, null /*sentIntent*/,
                null /*deliveryIntent*/);

        SomeArgs args = SomeArgs.obtain();
        args.arg1 = !TextUtils.isEmpty(contactName) ? contactName : phoneNumber;
        args.arg2 = context;
        mHandler.obtainMessage(MSG_SHOW_SENT_TOAST, args).sendToTarget();
    } catch (IllegalArgumentException e) {
        Log.w(RespondViaSmsManager.this, "Couldn't send SMS message: " +
                e.getMessage());
    }
}

seems like some oems (I have experianced this with oneplus) customized this and kept older behaviour which requires starting the service of SMS app. without keeping in mind that there are limatations in oreo with respect to background services.

following are a few complaints:

  1. https://www.reddit.com/r/oneplus/comments/8n9w37/cant_send_text_message_when_rejecting_phone_call/
  2. https://forums.oneplus.com/threads/reject-call-with-sms-is-not-working-after-oreo-update-oxygen-5-0-1-3t.817578/

I have experianced this behaviour on most of the SMS apps, including Messages from google on oneplus 5 with android version 8.1

This still doesn't explain how OEM provided sms app or SMS Organizer from microsoft works for this use case on same device.

Rahul Tiwari
  • 6,851
  • 3
  • 49
  • 78