Android打电话功能权限报错,从打电话权限报错看Android6.0权限变化
引言:去年Android?6.0發(fā)布后,其新引入的(Requesting Permissions at Run Time)運行時權(quán)限就備受開發(fā)者關(guān)注,隨著今年國內(nèi)手機廠商對6.0系統(tǒng)的普及,覺得大家有必要了解下這個新特性,因為在TargetSDK23+進(jìn)行開發(fā)不注意這些會造成APP運行在6.0+手機上崩潰,這篇博文將對這個新特性進(jìn)行探索。
在之前的SDK開發(fā)中,如果需要用到一些權(quán)限例如打電話,發(fā)短信只在AndroidManifest中配置一下就可以了,但是SDK23+以上用到一些危險敏感(Dangerous Permissions)權(quán)限就不僅僅是在AndroidManifest配置一下就可以了,需要在操作發(fā)生前需要讓用戶進(jìn)行授予權(quán)限才能進(jìn)行下一步的操作,跟iOS的權(quán)限處理很像,如果沒讓用戶授予權(quán)限或用戶拒絕了此權(quán)限再進(jìn)行操作例如打電話就會造成軟件崩潰。
*如果你的app TargetSDK設(shè)置在了23以下那么在6.0+系統(tǒng)中運行是不會崩潰的,當(dāng)然你也可以TargetSDK一直設(shè)置在23以下,那么這篇文章你就沒必要繼續(xù)看了:)
那么到底哪些權(quán)限需要進(jìn)行在運行時進(jìn)行授權(quán)呢?看下官方的說明
Dangerous permissions
以上這些權(quán)限不僅僅需要在AndroidManifest配置,還需要在運行時讓用戶進(jìn)行授予權(quán)限才能使用這些功能。
可以看到打電話是需要進(jìn)行運行時授權(quán)的,我們就做個點擊按鈕打電話的小demo,看看這個運行時權(quán)限到底怎么回事。
1:需要將APP的targetSdkVersion設(shè)置到23以上并且在Android6.0以上系統(tǒng)運行
2:在AndroidManifest中配置撥打電話的權(quán)限
1
1
3:在布局layout中我們就簡簡單單放個按鈕,點擊進(jìn)行撥打電話(略)
4.1:如果不做運行時權(quán)限處理會怎么樣呢?我們直接進(jìn)行點擊按鈕撥打電話
1
2
3
4
5
6
1
2
3
4
5
6public void CallPhone(View v) {
Intent intent = new Intent(Intent.ACTION_CALL);
Uri data = Uri.parse("tel:" + "10010");
intent.setData(data);
startActivity(intent);
}
運行效果:
可以看到在android 6.0系統(tǒng)上運行會崩潰
4.2:我們加上運行時權(quán)限的處理再運行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19private static final int REQUESTCODE = 8;
public void CallPhone(View v) {
//檢查權(quán)限
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.CALL_PHONE)
!= PackageManager.PERMISSION_GRANTED) {
//沒有權(quán)限,申請權(quán)限
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CALL_PHONE},
REQUESTCODE);
} else {
//已經(jīng)擁有權(quán)限進(jìn)行撥打
call();
}
}
API:? REQUESTCODE的作用是為了進(jìn)行回調(diào)處理,因為申請權(quán)限是有回調(diào)結(jié)果的后面會說到。
ContextCompat.checkSelfPermission?主要用于檢測某個權(quán)限是否已經(jīng)被授予,方法參數(shù)為(context,需要檢測的權(quán)限)方法返回值為PackageManager.PERMISSION_DENIED或者PackageManager.PERMISSION_GRANTED,當(dāng)返回PackageManager.PERMISSION_DENIED時需要調(diào)用API進(jìn)行權(quán)限申請。
ActivityCompat.requestPermissions用于權(quán)限的申請,方法參數(shù)為(context,需要申請的權(quán)限數(shù)組,自定義的請求碼),系統(tǒng)會彈出一個申請權(quán)限的對話框。
運行效果:
可以看到程序已經(jīng)成功進(jìn)行了電話的撥打。
4.3 但是如果用戶拒絕了此權(quán)限并且設(shè)置了不再提醒怎么辦呢?點擊按鈕就會沒響應(yīng)了,是非常不友好的,如下。
稍稍改下代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36public void CallPhone(View v) {
//檢查權(quán)限
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.CALL_PHONE)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CALL_PHONE)) {
new AlertDialog.Builder(MainActivity.this)
.setMessage("app需要開啟權(quán)限才能使用此功能")
.setPositiveButton("設(shè)置", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
}
})
.setNegativeButton("取消", null)
.create()
.show();
} else {
//申請權(quán)限
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CALL_PHONE},
REQUESTCODE);
}
} else {
//已經(jīng)擁有權(quán)限進(jìn)行撥打
call();
}
}
這里我們在申請權(quán)限前加了個判斷ActivityCompat.shouldShowRequestPermissionRationale(this,? Manifest.permission.CALL_PHONE)方法參數(shù)為(context,需要檢測的權(quán)限)如果返回true證明用戶上次點擊已經(jīng)選了拒絕,所以我們進(jìn)行一些友好的提示,這里做的是進(jìn)行進(jìn)行提示并讓用戶跳轉(zhuǎn)到設(shè)置將權(quán)限打開。
運行效果:
5:OK 最后介紹下,申請權(quán)限的回調(diào)方法處理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case REQUESTCODE: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//用戶同意了授權(quán)
call();
} else {
//用戶拒絕了授權(quán)
// Toast.makeText(MainActivity.this, "Permission Denied", Toast.LENGTH_SHORT).show();
}
return;
}
}
}
這個方法跟onActivityResult比較類似,先判斷requestCode,之后在判斷用戶的授權(quán)狀態(tài),grantResults數(shù)組代表了權(quán)限的結(jié)果數(shù)組,有點繞口,哈哈,之前申請權(quán)限是支持?jǐn)?shù)組的,所以 onRequestPermissionsResult的返回結(jié)果也放到了一個數(shù)組里面,數(shù)組grantResults[n] == PackageManager.PERMISSION_GRANTED代表這個權(quán)限已經(jīng)被用戶授權(quán)了。
final:最后我們看下完整的代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81/** * blog:www.lijizhou.com */
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private static final int REQUESTCODE = 8;
public void CallPhone(View v) {
//檢查權(quán)限
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.CALL_PHONE)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CALL_PHONE)) {
new AlertDialog.Builder(MainActivity.this)
.setMessage("app需要開啟權(quán)限才能使用此功能")
.setPositiveButton("設(shè)置", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
}
})
.setNegativeButton("取消", null)
.create()
.show();
} else {
//申請權(quán)限
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CALL_PHONE},
REQUESTCODE);
}
} else {
//已經(jīng)擁有權(quán)限進(jìn)行撥打
call();
}
}
private void call() {
Intent intent = new Intent(Intent.ACTION_CALL);
Uri data = Uri.parse("tel:" + "10010");
intent.setData(data);
startActivity(intent);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case REQUESTCODE: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//用戶同意了授權(quán)
call();
} else {
//用戶拒絕了授權(quán)
// Toast.makeText(MainActivity.this, "Permission Denied", Toast.LENGTH_SHORT).show();
}
return;
}
}
}
}
OK,一個利用android原始API進(jìn)行的運行時權(quán)限處理就介紹完了,當(dāng)然你也可以對此進(jìn)行封裝方便使用,歡迎大家在下方留言,本篇源碼下載地址?http://download.csdn.net/detail/leejizhou/9532629
最后如果只是調(diào)起打電話功能,其實谷歌是推薦采用 intent.setAction(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:"+ phone)); 這樣將跳到電話撥打界面,而不是直接調(diào)起打電話。
總結(jié)
以上是生活随笔為你收集整理的Android打电话功能权限报错,从打电话权限报错看Android6.0权限变化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 余承东亲自曝真机:华为P60和Mate
- 下一篇: android o 跨进程广播,[And