بهتره یکم دیدتون رو اصلاح کنم. توی اندروید 6 به بعد
تمام مجوزها باید در زمان اجرا گرفته بشن. درواقع مجوزها باید در زمانی که کار قراره انجام بشه گرفته بشن نه در لحظهی نصب و هردفعه هم باید چک بشن چون کاربر این اجازه رو داره که مجوز رو از برنامه بعد از نصب بگیره (درصورت تمایل). منتها مجوزها به دو دستهی معمولی و خطرناک تقسیم شدن. مجوزهای معمولی اینها هستن:
- ACCESS_LOCATION_EXTRA_COMMANDS
- ACCESS_NETWORK_STATE
- ACCESS_NOTIFICATION_POLICY
- ACCESS_WIFI_STATE
- BLUETOOTH
- BLUETOOTH_ADMIN
- BROADCAST_STICKY
- CHANGE_NETWORK_STATE
- CHANGE_WIFI_MULTICAST_STATE
- CHANGE_WIFI_STATE
- DISABLE_KEYGUARD
- EXPAND_STATUS_BAR
- GET_PACKAGE_SIZE
- INSTALL_SHORTCUT
- INTERNET
- KILL_BACKGROUND_PROCESSES
- MODIFY_AUDIO_SETTINGS
- NFC
- READ_SYNC_SETTINGS
- READ_SYNC_STATS
- RECEIVE_BOOT_COMPLETED
- REORDER_TASKS
- REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
- REQUEST_INSTALL_PACKAGES
- SET_ALARM
- SET_TIME_ZONE
- SET_WALLPAPER
- SET_WALLPAPER_HINTS
- TRANSMIT_IR
- UNINSTALL_SHORTCUT
- USE_FINGERPRINT
- VIBRATE
- WAKE_LOCK
- WRITE_SYNC_SETTINGS
همونطور که میبینید، خیلی از مجوزها معمولی هستن و مجوزهایی که توی این فهرست نیستن جزو مجوزهای خطرناک محسوب میشن. معنای مجوز معمولی اینه که خطری برای حریم خصوصی یا امنیت کاربر ایجاد نمیشه اگه یه برنامه، اون مجوزها رو داشته باشه. برای مثال کاربران دوست دارن بدونن که دقیقاً چهموقع یه برنامه اطلاعات Contactهای اونها رو میخونه. بنابراین باید این مجوز رو بصورت دستی بدن. درمقابل خطر خاصی توی مجوز لرزش دستگاه نیست، پس این مجوز معمولی حساب میشه.
اگه یه برنامه، مجوزهای معمولی رو توی مانیفست خودش معرفی کرده باشه، همون موقع نصب بهش داده میشه و کاربر هم نمیتونه ازش بگیره ولی مجوزهای خطرناک ازطریق پیغام به کاربر در لحظهی نیاز گرفته میشن و بعد از دادن مجوز هم درصورتی که کاربر نظرش عوض شد میتونه دوباره مجوز رو بگیره. پس هردفعه باید قبل از انجام کار، چک کنید که برنامه هنوز هم مجوز رو داره یا نه.
چطور مجوز رو در زمان اجرا بررسی کنیم؟
برای مثال میخوایم مجوز READ_PHONE_STATE رو بررسی کنیم. برای اینکار از متد ContextCompat.checkSelfPermission استفاده میکنیم. مثال:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
// Request Permission Here
}
پارامترهای این متد، شئ اکتیویتی جاری، و مجوز موردنظره.
چطور مجوز رو درصورتی که نداشته باشیم، درخواست کنیم؟
برای اینکار از متد ActivityCompat.requestPermission داخل شرط if که توی مرحلهی قبل نوشتیم، استفاده میکنیم:
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 1);
پارامترهای این متد، شئ اکتیویتی جاری، یه آرایه String شامل مجوزهای موردنظر هست که میخوایم درخواست بدیم و یه کد برای درخواست (RequestCode) هست که توی متد onRequestPermissionsResult بدرد میخوره.
چطور بفهمیم کاربر مجوز رو داد یا درخواست ما رو رد کرد؟
برای اینکار باید متد onRequesetPermissionsResult رو توی اکتیویتی خودمون Override کنیم. این متد موقعی فراخوانی میشه که کاربر درخواست مجوز رو تأیید یا رد کنه. یه مثال از نحوهی Override کردن این متد:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 1:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// READ_PHONE_STATE permission is granted
} else {
// READ_PHONE_STATE permission is denied
}
break;
}
}
میتونین برای هرکدوم از مجوزها یه کد درخواست مجزا تعریف کنید و توی این متد، با case های مختلفی که برای switch تعریف میکنید، نتایج تصمیم کاربر درخصوص مجوزهای درخواستی رو بصورت جداگانه بررسی کنید.
اگه چندتا مجوز دارین، باید برای هرکدوم یک بلاک if و یک درخواست مجوز بفرستین و همه رو توی onRequesetPermissionsResult چک کنید. تا وقتی که همهی مجوزها داده نشدن، اجازهندین برنامه ادامه پیدا کنه. یکیاز محلهای مناسب برای گرفتن تمام مجوزها، صفحهی SplashScreen هست.
اگه بازم مشکلی بود بفرمایید.