Java 从 Android 版本 Marshmallow 开始,如何请求允许从 Android 拨打电话?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40125931/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to ask permission to make phone call from Android from Android version Marshmallow onwards?
提问by OBX
I am trying to make a phone call from Android, and I've set run time permissions as well. And it asks whether to allow making phone calls. But when I press allow, the app crashes:
我正在尝试从 Android 拨打电话,并且我也设置了运行时权限。它询问是否允许拨打电话。但是当我按下允许时,应用程序崩溃了:
This is how I implemented it:
我是这样实现的:
private static final int REQUEST_PHONE_CALL = 1;
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + "+918511812660"));
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CALL_PHONE},REQUEST_PHONE_CALL);
}
else
{
startActivity(intent);
}
}
else
{
startActivity(intent);
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_PHONE_CALL: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startActivity(intent);
}
else
{
}
return;
}
}
}
This is what I obtain in logcat:
这是我在 logcat 中获得的:
java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:,
request=1, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }}
to activity {com.devpost.airway/com.devpost.airway.activities.MainActivity}:
java.lang.NullPointerException: Attempt to invoke virtual method
'java.lang.String android.content.Intent.toString()' on a null object reference
at android.app.ActivityThread.deliverResults(ActivityThread.java:3733)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3776)
at android.app.ActivityThread.-wrap16(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1412)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5461)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method
'java.lang.String android.content.Intent.toString()' on a null object reference
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1485)
at android.app.Activity.startActivityForResult(Activity.java:3930)
at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:48)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:75)
at android.app.Activity.startActivityForResult(Activity.java:3890)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:856)
at android.app.Activity.startActivity(Activity.java:4213)
at android.app.Activity.startActivity(Activity.java:4181)
at com.devpost.airway.activities.MainActivity.onRequestPermissionsResult(MainActivity.java:140)
at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:6582)
at android.app.Activity.dispatchActivityResult(Activity.java:6460)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3729)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3776)
at android.app.ActivityThread.-wrap16(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1412)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5461)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
What is possibly causing this?
什么可能导致这种情况?
采纳答案by Fabian Tamp
The stack trace seems to indicate that your permissions flow is working ok, but the call to startActivity
from onRequestPermissionsResult()
is crashing. Is the Intent
you're passing to startActivity
set correctly? I can't see it being set in that part of the code.
堆栈跟踪似乎表明您的权限流工作正常,但对startActivity
from的调用onRequestPermissionsResult()
正在崩溃。是Intent
你传递到startActivity
设置是否正确?我看不到它被设置在代码的那部分。
Note also that ContextCompat.checkSelfPermission
handles the SDK version checking on your behalf, so you should be able to use
另请注意,它ContextCompat.checkSelfPermission
代表您处理 SDK 版本检查,因此您应该能够使用
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CALL_PHONE},REQUEST_PHONE_CALL);
}
else
{
startActivity(intent);
}
by itself, without the wrapping SDK version check code.
本身,没有包装 SDK 版本检查代码。
回答by Ganesh Pokale
add new method
添加新方法
public static boolean hasPermissions(Context context, String... permissions) {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
add this in Global
在全局中添加这个
int PERMISSION_ALL = 1;
String[] PERMISSIONS = {Manifest.permission.READ_CONTACTS, Manifest.permission.CALL_PHONE};
and write below code in onCreate
并在 onCreate 中编写以下代码
if(!hasPermissions(this, PERMISSIONS)){
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
}
回答by himanshu1496
Change your onRequestPermissionsResult
to below, you basically need to create the intent
first and then call it on permission granted. That's where you are doing it wrong.
将您更改onRequestPermissionsResult
为下面,您基本上需要创建第intent
一个,然后在授予权限时调用它。那就是你做错的地方。
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_PHONE_CALL : {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + "+918511812660"));
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
startActivity(intent);
}
}
}
}
}
回答by Tin Tran
You need to create your Intent
in onRequestPermissionsResult
你需要创建你Intent
的onRequestPermissionsResult
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_PHONE_CALL: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + "+918511812660"));
startActivity(intent);
}
else
{
}
return;
}
}
}
回答by Abhishek Luthra
I would better suggest to use ACTION_DIAL rather than ACTION_CALL while constructing Intent to call a particular number . Using ACTION_DIAL , you will need no call permissions in your app, as ACTION_DIAL opens the dialer with the number already entered, and further allows the user to decide whether to actually make the call or modify the phone number before calling or not call at all.
我建议在构建 Intent 以呼叫特定号码时使用 ACTION_DIAL 而不是 ACTION_CALL 。使用 ACTION_DIAL ,您将不需要您的应用程序中的呼叫权限,因为 ACTION_DIAL 使用已经输入的号码打开拨号器,并进一步允许用户决定是否在呼叫之前实际拨打电话或修改电话号码或根本不拨打电话。
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + "Your Phone_number"));// Initiates the Intent
startActivity(intent);