在 Android Studio 中按下按钮时无法拨打 phone
Can't dial a phone on the event of a button press in Android Studio
在我的 android 应用程序中,我有一个带有几个按钮的导航抽屉,这些按钮可以打开具有相关布局的不同片段。
其中一个按钮应该调用理论上应该执行 phone 拨号的功能。它似乎不起作用。没有任何反应,导航抽屉就关闭了。我已经在清单中实现了这个权限,它应该为了权限而工作:
<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;
}
最后但同样重要的是,执行 phone 调用的函数如下所示;我必须指出,如果我没有检查包管理器是否已授予执行 phone 调用的访问权限,它会引发错误。这就是代码检查是否授予权限的原因:
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();
}
}
没有权限怎么办?
在 marshmallow 之后的新版本 android 中,您需要像以前一样检查代码中的权限,但如果未获得权限,则需要请求权限。因为对于此版本的 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);
}
您还可以在您的 activity 中获得案例许可的回调,如下所示:
@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);
}
}
我知道 Amiars 的答案有效,但这并不是真正正确的答案。
问题是:您不需要 Intent.ACTION_DIAL
的任何许可。
您需要权限 CALL_PHONE
才能使用 Intent.ACTION_CALL
。
不同的是ACTION_CALL
实际执行调用,这有点危险,因为它通常会对用户产生fees/charges,而ACTION_DIAL
只是打开拨号器,用户将通过按下呼叫按钮明确完成操作。全部在文档中: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.
和
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
所以正确答案是:
去掉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?
希望对您有所帮助。
在我的 android 应用程序中,我有一个带有几个按钮的导航抽屉,这些按钮可以打开具有相关布局的不同片段。
其中一个按钮应该调用理论上应该执行 phone 拨号的功能。它似乎不起作用。没有任何反应,导航抽屉就关闭了。我已经在清单中实现了这个权限,它应该为了权限而工作:
<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;
}
最后但同样重要的是,执行 phone 调用的函数如下所示;我必须指出,如果我没有检查包管理器是否已授予执行 phone 调用的访问权限,它会引发错误。这就是代码检查是否授予权限的原因:
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();
}
}
没有权限怎么办?
在 marshmallow 之后的新版本 android 中,您需要像以前一样检查代码中的权限,但如果未获得权限,则需要请求权限。因为对于此版本的 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);
}
您还可以在您的 activity 中获得案例许可的回调,如下所示:
@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);
}
}
我知道 Amiars 的答案有效,但这并不是真正正确的答案。
问题是:您不需要 Intent.ACTION_DIAL
的任何许可。
您需要权限 CALL_PHONE
才能使用 Intent.ACTION_CALL
。
不同的是ACTION_CALL
实际执行调用,这有点危险,因为它通常会对用户产生fees/charges,而ACTION_DIAL
只是打开拨号器,用户将通过按下呼叫按钮明确完成操作。全部在文档中: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.
和
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
所以正确答案是:
去掉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?
希望对您有所帮助。