0Pricing
Android Academy · درس

الأذونات وطلبات وقت التشغيل

صرّح بالأذونات الخطرة واطلبها أثناء التشغيل باستخدام ActivityResultContracts، واعرض مربعات حوار توضيحية، وعالج الرفض الدائم.

الأذونات وطلبات وقت التشغيل درس مجاني في Android Academy على CoddyKit. هذا هو الدرس 7 من أصل 7. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Android Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Android Academy 7 دروس في المجموع.

نظرة عامة على أذونات Android

يجب أن تصرّح تطبيقات Android بميزات الجهاز التي تحتاج إليها. تحمي الأذونات خصوصية المستخدم:

  • الأذونات العادية — منخفضة الخطورة، وتُمنح تلقائيًا (INTERNET وVIBRATE)
  • الأذونات الخطرة — تتيح الوصول إلى بيانات حساسة، ويجب طلبها أثناء التشغيل (CAMERA وLOCATION وREAD_CONTACTS)
  • أذونات التوقيع — تقتصر على التطبيقات الموقّعة بالشهادة نفسها

التصريح في ملف Manifest

يجب أولًا التصريح بجميع الأذونات في AndroidManifest.xml:

<!-- AndroidManifest.xml -->
<manifest ...>

    <!-- Normal: granted automatically -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.VIBRATE" />

    <!-- Dangerous: must request at runtime -->
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />

    <application ...>
        ...
    </application>
</manifest>

التحقق من منح الإذن

قبل استخدام ميزة خطرة، تحقّق دائمًا مما إذا كان الإذن ممنوحًا بالفعل:

import androidx.core.content.ContextCompat
import android.content.pm.PackageManager

fun isCameraPermissionGranted(): Boolean {
    return ContextCompat.checkSelfPermission(
        this,   // Context
        android.Manifest.permission.CAMERA
    ) == PackageManager.PERMISSION_GRANTED
}

طلب الإذن باستخدام ActivityResultLauncher

استخدم ActivityResultContracts.RequestPermission() — وهي الطريقة الحديثة (من دون استخدام onRequestPermissionsResult المهملة):

class CameraActivity : AppCompatActivity() {

    private val requestCameraPermission = registerForActivityResult(
        ActivityResultContracts.RequestPermission()
    ) { isGranted ->
        if (isGranted) {
            openCamera()
        } else {
            showPermissionDeniedMessage()
        }
    }

    fun onTakePhotoClick(view: View) {
        if (isCameraPermissionGranted()) {
            openCamera()
        } else {
            requestCameraPermission.launch(android.Manifest.permission.CAMERA)
        }
    }
}

طلب عدة أذونات دفعة واحدة

اطلب عدة أذونات باستخدام RequestMultiplePermissions:

private val requestMultiple = registerForActivityResult(
    ActivityResultContracts.RequestMultiplePermissions()
) { permissions ->
    val cameraGranted   = permissions[android.Manifest.permission.CAMERA] ?: false
    val locationGranted = permissions[android.Manifest.permission.ACCESS_FINE_LOCATION] ?: false

    if (cameraGranted && locationGranted) {
        startFeature()
    } else {
        showWhichPermissionsDenied(cameraGranted, locationGranted)
    }
}

fun requestPermissions() {
    requestMultiple.launch(arrayOf(
        android.Manifest.permission.CAMERA,
        android.Manifest.permission.ACCESS_FINE_LOCATION
    ))
}

التعليل: متى تشرح السبب

تعيد shouldShowRequestPermissionRationale() القيمة true عندما يكون المستخدم قد رفض الإذن سابقًا. اعرض شرحًا قبل طلب الإذن مرة أخرى:

fun requestCameraWithRationale() {
    when {
        isCameraPermissionGranted() -> {
            openCamera()
        }
        shouldShowRequestPermissionRationale(android.Manifest.permission.CAMERA) -> {
            // Explain why we need it, then request
            AlertDialog.Builder(this)
                .setTitle("Camera needed")
                .setMessage("We use the camera to take profile photos.")
                .setPositiveButton("OK") { _, _ ->
                    requestCameraPermission.launch(android.Manifest.permission.CAMERA)
                }
                .show()
        }
        else -> {
            requestCameraPermission.launch(android.Manifest.permission.CAMERA)
        }
    }
}

الرفض الدائم — الانتقال إلى الإعدادات

إذا نقر المستخدم على "عدم السؤال مرة أخرى"، تعيد shouldShowRequestPermissionRationale القيمة false، ولا يمكنك طلب الإذن مرة أخرى. وجّه المستخدم إلى إعدادات التطبيق:

fun openAppSettings() {
    val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
        data = Uri.fromParts("package", packageName, null)
    }
    startActivity(intent)
}

إذن الموقع

للموقع مستويان — اختر المستوى المناسب لحالة الاستخدام:

  • ACCESS_COARSE_LOCATION — دقة على مستوى المدينة (WiFi/أبراج الاتصالات)
  • ACCESS_FINE_LOCATION — دقة GPS
  • ACCESS_BACKGROUND_LOCATION — مطلوب بشكل منفصل في Android 10 والإصدارات الأحدث للوصول إلى الموقع في الخلفية

مثال كامل لإذن الكاميرا

التدفق الكامل الذي يجمع بين التحقق ← التعليل ← الطلب:

class PhotoActivity : AppCompatActivity() {

    private val cameraLauncher = registerForActivityResult(
        ActivityResultContracts.RequestPermission()
    ) { granted ->
        if (granted) openCamera() else showDenied()
    }

    private fun handleCameraClick() {
        val permission = android.Manifest.permission.CAMERA
        when {
            ContextCompat.checkSelfPermission(this, permission) ==
                    PackageManager.PERMISSION_GRANTED -> openCamera()
            shouldShowRequestPermissionRationale(permission) ->
                showRationaleDialog()
            else -> cameraLauncher.launch(permission)
        }
    }

    private fun showDenied() {
        Snackbar.make(binding.root, "Camera permission required", Snackbar.LENGTH_LONG)
            .setAction("Settings") { openAppSettings() }.show()
    }
}

أفضل ممارسات الأذونات

القواعد الأساسية لتجربة أذونات سلسة:

  • اطلب الأذونات عند الحاجة إليها فقط (وليس عند تشغيل التطبيق)
  • اطلب الحد الأدنى من الأذونات المطلوبة فقط
  • تعامل دائمًا مع حالة الرفض بطريقة مناسبة
  • لا تكرر الطلب بعد اختيار "عدم السؤال مرة أخرى"
  • اشرح السبب قبل ظهور مربع حوار النظام، وليس بعد الرفض

أذونات الوسائط الدقيقة في Android 13 والإصدارات الأحدث

منذ Android 13 (API 33)، جرى تقسيم READ_EXTERNAL_STORAGE إلى أذونات تفصيلية:

  • READ_MEDIA_IMAGES
  • READ_MEDIA_VIDEO
  • READ_MEDIA_AUDIO

تحقّق دائمًا من Build.VERSION.SDK_INT واطلب الإذن المناسب لإصدار نظام التشغيل.

اختبار سريع

متى ينبغي عرض مربع حوار للتعليل قبل طلب إذن خطِر؟

مراجعة: الأذونات

تطبيق أذونات وقت التشغيل بطريقة صحيحة:

  • التصريح بها في AndroidManifest.xml
  • التحقق منها باستخدام ContextCompat.checkSelfPermission()
  • طلبها عبر registerForActivityResult(RequestPermission())
  • عرض التعليل عندما تكون قيمة shouldShowRequestPermissionRationale() هي true
  • عند الرفض الدائم، توجيه المستخدمين إلى الإعدادات
  • عدم طلب الأذونات قبل حاجة المستخدم إليها

التالي: حفظ البيانات محليًا باستخدام DataStore.

الأسئلة الشائعة

هل درس «الأذونات وطلبات وقت التشغيل» مجاني؟

نعم — نص درس «الأذونات وطلبات وقت التشغيل» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Android Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Android Academy 7 دروس في المجموع.

ماذا ستتعلم في «الأذونات وطلبات وقت التشغيل»؟

صرّح بالأذونات الخطرة واطلبها أثناء التشغيل باستخدام ActivityResultContracts، واعرض مربعات حوار توضيحية، وعالج الرفض الدائم. تتمرن على Android Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Android Academy؟

لا تُشترط خبرة سابقة. Android Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 7 من أصل 7.

كم من الوقت يستغرق درس «الأذونات وطلبات وقت التشغيل»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Android Academy هذا؟

نعم. كل درس في Android Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. بنية المشروع وملف البيان
  2. الأنشطة ودورة الحياة
  3. التخطيطات وطرق العرض
  4. معالجة إدخال المستخدم
  5. النوايا والتنقّل
  6. الأجزاء
  7. الأذونات وطلبات وقت التشغيل
← العودة إلى Android Academy