Request App Permissions
在執行時期取得權限,是自 Marshmallow(6.0, API23) 加入的功能,為使用者提供更多保護;回想一下,您在安裝 APP 時,會仔細看 APP 要求取得哪些權限嗎?自 Android6.0(含) 起,在 APP 第一次執行時,會提示使用者,您的 APP 需要取得哪些權限,並必須得使用者允許。
所以在 Android6.0(含) 以上的裝置,如果沒有撰寫相關的程式碼,為 APP 執行時期取得權限,嚴重時甚至 APP 會 crash 掉!
AndroidManifest.xml (宣告 APP 必須取得的權限)
<!-- 要求取得相機權限 --> <uses-permission android:name="android.permission.CAMERA"/> ... ... <application ... ...
編輯 build.gradle(Module: app)
dependencies { ... ... implementation 'com.android.support:design:27.1.1' // Snackbar 需要 }
activity_main.xml (記得要給 layout ID,不然 Snackbar 不會顯示)
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main_layout" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="開啟相機" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" android:onClick="showCameraPreview"/> </android.support.constraint.ConstraintLayout>
Mainactivity.java
public class MainActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback { private static final int PERMISSION_REQUEST_CAMERA = 0; private View mLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mLayout = findViewById(R.id.main_layout); } public void showCameraPreview(View v) { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { Snackbar.make(mLayout, "已取得相機權限, 開始預覽", Snackbar.LENGTH_SHORT).show(); startCamera(); } else { requestCameraPermission(); } } private void startCamera() { // 開啟相機, 在此寫您自己的程式 } private void requestCameraPermission() { if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) { Snackbar.make(mLayout, "需要取得相機權限", Snackbar.LENGTH_INDEFINITE) .setAction("OK", new View.OnClickListener() { @Override public void onClick(View view) { ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, PERMISSION_REQUEST_CAMERA); } }) .show(); } else { Snackbar.make(mLayout, "無法開啟相機,可能有其他 APP 正在使用中 或 本 APP 尚未取得授權", Snackbar.LENGTH_SHORT).show(); ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, PERMISSION_REQUEST_CAMERA); } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == PERMISSION_REQUEST_CAMERA) { if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Snackbar.make(mLayout, "已取得相機權限, 開始預覽", Snackbar.LENGTH_SHORT) .show(); startCamera(); } else { Snackbar.make(mLayout, "請求相機權限被拒", Snackbar.LENGTH_SHORT) .show(); } } } }
APP 安裝到實體裝置後,先關閉不執行,到 Android 的 "設定" 進一步觀察:
安裝在 KitKat4.4(API19),就已經取得權限
安裝在 Oreo8.0(API26),尚未取得權限
執行 APP,點擊 "開啟相機" 鈕,會出現請求授權的畫面
選取 "拒絕",就會跳出 "請求相機權限被拒" 的 Snackbar
再按一次 "開啟相機",這次 Snackbar 會提示您 APP 需要取得相機權限,選取 "OK"
打勾 "不要再詢問",並再次拒絕
這麼一來,就再也不會出現請求授權的畫面了,只能到 "設定" → 應用程式與通知 → 應用程式資訊 → 找到 APP → 點擊 "權限" 去手動開啟授權
或是將 APP 移除再重新安裝了
若是在 請求授權畫面選擇 "允許" 或 手動進 "設定" 開啟授權 後,執行 APP 點擊 "開啟相機" 鈕,就會跳出已取得授權的 Snackbar
相關筆記 ----
Snackbar -- 比 Toast 更多功能的 跳出式訊息