【问题标题】:Should app check if device has calling functionality when using ACTION_DIAL intent?应用程序在使用 ACTION_DIAL 意图时是否应该检查设备是否具有呼叫功能?
【发布时间】:2015-01-15 20:25:09
【问题描述】:

我的程序中有以下代码:

  public static void callPhoneNumber(Context context, String clientPhoneNum) {

    if (isCallingSupported(context)) {
      Intent i = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + clientPhoneNum));
      context.startActivity(i);
    } else {
      final AlertDialog alertDialog =
          new AlertDialog.Builder(context).setMessage(context.getString(R.string.error))
              .setMessage(context.getString(R.string.no_call_functionality))
              .setPositiveButton(context.getString(R.string.ok),
                  new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                      dialog.dismiss();
                    }
                  })

              .create();

      alertDialog.show();
    }
  }

  private static boolean isCallingSupported(Context context) {
    TelephonyManager telephonyManager =
        (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

    return (telephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE);
  }

我想知道isCallingSupported() 是否有必要?我不记得我为什么要这样写,但现在当我回顾时,我想用户可能只是使用他的 Skype 或其他 VOIP 应用程序拨打一个号码。我应该做任何其他检查,还是在没有isCallingSupported() 的情况下这个意图是安全的(我的意思是,即使用户的平板电脑没有呼叫功能并且没有其他可以处理呼叫的应用程序,意图不导致崩溃)?

【问题讨论】:

    标签: android android-intent


    【解决方案1】:

    使用 Robin 的出色回答,我在 RunUtilities 类中创建了一个助手:

    class RunUtilities {
    
        companion object {
    
            fun canMakeCalls(context: Context): Boolean {
                val intent = Intent(Intent.ACTION_DIAL)
                val infos = context.packageManager.queryIntentActivities(intent, 0)
                return infos.size > 0
            }
        }
    }
    

    示例用法:

    if (!RunUtilities.canMakeCalls(this)) {
        callButton.visibility = View.GONE
    }
    

    (我对 Kotlin 还很陌生,所以欢迎任何指点)

    【讨论】:

      【解决方案2】:

      来自this问题:

      PackageManager manager = context.getPackageManager();
      List<ResolveInfo> infos = manager.queryIntentActivities(intent, 0);
      if (infos.size() > 0) {
             //Then there is application can handle your intent
      }else{
             //No Application can handle your intent
      }
      

      首先检查是否有任何应用已注册到此 Intent。如果他们有,请使用它。如果没有,请显示您的对话框。

      你最终会用上面的代码替换你的 isCallingSupported 函数:

      private static boolean isCallingSupported(Context context) {
      
          boolean result = true;
          PackageManager manager = context.getPackageManager();
          List<ResolveInfo> infos = manager.queryIntentActivities(intent, 0);
          if (infos.size() <= 0) {
              result = false;
          }
          return result;
      

      }

      【讨论】:

      • 做了类似的事情return (pm.queryIntentActivities(dialIntent, 0).size() &gt; 0);
      • 是的,这完全一样:)
      【解决方案3】:

      我会使用PackageManagerresolveActivity() 来查看是否有任何东西会响应您配置的ACTION_DIAL Intent。这将处理:

      • 没有本地电话和拨号器的设备,如resolveActivity() 应返回null

      • 没有本地电话但有拨号器(例如 VOIP)的设备,希望该拨号器的作者有 ACTION_DIAL 支持

      • 确实具有本机电话但当前用户无权访问拨号器的设备(例如,受限配置文件)

      【讨论】:

      • 这是来自 commonsware 博客的好读物 :) - commonsware.com/blog/2011/02/25/…
      • @ShivamVerma: hasSystemFeature() 和 kin 用于检查没有 Intent 的情况,例如确定 SmsManager 是否能够发送短信。
      • 谢谢马克,由于其他用户的代表较低,我选择接受他的回答,但您的回答同样有价值。
      • 我刚刚在仅支持 wifi 的三星平板电脑上测试了这个问题中描述的解决方案。奇怪的是,com.android.contacts 是由 queryIntentActivities() 返回的。如果我单击设备上 Html 页面中的 tel: url,系统会询问我是否要将电话号码添加到我的联系人中。有没有办法过滤掉它,只找到真正可以拨打电话的东西?
      • @MichaelLevy:你可以使用hasSystemFeature(PackageManager.FEATURE_TELEPHONY)。或者,您可以尝试ACTION_CALL 而不是ACTION_DIAL——虽然您需要CALL_PHONE 权限才能实际使用IntentstartActivity(),但您应该能够在未经许可的情况下使用queryIntentActivities()
      猜你喜欢
      • 2021-12-26
      • 1970-01-01
      • 1970-01-01
      • 2021-11-13
      • 1970-01-01
      • 2013-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多