循环时处理动作NEW_OUTGOING_CALL的正确方法是什么?

and*_*dev 9 android

目前我正在开发一个应用程序,它NEW_OUTGOING_CALL可以在a的帮助下捕获动作BroadcastReceiver.我正在通过电话中止呼叫setResultData(null).之后,我向用户显示一个对话框,允许他决定是否要使用我的应用程序重写其编号.当用户决定发生时,我将根据决定发出新呼叫.现在我的广播接收器再次被召唤.

了解我已经处理过该号码的正确方法是什么?我得到了一个工作解决方案,它使用时间戳来猜测它是否已经被处理过.另一种解决方案是"+"在处理后的数字的末尾添加a .这些方法适用于我的应用程序是唯一一个捕获NEW_OUTGOING_CALL事件.但是,当其他应用程序(如Sipdroid或Google Voice)也坐在那里捕获NEW_OUTGOING_CALL广播中止并重新启动它时,我该怎么办?我没有看到是否有可能知道我们是否仍在同一个"呼叫流程"并且我已经处理了这个号码.

我很想听听你对这个问题的看法!

Sco*_*cot 2

您正在使用什么 API 级别?如果它 >= 11,请查看新的 BroadcastReceiver.goAsync 函数,该函数可让您将广播处理扩展到接收器的 onReceive 函数之外。这可以完全绕过循环的需要。

如果你像我一样在 11 级之前被困在尝试这样做,那么优雅地做到这一点是非常棘手的。您可能也这样做了,但我尝试在我的代码生成的 ACTION_CALL 意图中包含一个“已处理”标志作为额外内容,希望它能以某种方式包含在生成的 ACTION_NEW_OUTGOING_CALL 广播中,但遗憾的是这不起作用。

我能找到的最佳解决方案是在 URI 中包含您生成的 ACTION_CALL 意图的片段。此片段将包含在生成的 ACTION_NEW_OUTGOING_CALL 广播中,因此您的广播接收器可以区分原始调用和您生成的调用,但它不会干扰不寻找它的处理程序。

这是基本代码。

在 ACTION_NEW_OUTGOING_CALL 的 BroadcastReceiver 中

public class YourBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // extract the fragment from the URI
        String uriFragment = Uri.parse(
            intent.getStringExtra("android.phone.extra.ORIGINAL_URI")).getFragment();

        // if the fragment is missing or does not have your flag, it is new
        if (uriFragment == null || !uriFragment.contains("your_flag")) {

            // launch your activity, pass the phone number, etc.
            // use getResultData to get the number in order to respect
            // earlier broadcast receivers
            ...

            // abort the broadcast
            this.setResultData(null);
            this.abortBroadcast();
        }
        // otherwise, your code is there, this call was triggered by you
        else {
            // unless you have a special need, you'll probably just let the broadcast
            // go through here

            // note that resultData ignores the fragment, so other receivers should
            // be blissfully unaware of it
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当用户第一次拨打号码时,片段将完全丢失,或者您的标志将不存在,因此您将中止广播并开始您的活动。在您的活动中,如果您决定再次拨打电话,请执行以下操作:

startActivity(new Intent(Intent.ACTION_CALL,
                         Uri.parse("tel:" + modified_number + "#your_flag")));
Run Code Online (Sandbox Code Playgroud)

然后,“your_flag”片段将出现在后续的 NEW_OUTGOING_CALL 广播中,从而允许您在广播接收器中以不同的方式处理这种情况。

这样做的好处是,除非您在 ORIGINAL_URI 中查找该片段,否则该片段将被完全忽略,因此其他广播接收器可以继续运行。如果您想变得非常友善,您可能需要查找现有片段并向其添加您的标志(可能使用逗号分隔符)。

我希望这有帮助。祝你好运!