在 Android 6.0 之後,有了新的 permission model, 安裝 App 的權限可以不用在 Google Play 安裝的時侯就授權。而是等到使用者要使用這個功能的時侯,再詢問使用者。而權限分成兩種: normal permission 跟 dangerous permission 兩種。 normal permission 可以直接在 AndroidManifest.xml 直接定義,不會詢問使用者就可以直接取得權限,像是android.permission.INTERNET
權限就屬於此類,主要是跟使用者的隱私比較無關的功能。如果想使用權限是屬於那一類的話,可以參考這個清單。
檢查權限
首先都要先檢查是否有這個權限:
ContextCompat.checkSelfPermission(Context context, String permission)
例如,檢查是否有寫入行事曆的權限
ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR);
回傳值有兩種可能: PERMISSION_GRANTED(0)
和 PERMISSION_DENIED(-1)
範例程式1: 請求單一權限
private static final int REQUEST_PERMISSION = 1;
private boolean checkPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
final String permission = Manifest.permission.PERMISSION_YOU_WANT;
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
if (shouldShowRequestPermissionRationale(permission)) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("We need you to grant permission");
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@TargetApi(Build.VERSION_CODES.M)
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(new String[]{permission}, REQUEST_PERMISSION);
}
});
} else {
requestPermissions(new String[]{permission}, REQUEST_PERMISSION);
}
return false;
}
}
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Has permission Todo
} else {
// No permission
}
}
}
範例程式2: 請求多個權限
private boolean checkPermissions(Context context, String... permissions) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null) {
for (final String permission : permissions) {
int requestCode = 0;
if (permission.equals(android.Manifest.permission.USE_SIP)) {
requestCode = REQUEST_SIP_PERMISSION;
} else if (permission.equals(android.Manifest.permission.RECORD_AUDIO)) {
requestCode = REQUEST_RECORD_AUDIO_PERMISSION;
}
if (context.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "checkPermissions: requestCode" + requestCode);
requestPermissions(new String[]{permission}, requestCode);
}
}
}
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_SIP_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Has permission Todo
} else {
// No permission
final String permission = android.Manifest.permission.USE_SIP;
if (shouldShowRequestPermissionRationale(permission)) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setMessage("We need you to grant SIP permission");
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@TargetApi(Build.VERSION_CODES.M)
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(new String[]{permission}, REQUEST_SIP_PERMISSION);
}
});
builder.show();
}
}
}
if (requestCode == REQUEST_RECORD_AUDIO_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Has permission Todo
} else {
// No permission
final String permission = android.Manifest.permission.RECORD_AUDIO;
if (shouldShowRequestPermissionRationale(permission)) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setMessage("We need you to grant audio record permission");
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@TargetApi(Build.VERSION_CODES.M)
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(new String[]{permission}, REQUEST_SIP_PERMISSION);
}
});
builder.show();
}
}
}
}
有了這個權限架構可以更保護使用者的隱私,不用讓使用者在一開始安裝 App 就必須答應所有的權限要求。