首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >循环时处理动作NEW_OUTGOING_CALL的正确方法是什么?

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

Stack Overflow用户
提问于 2010-07-14 13:42:00
回答 4查看 1.9K关注 0票数 9

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

知道我已经处理了号码的正确方法是什么?我得到了一个有效的解决方案,它使用时间戳来猜测它是否已经被处理。另一种解决方案是在处理的数字的末尾添加一个"+"。对于我的应用程序来说,这些方法工作得很好,因为我的应用程序是唯一捕获NEW_OUTGOING_CALL事件的应用程序。但是,当其他应用程序(如Sipdroid或Google Voice)也在那里捕捉NEW_OUTGOING_CALL广播,中止并重新启动它时,我该怎么办?我不认为有可能知道我们是否仍然处于相同的“呼叫流程”中,以及我是否已经处理了号码。

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

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-06-21 02:16:43

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

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

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

这是基本的代码。

在ACTION_NEW_OUTGOING_CALL的BroadcastReceiver中

代码语言:javascript
复制
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
        }
    }
}

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

代码语言:javascript
复制
startActivity(new Intent(Intent.ACTION_CALL,
                         Uri.parse("tel:" + modified_number + "#your_flag")));

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

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

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

票数 2
EN

Stack Overflow用户

发布于 2010-09-19 16:48:26

我不认为有可能知道我们是否仍然处于相同的“呼叫流程”中,以及我是否已经处理了号码。

从技术上讲,你不在同一个“调用流”中,因为发出一个新的调用是异步的。您必须使用提示(例如时间戳),因为您似乎已经在这样做了。

如果您确信除了更改前缀或添加后缀之外,其他应用程序不会重写数字,那么您可能希望添加另一个“接近检查”提示,以避免误报/漏报,但恐怕这就是您所能做的全部。

票数 1
EN

Stack Overflow用户

发布于 2013-08-13 16:29:12

广播接收器中的onReceive()方法接收一个Intent作为参数。使用Intent.getExtras()从Intent中提取包。此捆绑包包含3个键值对,如下所示:

  1. android.phone.extra.ALREADY_CALLED = null
  2. android.intent.extra.PHONE_NUMBER = 98xxxxxx98
  3. android.phone.extra.ORIGINAL_URI = tel:98xxxxxx98

98xxxxx98是用户拨打的号码。

当再次调用onReceive()时,此数字将更改为98xxxxxx98**。通过检查拨号号码末尾的星号(*),可以推断是第一次调用onReceive()方法,还是下次调用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3243635

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档