الحصول على الاذونات في الاندرويد الجزء الاول

27 June

مدخل

Permissions او نظام الاذونات على الاندرويد مقرر لحماية معلومات المستخدمين و عرف تطورات عدة من اندرويد الفا وصولا الى اول نسخة من مارشميلو او ما يسمى بلغة مطوري اندرويد API 23 و مند ذلك الحين قسمت الاذونات الى قسمين الاول اذونات خطيرة و اذونات عادية و اقسام اخرى لا دخل لنا بها اليوم .



ليس هذا التقسيم الوحيد فهناك ايضا تقسيمات اخرى اوذنات اثناء تنصيب التطبيق install-time و اذونات اثناء فتح التطبيق Runtime، و العلاقة بينهما ان الاذونات العادية تظهر اثناء التنصيب و لا تحتاج الى طلب اثناء تشغيل التطبيق في حيت ان الاذونات الخطيرة تحتاج الى طلب اذن اثناء التشغيل .
على اليمين اذونات  install time و على اليسار اذونات Runtime .

 ابرز الاذونات العادية(اوذنات اثناء تنصيب التطبيق) : الشبكات(الويفي بلوتوت انترنيت ....) ، الهزاز ،تغيير الخلفية ... . ابرز الاذونات الخطيرة(اوذنات اثناء فتح التطبيق) :الكاميرا ، ارقام الهواتف ،الموقع الجغرافي ،الذاكرة، الميكروفون ، الرسائل،المستشعر .
تجدر الاشارة الى انك اذا قررت استعمال الاذونات الخطيرة دون اذن فستحصل على secuirity Execption

قبل اندرويد ماشميلو API 23

حسنا قبل الاندرويد مارشميلو الفاسق الفاجر ، كانت الامور على ما يرام ، مجرد اضافة سطر واحد الى ملف manifest يجعلك تستمتع بالوصول الى الكاميرا مثلا اعرف ما يجول في راسك الان اتقي الله يا صديقي 😂 دعني اريك الكود و قبل ذلك فليس هناك بين الاذونات الخطيرة او العادية فرق الكل عادي.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
              package="com.example.snazzyapp">
    
        <uses-permission android:name="android.permission.SEND_SMS"/>
    
        <application ...>
            ...
        </application>
    </manifest>
تهانينا لقد حصلت لتوك على اذن للوصول الى الرسائل و ارسالها ايضا جميل اليس كذلك؟ الامر اشبه لما هو موجود بالاعلى يظهر تطبيقك بقائمة الاذونات التي يحتاجها اثناء التنصيب في الوليبوب مثلا .
سبق و ذكرت ان انظمة اندرويد الاقل من API 23 تحتاج الى طلب اذن اثناء التنصيب فقط اما بعد ذلك فلا .

اندرويد ماشميلو API 23 و ما بعده


الحال هنا مختلفة قليلا او كثيرا و طلب الاذن يمر من خمس مراحل يسعدني ذكرها لكم و شرحها
قبل ذلك فهنا اتى تقسيم الاذونات الى خطيرة التي تحتاج الى اتباع هذه الخطوات و اخرى عادية لا تختلف عن سابقاتها .

  • التحقق من النظام
  • التحقق من الاذن
  • لماذا تحتاج الى الاذن
  • طلب الاذن
  • نتيجة الطلب
لازلت مجبرا على اضافة طلب الاذن في ملف manifest بعد ان تضيفه قم بتتبع الخطوات التالية .

الخطوة الاولى : التحقق من النظام

بما ان طلب الاذن لا يوجد الا في اندرويد مارشميلو 6.0 و ما بعده فنحن لسنا بحاجة الى طلبه في ما قبل هذا النظام كالولي بوب 5.0 مثلا .
طريقة التحقق :
if (Build.VERSION.SDK_INT>=23){
        //المرحلة الثانية التحقق من الاذن
    }
if (Build.VERSION.SDK_INT>=23){
        //المرحلة الثانية التحقق من الاذن
    }
تجدر الاشارة الى ان تطبيق سيتوقف في الاصدارات القديمة اذا تجاوزت هذه الخطوة .

الخطوة الثانية : التحقق من الاذن

اولا نحتاج الى ان تحقق من ان المستخدم لم يقم سابقا باعطائنا الاذن تجدر الاشارة الى ان المستخدم يستطيع التراجع عن الاذن من خلال الاعدادات لهذا يجب التحقق في كل مرة تحتاج فيها الى هذا الاذن خلاصة القول لا تستعمل shared preference .
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR)
            != PackageManager.PERMISSION_GRANTED) {
        // لم تحصل على اي اذن
    }
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR)
            != PackageManager.PERMISSION_GRANTED) {
        // لم تحصل على اي اذن
    }

