【问题标题】:Can't dial a phone on the event of a button press in Android Studio在 Android Studio 中按下按钮时无法拨打电话
【发布时间】:2017-04-16 10:16:20
【问题描述】:

在我的 android 应用程序中,我有一个导航抽屉,其中有几个按钮可以打开具有相关布局的不同片段。

其中一个按钮应该调用理论上应该执行电话拨号的功能。它似乎不起作用。什么都没有发生,导航抽屉刚刚关闭。我已经在清单中实现了这个权限,它应该为了权限而工作:

<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>

根据导航抽屉中的按钮事件执行代码片段的代码如下所示:

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    int id = item.getItemId();
    android.app.FragmentManager fragmentmanager = getFragmentManager();

    if (id == R.id.nav_forside) {
        fragmentmanager.beginTransaction()
                .replace(R.id.content_frame
                        , new MainFragment())
                .commit();

    } else if (id == R.id.nav_matif) {
        fragmentmanager.beginTransaction()
                .replace(R.id.content_frame
                        , new MatifFragment())
                .commit();

    } else if (id == R.id.nav_om) {
        fragmentmanager.beginTransaction()
                .replace(R.id.content_frame
                        , new OmFragment())
                .commit();

    } else if (id == R.id.nav_rk) {
        fragmentmanager.beginTransaction()
                .replace(R.id.content_frame
                        , new RkFragment())
                .commit();

    } else if (id == R.id.nav_bd) {
        fragmentmanager.beginTransaction()
                .replace(R.id.content_frame
                        , new BdFragment())
                .commit();

    } else if (id == R.id.nav_rf) {
        fragmentmanager.beginTransaction()
                .replace(R.id.content_frame
                        , new RfFragment())
                .commit();

    } else if (id == R.id.nav_kontakt_os) {
        fragmentmanager.beginTransaction()
                .replace(R.id.content_frame
                        , new KontaktOsFragment())
                .commit();

    } else if (id == R.id.nav_call_number) {
    callNumber();

    }

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

最后但并非最不重要的一点是,执行电话呼叫的功能如下所示;我必须指出,如果我没有检查包管理器是否已授予执行电话呼叫的访问权限,它会引发错误。这就是代码检查是否授予权限的原因:

public void callNumber () {
            //Tries to call the phone number, and catches any errors that might be present
            try {
                //Checking if the the permission to call a phone is granted
                if (ActivityCompat.checkSelfPermission(MainActivity.this.getApplicationContext(), Manifest.permission.CALL_PHONE) ==
                        PackageManager.PERMISSION_GRANTED) {

                    Intent i = new Intent(Intent.ACTION_DIAL);
                    String p = "tel:12345678";
                    i.setData(Uri.parse(p));
                    startActivity(i);
                }
            } catch (Exception exLog) {
                //Catches error that prevents phone from calling, and expresses itself in form of a alertdialog
                AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
                alertDialog.setTitle("Opkaldet kunne ikke gennemføres");
                alertDialog.setMessage(exLog.toString());
                alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.dismiss();
                            }
                        });
                alertDialog.show();
            }
        }

【问题讨论】:

  • 你的问题到底是什么?更加详细一些。你得到了什么错误?实际发生了什么?
  • @IspasClaudiu 我在第四行文字中是否说过:什么都没有发生,就像根本没有调用任何函数一样。
  • 从设置->应用管理器->你的应用中检查实际应用的权限。您可能必须手动授予权限。
  • 对于ACTION_DIAL,您不需要CALL_PHONE 权限。

标签: java android phone-call


【解决方案1】:

我知道 Amiars 的答案有效,但它并不是真正的正确答案。

问题是:Intent.ACTION_DIAL 不需要任何权限。 您需要CALL_PHONE 的权限才能使用Intent.ACTION_CALL

不同之处在于ACTION_CALL实际执行调用,这有点危险,因为它通常会为用户产生费用/收费,而ACTION_DIAL仅打开拨号器,用户将通过按下调用显式完成操作按钮。这一切都在文档中:https://developer.android.com/reference/android/content/Intent.html

ACTION_CALL

活动操作:给某人打电话 (...)

注意:哪些应用可以发起呼叫会有限制;大多数应用程序应该使用 ACTION_DIAL

注意:如果您的应用针对 M 及以上版本并声明使用未授予的 CALL_PHONE 权限,则尝试使用此操作将导致 SecurityException。

ACTION_DIAL

活动操作:拨打数据指定的号码。这显示了一个带有正在拨打的号码的 UI,允许用户明确发起呼叫

所以正确答案是:

去掉if有权限,直接调用startActivity(i);

编辑:

我只是在最新的 AndroidStudio 上输入了该内容,而没有任何清单上的许可,它可以正常工作。没有警告,在设备上执行它会打开拨号器。

 public static void call(Context context, String number) {
    Intent i = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + number));
    try {
      context.startActivity(i);
    } catch (Exception e) {
      // this can happen if the device can't make phone calls
      // for example, a tablet
    }
  }

我还可以向您指出其他几个提出相同问题的 SO 问题:

How do I get the dialer to open with phone number displayed?

Permission required when using Intent to call phone?

How to open dialer on phone with a selected number in android

Intent call action doesn't works on Marshmallow

https://stackoverflow.com/a/13123613/906362

希望对你有帮助。

【讨论】:

  • 就目前而言,我调用电话的代码是埃米尔代码的精确复制品。它不执行呼叫,它只打开拨号器。如果我删除 if 语句,我将无法编译我的代码,因为我收到一个错误,告诉我检查是否授予访问权限。
  • 您的答案与描述的一样有效,并且似乎比阿米尔的答案更完善,因此我会将您的答案标记为正确的。
【解决方案2】:

如果未授予权限怎么办?

在棉花糖之后的新版本的android中,您需要像以前一样检查代码中的权限,但如果未授予权限,则需要请求权限。因为对于这个版本的 android,manifest 中的权限不起作用。

if (ActivityCompat.checkSelfPermission(MainActivity.this.getApplicationContext(), Manifest.permission.CALL_PHONE) ==
                    PackageManager.PERMISSION_GRANTED) {

                Intent i = new Intent(Intent.ACTION_DIAL);
                String p = "tel:12345678";
                i.setData(Uri.parse(p));
                startActivity(i);
}
else
{
  ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CALL_PHONE}, 0);
}

您还可以在您的活动中对授予的案例权限进行回调,如下所示:

@Override
public void onRequestPermissionsResult(int requestCode,
                                   String permissions[], int[] grantResults) 
{
  if(requestCode==0 && ActivityCompat.checkSelfPermission(MainActivity.this.getApplicationContext(), Manifest.permission.CALL_PHONE) ==
                PackageManager.PERMISSION_GRANTED) {
   Intent i = new Intent(Intent.ACTION_DIAL);
                String p = "tel:12345678";
                i.setData(Uri.parse(p));
                startActivity(i);
   }
}

【讨论】:

  • 在请求权限的行中将“activity”替换为“this”后,终于成功了!我不能感谢你!
猜你喜欢
  • 1970-01-01
  • 2017-11-21
  • 2017-08-12
  • 1970-01-01
  • 2011-07-21
  • 2016-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多