当前位置: 首页 > 知识库问答 >
问题:

在 Android Studio 中按下按钮时无法拨打电话

凌声
2023-03-14

在我的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();
            }
        }

共有2个答案

金泉
2023-03-14

如果不授予许可怎么办?

在Marshmallow之后的新版本的android中,您需要像以前一样检查代码中的权限,但如果不授予权限,则需要请求权限。cuz对于这个版本的android,清单中的权限不起作用。

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);
   }
}
郗欣嘉
2023-03-14

我知道阿米尔的答案可行,但它并不是真正的正确答案。

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

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

行动_呼叫

活动操作:执行对某人的呼叫 (...)

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

注意:如果您的应用程序以 M 及以上为目标,并声明使用未授予的CALL_PHONE权限,则尝试使用此操作将导致 SecurityException。

ACTION_DIAL

活动操作:拨打数据指定的号码。这将显示一个包含所拨打号码的 UI,允许用户显式发起呼叫

所以正确的答案是:

如果拥有权限,则将其删除,只需直接调用 startActivity(i);

编辑:

我刚刚在最新的AndroidStudio上输入了这个,没有任何关于manifest的许可,它就像它应该的那样工作。没有警告,并在设备上执行它打开拨号器。

 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
    }
  }

我还可以向你指出其他几个S问题,这些问题也问了同样的事情:

如何让拨号器打开并显示电话号码?

使用Intent拨打电话时需要权限?

如何在android中使用选定的号码在手机上打开拨号器

意向呼叫操作在Marshmallow上不起作用

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

我希望它能有所帮助。

 类似资料:
  • 问题内容: 我在这方面是一个初学者,因此我正在努力使它起作用。 当按下按钮时,我只是希望拨号器以自动输入的指定号码打开。 到目前为止,我已经尝试了以下方法: 我也尝试过: 我已将权限ACTION_CALL添加到清单中。 每当我单击“呼叫”按钮时,应用程序强制关闭。 任何帮助将不胜感激。 谢谢! 问题答案: 您需要将此权限添加到清单中。

  • 问题内容: 下面的代码正确返回该单元格: 但是在表视图中查找indexpath会崩溃: 我尝试了另一种方法,但是没有成功: 问题答案: 我不知道是否有简单的方法可以做到这一点。( 编辑: 实际上有。请查看@mustafa的第二个解决方案。)一种解决方法是将按钮的标签设置为in ,然后可以仅访问按钮的标签以找出按钮所属的行。 警告: 此解决方法很脆弱。如果您允许在不调用的情况下从表中添加或删除行,则

  • 我是新的Android和试图研发应用程序快速帮助。一旦用户双击电源按钮,我希望我的应用程序为两种情况直接呼叫救护车(屏幕打开/关闭)。我已经写了这段代码,但它不起作用。任何帮助将不胜感激。提前谢谢你。:) Android显示 我的电话服务。JAVA MyReceiver.java 主要活动。JAVA

  • 我以编程方式生成了许多按钮(一些按钮用于增加值,而另一些按钮用于减少值),当它们调整的值达到最大值或最小值时,我会禁用这些按钮。(即,当达到最大值时,“增加”按钮被禁用,而当达到最小值时,“减少”按钮被禁用。)除了禁用,我还将按钮状态设置为“按下”,以直观地指示已达到极限值,并且按钮不再工作。 我的按钮onClickListener的'增加'按钮看起来像这样: ClickListeners上相应的

  • 我已经用远程视图定制了一个通知,视图包含布局和两个按钮,我想要的是当用户点击一个名为“contentLayout”的布局时,活动“Test”将被打开,当用户点击按钮,“remindTenMinButton”或“remindLaterButton”时,操作“Test2”将启动。现在的问题是活动“Test”启动正确,但对于活动“Test2”,当我单击通知栏中的按钮时,似乎什么都没有发生,但当我单击“b

  • 问题内容: 我希望我的应用程序中的按钮样式在按下时可以更改。做这个的最好方式是什么? 问题答案: 使用。 这里是一个例子: