تالار گفتمان nCIS.ir

نسخه‌ی کامل: پرمیشن ها در اندروید 6
شما در حال مشاهده نسخه آرشیو هستید. برای مشاهده نسخه کامل کلیک کنید.
با سلام خدمت اساتید عزیز این فروم
دوتا سوال دارم:
1-توی اندروید 6 یک سری پرمیشن ها باید ران تایم بگیریم لیست این پرمیشن ها چیه؟
2-من چند تا پرمیشن دارم که باید با ران تایم بگیرمش چطوری این چند تا همش رو توی یه پیغام تاییدش رو بگیرم؟

ممنون میشم پاسخ بدید.
بهتره یکم دیدتون رو اصلاح کنم. توی اندروید 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 هست.

اگه بازم مشکلی بود بفرمایید.
نتونستم این رو  Override کنم چون من  extends Application دارم.

@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;
   }
}
چطوری از Application مشتق کردین؟ این کد رو باید توی اکتیویتی بنویسین نه کلاس Application
توی کلاس App نیاز دارم به:
App.imsi = App.telephonyManager.getDeviceId();
مجبور شدم که ببرم تو اسپلش اسکرین به گفته شما الان پرمیشن رو میگیره ولی خوب بازم متد onRequestPermissionsResult رو اصلا صدا نمیزنه!!!! و نمیتونم بفهمم قبول کرده یا ن !!!
چک کنید اکتیویتی شما از AppCompatActivity مشتق شده باشه. اگه همه‌چیز رو درست انجام داده باشین نباید مشکلی پیش بیاد. درمورد اون مشکل کلاس App هم میتونید فیلد رو تعریف کنید و بعد توی Splash Screen بعد از گرفتن مجوزها مقداردهی کنید. چون public static هست، توی بقیه‌ی برنامه راحت بهش دسترسی دارین.
یک راه دیگه، مجوزدادن بصورت گروهیه. برای مثال:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED ||
        ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_FINE_LOCATION}, 1);
}

و نحوه‌ی گرفتن پاسخ درخواست مجوز:
@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) {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // READ_PHONE_STATE permission is granted
                } else {
                    // READ_PHONE_STATE permission is denied
                }
                if (grantResults[1] == PackageManager.PERMISSION_GRANTED) {
                    // ACCESS_FINE_LOCATION permission is granted
                } else {
                    // ACCESS_FINE_LOCATION permission is denied
                }
            }
            break;
    }
}

درواقع ترتیب آرایه‌ی پاسخ‌ها همون ترتیبی هست که شما مجوزها رو درخواست کردین.
سلام
استاد اگه پرمیشن تو کلاس سرویس نیاز داشته باشیم یعنی کدها ی که نیاز به پرمیشن داره همه تو سرویس باشه بازم به همین صورت است یعنی اکتیویتی بجوز کد پرمیشن هیج کد دیگه نیست
یا فرق داره اگه فرق داره ممنون میشم توضیح بدین
فرقی نداره. باید بهرحال همیشه قبل از استفاده از یک قابلیت خاص، وجود مجوزش رو بررسی کنید چون حتی بعد از نصب و دادن مجوزها هم امکان گرفتن مجوز خاصی از برنامه توسط کاربر وجود داره.
با سلام استاد برای من  Manifest.permission رو نمیاره خطا میده
دو تا کلاس Manifest داریم. یکی توی پکیج android و یکی دیگه توی java.util.jar

دقت کنید که پکیج درست رو Import کرده باشین (اندروید).