在Android Studio中按下按钮后无法拨打电话 [英] Can't dial a phone on the event of a button press in Android Studio

查看:167
本文介绍了在Android Studio中按下按钮后无法拨打电话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

解决方案

我知道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

活动操作:拨打数据指定的号码.这显示了一个正在拨打电话的用户界面,允许用户明确发起呼叫

正确的答案是:

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

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

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

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

如何打开拨号器android中具有选定号码的手机

意图调用操作不适用于棉花糖

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

希望对您有帮助.

In my android app, I have a navigation drawer with a few buttons that open different fragments with associated layouts.

One of the buttons is supposed to call a function which in theory should perform a phone dial. It just doesn't seem to work. Nothing happens, and the navigation drawer just closes. I already implemented this permission in the manifest, which should do the work for the sake of permissions:

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

My code that executes pieces of code based on the button events in the navigation drawer looks like this:

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

And last but not least, the function the performs the phone call looks like this; I must point out that it threw an error if I didn't check if the package manager had granted access to perform the phone call. That is why the code checks if permission is granted:

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

解决方案

I know that Amiars answer works, but it's not really the correct answer.

The thing is: you don't need any permission for Intent.ACTION_DIAL. You need the permission CALL_PHONE to use Intent.ACTION_CALL.

The difference is that ACTION_CALL actually executes the call, which is somewhat dangerous as it normally incur fees/charges for the user, while ACTION_DIAL only opens the dialer and the user will explicitly complete the action by pressing the call button. It's all in the docs: https://developer.android.com/reference/android/content/Intent.html

ACTION_CALL

Activity Action: Perform a call to someone (...)

Note: there will be restrictions on which applications can initiate a call; most applications should use the ACTION_DIAL.

Note: if you app targets M and above and declares as using the CALL_PHONE permission which is not granted, then attempting to use this action will result in a SecurityException.

and

ACTION_DIAL

Activity Action: Dial a number as specified by the data. This shows a UI with the number being dialed, allowing the user to explicitly initiate the call

So the right answer is:

remove that if have permission and just directly invoke the startActivity(i);

edit:

I just typed that on latest AndroidStudio without any permission on manifest and it works as it should. No warning, and executing on device it opens the dialer.

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

I can also point you to several other SO questions that are asking the same thing:

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

I hope it helps.

这篇关于在Android Studio中按下按钮后无法拨打电话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