调用 Intent.ACTION_CALL 时出现 ActivityNotFoundException

Posted

技术标签:

【中文标题】调用 Intent.ACTION_CALL 时出现 ActivityNotFoundException【英文标题】:ActivityNotFoundException when calling Intent.ACTION_CALL 【发布时间】:2015-03-24 15:34:27 【问题描述】:

我在执行 Intent.ACTION_CALL 操作时得到ActivityNotFoundException。我找到了很多链接,但都无法解决我的问题。

它有时会给我例外

android.content.ActivityNotFoundException: No Activity found to handle Intent  act=android.intent.action.CALL dat=tel:xxx-xxx-xxxx pkg=com.android.phone (has extras) 

我在我的项目中使用了以下代码

String contact_number="123456789";
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:" + contact_number));
startActivity(callIntent);

【问题讨论】:

ACTION_DIAL 不是正确的吗?我不认为你可以在没有任何用户输入的情况下拨打电话。 您正在拨打该号码 - 如果您已经拥有该号码,您需要什么输入? 我正在从用户输入中获取联系号码,这只是我在问题中使用的一个示例。我无法使用 ACTION_DIAL,因为我需要在不显示拨号的情况下拨打电话 【参考方案1】:

无法保证可以处理给定的意图(即平板电脑可能根本没有电话应用)。如果没有匹配intent-filter 的应用程序,那么您将面对ActivityNotFoundException。正确的做法是意识到这一点并使用try/catch 来阻止崩溃并正确恢复:

try 
   String contact_number="123456789";
   Intent callIntent = new Intent(Intent.ACTION_CALL);
   callIntent.setData(Uri.parse("tel:" + contact_number));
   startActivity(callIntent);
 catch (Exception e) 
   // no activity to handle intent. show error dialog/toast whatever

另外,您应该改用ACTION_DIAL,因为ACTION_CALL 需要额外的权限。

【讨论】:

我不认为使用 try-catch 可以解决我的问题【参考方案2】:

您应该在开始之前检查是否有任何活动处理此意图。如果您的应用在仅具有 wifi 且没有电话功能的平板电脑上运行,则可能会发生这种情况。此外,如果您只打算启动拨号器,最好使用ACTION_DIAL,而不是直接从您的应用程序拨打电话的ACTION_CALL

final Intent dialIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:"));
if (dialIntent.resolveActivity(context.getPackageManager()) != null) 
    // put your logic to launch call app here
  

【讨论】:

我的回答哪一部分是错误的?我没有提到任何关于许可的事情。并且官方文档还推荐 ACTION_DIAL 而不是 ACTION_CALL developer.android.com/reference/android/content/… 我已经获得了权限 我不能使用ACTION_DIAL,因为我需要直接呼叫联系人而不显示拨号。 这个问题出现在 LG Nexus-4 版本 (5.0.1) 而不是平板电脑中 也许您应该尝试设置EXTRA_PHONE_NUMBER 来代替? developer.android.com/reference/android/content/…【参考方案3】:

我已经解决了这个问题。我使用了以下代码

String contact_number="123456789";
Intent callIntent = new Intent(Intent.ACTION_CALL);
intent.setPackage("com.android.phone");
callIntent.setData(Uri.parse("tel:" + contact_number));
startActivity(callIntent);

我已将这一行替换为 Lollipop

intent.setPackage("com.android.phone");

intent.setPackage("com.android.server.telecom");

【讨论】:

先生,如果我想将来自我的应用程序的来电切换到默认系统应用程序怎么办?你知道吗?我正在使用这种方法与“ACTION_ANSWER”但不工作。 用你的代码我得到了错误:没有找到处理意图的活动 act=android.intent.action.CALL dat=tel:xxxxxxxxxx pkg=com.android.phone 【参考方案4】:

这是我的代码。

if (BuildUtil.isAndroidM()) 
        if (ActivityCompat.checkSelfPermission(mActivity,
                Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) 
            ActivityCompat.requestPermissions(mActivity, PermissionUtil.requestPermissionFineAndCoarse(),
                    PHONE_REQUEST_CODE);
        
     else 
        Intent callIntent = new Intent(Intent.ACTION_CALL);
        if (BuildUtil.isAndroidL()) 
            callIntent.setPackage("com.android.server.telecom");
         else 
            callIntent.setPackage("com.android.phone");
        
        callIntent.setData(Uri.parse("tel:" + phone));
        startActivity(callIntent);
    

【讨论】:

以上是关于调用 Intent.ACTION_CALL 时出现 ActivityNotFoundException的主要内容,如果未能解决你的问题,请参考以下文章

Android开发,如何编程实现开启电话的免提功能?

拨打电话号码

如何挂断Android中的拨出电话?

如何从后台服务拨打电话?

如何在 Kotlin 中正确拨打电话意图?

Android 拨号器