الخطوة التالثة : طلب الاذن

حسنا ان حصلنا على الاذن فهذا جيد لكن ان لم نحصل على الاذن فهنا نحتاج الى طلبه من المستخدم من خلال نافدة منبتقة و لاضهار هذه النافدة نحتاج الى الكود التالي :
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS)
            != PackageManager.PERMISSION_GRANTED) {
    
        // لم تحصل على الاذن
        //طلب الاذن
        ActivityCompat.requestPermissions(context,
            arrayOf(Manifest.permission.READ_CONTACTS), RESULTCODE)
    } else {
        // ثم الحصول على الاذن سابقا
    }
if (ContextCompat.checkSelfPermission(context,
            Manifest.permission.READ_CONTACTS)
            != PackageManager.PERMISSION_GRANTED) {
    
        // لم تحصل على الاذن
        //طلب الاذن
            ActivityCompat.requestPermissions(context,
                    new String[]{Manifest.permission.READ_CONTACTS},RESULTCODE);
    } else {
        // ثم الحصول على الاذن سابقا
    }
ماذا يعني RESULTCODE :
عبارة عن رقم تابث محدد و معروف يمكن المطور من معرفة النتيجة التي ثم ارجاعها من نافدة غير تابعة للتطبيق و هذا في حالة تعدد الطلبات .

الخطوة الرابعة : لماذا نحتاج الاذن

احيانا يقوم المستخدم برفض الطلب بكل وقاحة و لا يتفهم ان هذا من مصلحته و الان في حالة الرفض ستبين له لماذا فعلا يحتاج الى اعطائك هذا الاذن مثلا في حالة كان لديك تطبيق قراءة الكتب و اردت الوصول الى الكاميرا قد يتسائل المستخدم لماذا يحتاج التطبيق الى الكاميرا انذاك تخبره بان التطبيق يستطيع تحديد الكتاب من الصورة و قراءته لك .
كيف يتم ذلك
في اول طلب لك تظهر للمستخدم هذه النافذة المنبتقة : بها زرا الموافقة و الرفض و ايقونة و ايضا الخاصية التي تريد الوصول اليها .

في حالة الرفض يتم اضهار النافذة المنبتقة مرة اخرى : بها زرا الموافقة و الرفض و ايقونة و ايضا الخاصية التي تريد الوصول اليها لكن هذه المرة يضاف اليها checkBox و امامها لا تسال مجددا هنا لهذا قبل اضهارها مجددا تحتاج الى اقناع المستخدم باعطائك للاذن و الا فلن تستطيع طلبه مجددا .

ارني الكود :
if (ContextCompat.checkSelfPermission(context,
                            Manifest.permission.READ_CONTACTS)
                    != PackageManager.PERMISSION_GRANTED) {
    
                // لم تحصل على الاذن
                // هل نحتاج الى شرح سبب الطلب
                if (ActivityCompat.shouldShowRequestPermissionRationale(context,
                                Manifest.permission.READ_CONTACTS)) {
                    // اضهر الشرح للمستخدم
                    // بعد رؤية المستخدم للشرح
                    // سيتم اظهار الطلب مجددا
                    Toast.makeText(context,"انا مسكين و احتاج الى ارقام الهاتف لبيعها",Toast.LENGTH_LONG).show()
                } else {
                    // لا حاجة للشرح هذه اول مرة
                    ActivityCompat.requestPermissions(context,
                            arrayOf(Manifest.permission.READ_CONTACTS), RESULTCODE)
                    
                }
            } else {
                // حصلت على الاذن سابقا
            }
if (ContextCompat.checkSelfPermission(context,
                            Manifest.permission.READ_CONTACTS)
                    != PackageManager.PERMISSION_GRANTED) {
    
                // لم تحصل على الاذن
                // هل نحتاج الى شرح سبب الطلب
                if (ActivityCompat.shouldShowRequestPermissionRationale(context,
                                Manifest.permission.READ_CONTACTS)) {
                    // اضهر الشرح للمستخدم
                    // بعد رؤية المستخدم للشرح
                    // سيتم اظهار الطلب مجددا
                    Toast.makeText(context,"انا مسكين و احتاج الى ارقام الهاتف لبيعها",Toast.LENGTH_LONG).show();
                } else {
                    // لا حاجة للشرح هذه اول مرة
                    ActivityCompat.requestPermissions(context,
                            new String[]{Manifest.permission.READ_CONTACTS}, RESULTCODE);
                    
                }
            } else {
                // حصلت على الاذن سابقا
            }

