【问题标题】:Oreo, default SMS App and ACTION_RESPOND_VIA_MESSAGEOreo,默认短信应用和 ACTION_RESPOND_VIA_MESSAGE
【发布时间】:2018-01-11 10:45:09
【问题描述】:

针对 Android O 的应用程序在使用服务时有一些新规则,其中之一是我们不能在应用程序处于后台时启动服务。

成为默认 SMS 应用程序的要求之一是:(来自 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>

您可以看到我的问题...因为 ACTION_RESPOND_VIA_MESSAGE 需要具有 SEND_RESPOND_VIA_MESSAGE 权限的服务,如果我们在应用程序处于后台时接到电话并且用户使用短信拒绝呼叫,该服务将无法启动。

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

知道如何解决这个问题吗?

【问题讨论】:

  • 正如docs 所说,您现在应该启动foreground 服务。
  • 我不是启动服务的人,是本机手机应用程序。你是说本机手机应用程序应该调用 startForegroundService 吗?这实际上是有道理的。在这种情况下,除了等待手机应用程序更新代码以匹配最新的 android oreo 指南之外,我无事可做。
  • 我最初的印象是,尝试启动服务的是您的应用程序。本机电话应用程序不受您所说的更改的影响,因为在用户可能选择使用短信回答时,电话应用程序应该处于前台。此时您的应用程序也应该被视为前台应用程序,因为它属于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。那么,实际发生了什么?
  • 再一次,你说的很有道理。完整的用例是,我是默认的短信应用程序,我的应用程序在后台运行(没有运行服务/任务),我收到一个本地呼叫并回复一条消息。查看日志我可以看到系统正在尝试启动我的服务,但它失败了 java.lang.IllegalStateException: Not allowed to start service Intent { ... }: app is in background uid null (注意我的应用程序没有' t 崩溃)。我开始认为这可能是设备问题,我使用的是 OnePlus 3
  • 你能用其他设备测试吗?还是模拟器?您可以从测试应用发送相同的意图。

标签: java android android-intent service android-intentservice


【解决方案1】:

这不应该是股票 android 的情况,因为默认实现不会调用 SMS 应用程序来拒绝使用消息和使用 SmsManager 的呼叫。

来自RespondViaSmsManager.java 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());
    }
}

似乎一些 OEM(我曾使用 oneplus 体验过)对此进行了定制并保留了需要启动 SMS 应用服务的旧行为。没有记住oreo 中存在关于后台服务的限制。

以下是一些抱怨:

  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/

我在大多数 SMS 应用程序上都经历过这种行为,包括来自 google 的Messages on oneplus 5 with android version 8.1

这仍然没有解释 OEM 提供的短信应用程序或来自微软的SMS Organizer 如何在同一设备上用于此用例。

【讨论】:

    猜你喜欢
    • 2016-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-03
    • 2015-08-10
    相关资源
    最近更新 更多