一、為什麼需要動態申請許可權?
在Android移動設備上,許可權是一項非常重要的安全特性。應用需要獲得用戶授權才能訪問特定的設備功能或用戶信息。根據不同的功能,許可權可分為正常許可權和危險許可權兩種。
正常許可權通常是指運行應用所必需的許可權,如訪問網路狀態等。這些許可權會在安裝應用時自動授予,用戶不需要進行確認。
而危險許可權則是指對用戶個人信息和設備重要功能進行訪問的許可權,比如讀取聯繫人、讀取簡訊等。這些許可權需要用戶明確授權才能使用。Android 6.0(API 23)引入了動態許可權模型,允許用戶在應用運行時動態地授權這些危險許可權。
使用動態許可權申請,能保護用戶隱私安全,提高應用用戶友好度,避免用戶對應用的不信任感,增加用戶與應用的互動,提高應用的用戶活躍度,從而提高應用評分和推廣度。
二、如何執行動態申請許可權
Android雖然提供了許可權管理,但是某些應用運行時可能需要並未在manifest文件中包含的新許可權,因此需要動態申請許可權。
如下是一個運用動態許可權申請的應用示例,其實現為讓用戶在使用應用期間打開相機並捕捉照片的功能。
public class MainActivity extends AppCompatActivity { private static final int REQUEST_CAMERA_PERMISSION = 1; private static final int REQUEST_CAMERA = 2; private Camera mCamera; private boolean hasCameraPermission() { // Check if the Camera permission has been granted return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED; } private void requestCameraPermission() { // Request the Camera permission if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) { new ConfirmationDialog().show(getFragmentManager(), FRAGMENT_DIALOG); } else { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION); } } private void requestCamera() { // Request to launch the Camera Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, REQUEST_CAMERA); } @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button = findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (hasCameraPermission()) { requestCamera(); } else { requestCameraPermission(); } } }); // Open the camera when the app is launched if (hasCameraPermission()) { requestCamera(); } else { requestCameraPermission(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { case REQUEST_CAMERA_PERMISSION: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { requestCamera(); } else { Toast.makeText(this, "You need to grant permission to use the camera", Toast.LENGTH_SHORT).show(); } break; } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case REQUEST_CAMERA: if (resultCode == RESULT_OK) { // Save the captured image Bundle bundle = data.getExtras(); Bitmap bitmap = (Bitmap) bundle.get("data"); ImageView imageView = findViewById(R.id.image_view); imageView.setImageBitmap(bitmap); } break; } } public static class ConfirmationDialog extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { final Fragment parent = getParentFragment(); return new AlertDialog.Builder(getActivity()) .setMessage("Need permission to use the camera") .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { FragmentCompat.requestPermissions(parent, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION); } }) .setNegativeButton(android.R.string.cancel, null) .create(); } } }
上述代碼中,首先定義了應用所需的危險許可權「CAMERA」和requestCode,然後使用hasCameraPermission()判斷是否獲得授權。如果未獲得許可權,則使用requestCameraPermission()方法向系統發出許可權請求,如果已獲得授權,則使用requestCamera()方法請求打開相機。
當用戶按下拍照按鈕後,onActivityResult()會接收請求的結果。如果結果是OK,表示照片已捕捉到。否則,用戶可能取消了該動作或者出現了問題。
三、優化動態申請許可權的用戶體驗
儘管動態許可權申請提升了應用的用戶體驗,但是在用戶授權的途中,用戶可能會遇到多次重複授權的問題,這會降低用戶對應用的滿意度。為了緩解用戶對彈出請求的強烈反感及讓用戶更好的理解對應用所需授權的必要性,我們可以採取如下幾種方式來優化用戶體驗。
1. 顯示完整的證明
為了更好地避免用戶對應用的不信任感,設備令生產商和廠商提供了「應用設置」中關於應用所需許可權的描述。為了提高用戶對許可權描述的理解和透明度,我們可以在彈出框中顯示完整的證明。
public class MainActivity extends AppCompatActivity { private void requestCameraPermission() { // Request the Camera permission if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) { // Explain to the user why we need permission Snackbar.make(findViewById(android.R.id.content), "Need permission to use the camera for taking pictures", Snackbar.LENGTH_LONG).setAction("OK", new View.OnClickListener() { @Override public void onClick(View v) { ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION); } }).show(); } else { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION); } } }
上述代碼中,使用Snackbar進行證明說明,將對話框內容從簡單的「A「更新為有用的描述。同時,添加了一個」OK」按鈕來開始授權請求。
2. 在請求過程中展示進度
當系統請求許可權時,等待是不可避免的。但是,我們可以在會話過程中顯示一個進度條,以便用戶有時間了解發生了什麼。
public class MainActivity extends AppCompatActivity { private ProgressDialog mProgressDialog; private void requestCameraPermission() { // Show a progress bar while the app requests permission if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) { // Explain to the user why we need permission showCameraPermissionExplanation(); } else { showProgressBar(); ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION); } } private void showProgressBar() { mProgressDialog = new ProgressDialog(this); mProgressDialog.setMessage("Requesting permission"); mProgressDialog.setCancelable(false); mProgressDialog.setIndeterminate(true); mProgressDialog.show(); } private void cancelProgressBar() { mProgressDialog.cancel(); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); cancelProgressBar(); switch (requestCode) { case REQUEST_CAMERA_PERMISSION: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { requestCamera(); } else { Toast.makeText(this, "You need to grant permission to use the camera", Toast.LENGTH_SHORT).show(); } break; } } }
上述代碼中,使用ProgressDialog來顯示進度條。在permission請求結束後,使用cancelProgressBar()方法取消進度條,展示授權請求結果。同時,在onRequestPermissionsResult()中使用cancelProgressBar()取消進度條。
3. 向用戶解釋為什麼需要特定的許可權
當用戶拒絕授權時,可以向用戶展示為什麼需要該許可權,以便幫助解釋需要的原因。
public class MainActivity extends AppCompatActivity { private void requestCameraPermission() { // Request the Camera permission if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) { // Explain to the user why we need permission showCameraPermissionExplanation(); } else { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION); } } private void showCameraPermissionExplanation() { new AlertDialog.Builder(this).setTitle("Need permission to use the camera").setMessage("This app needs the camera permission in order to take pictures.").setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION); } }).setNegativeButton("Cancel", null) .show(); } }
上述代碼中,在shouldShowRequestPermissionRationale()返回true時,首先創建一個AlertDialog以向用戶解釋為什麼需要許可權,然後提供一個「OK」按鈕,以便用戶開始授權請求。
四、總結
採用動態許可權申請方式,可以保護用戶隱私安全,提高應用用戶友好度,避免用戶對應用的不信任感,增加用戶與應用的互動,提高應用的用戶活躍度,
從而提高應用評分和推廣度。優化動態許可權申請的用戶體驗,能緩解用戶對彈出請求的反感,提高用戶對應用的滿意度。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/232085.html