الخطوة الاخيرة : نتيجة الاذن

حسنا قد يتسائل سائل كيف اعرف اذا ما رفض الطلب او لا لآباشر الوصول الى الخاصية او اعيد الطلب حسنا كل هذا من خلال دالة onRequestPermissionsResult و هي عبارة عن انترفييس للاكتفيتي حسنا هكذا سيكون الكود :
 override fun onRequestPermissionsResult(requestCode: Int,
                                                permissions: Array<string>, grantResults: IntArray) {
            when (requestCode) {
                RESULTCODE -> {
                    // في حالة الرفض
                    //permissions سيكون فارغ
                    if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                        // ثم منحك الاذن 
                        // يمكنك بيع ارقام الهاتف ولتصبح غنيا
                        // sellContacts()
                    } else {
                        // ثم رفض الطلب للاسف
                    }
                    return
                }
    
                else -> {
                    // لا شيء
                }
            }
        }
 @Override
        public void onRequestPermissionsResult(int requestCode,
                                                String permissions[], int[] grantResults) {
            switch (requestCode) {
                case RESULTCODE :{
                    // في حالة الرفض
                    //permissions سيكون فارغ
                    if ((grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                        // ثم منحك الاذن 
                        // يمكنك بيع ارقام الهاتف ولتصبح غنيا
                        // sellContacts() hhhh
                    } else {
                        // ثم رفض الطلب للاسف
                    }
                    return;
                }
    
                default : {
                    // لا شيء
                }
            }
        }

الكود الكامل

class MainActivity : AppCompatActivity() {
        val RESULTCODE=1
        lateinit var btn:Button
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            btn=Button(this)
            btn.apply {
                text="get Permission"
                setOnClickListener{
                    if (Build.VERSION.SDK_INT>=23) checkPer()
                }
            }
            setContentView(btn)
    
        }
        fun checkPer(){
            if (ContextCompat.checkSelfPermission(this,
                            Manifest.permission.READ_CONTACTS)
                    != PackageManager.PERMISSION_GRANTED) {
    
                // لم تحصل على الاذن
                // هل نحتاج الى شرح سبب الطلب
                if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                                Manifest.permission.READ_CONTACTS)) {
                    // اضهر الشرح للمستخدم
                    // بعد رؤية المستخدم للشرح
                    // سيتم اظهار الطلب مجددا
                    val snackbar = Snackbar.make(btn,"انا مسكين و احتاج الى ارقام الهاتف لبيعها" , Snackbar.LENGTH_INDEFINITE)
                    snackbar.setAction("حسنا") {
                        ActivityCompat.requestPermissions(this,
                                arrayOf(Manifest.permission.READ_CONTACTS), RESULTCODE)
                    }
                    snackbar.show()
                } else {
                    // لا حاجة للشرح هذه اول مرة
                    ActivityCompat.requestPermissions(this,
                            arrayOf(Manifest.permission.READ_CONTACTS), RESULTCODE)
    
                }
            } else {
                Toast.makeText(this,"حصلت على الاذن",Toast.LENGTH_LONG).show()
            }
        }
        override fun onRequestPermissionsResult(requestCode: Int,
                                                permissions: Array<string>, grantResults: IntArray) {
            when (requestCode) {
                RESULTCODE -> {
                    // في حالة الرفض
                    //permissions سيكون فارغ
                    if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                        // ثم منحك الاذن
                        // يمكنك بيع ارقام الهاتف ولتصبح غنيا
                        // sellContacts()
                    } else {
                        // ثم رفض الطلب للاسف
                        checkPer()
                    }
                    return
                }
    
                else -> {
                    // لا شيء
                }
            }
        }
    }
    

هل ترغب في مثل هذه التدوينات

اسماعيل ايت بلا

ببساطة ارغب في تجربة جديدة من التعلم من خلال مشاركة ما تعلمه يجبرني ذلك على البحث لمدة طويلة مما يجعل الموقع جديرا بالثقة

اترك لنا تعليقا

الاشتراك بالقائمة البريدية

توصل باحدث مواضيعنا و كن على اطلاع باخر اخبار وتقنيات الاندرويد