فشل startForeground بعد التحديث إلى Android 8.1: الحل بلغة Kotlin

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

هل "تعطلت" خدمة المقدمة بعد التحديث؟ لست وحدك

\n

تخيل: تقوم بتشغيل تطبيقك، من المفترض أن يعمل في الخلفية، ويعرض إشعارًا مهمًا. كان كل شيء يعمل بشكل رائع على Android 7.0، والمستخدمون سعداء. ولكن بعد التحديث إلى Android 8.1، يتعطل التطبيق مع خطأ غامض startForeground fail. هل هذا مألوف؟ إذا واجهت هذه المشكلة، فأنت تعلم كم هي مزعجة. على Stack Overflow، حصد هذا السؤال آلاف المشاهدات، مما يعني أنه أثر على العديد من المطورين. في هذه المقالة، سنشرح لماذا يحدث هذا، وكيفية إصلاح الخطأ بلغة Kotlin، والأهم من ذلك، كيفية تجنبه في المستقبل.

\n\n

ما هو startForeground ولماذا هو مطلوب؟

\n

في Android، خدمة المقدمة (foreground service) هي خدمة تؤدي إجراءات مرئية للمستخدم. على سبيل المثال، تشغيل الموسيقى، تسجيل مسار GPS، أو تنزيل ملف. على عكس الخدمة العادية، يجب أن تعرض خدمة المقدمة إشعارًا دائمًا في شريط الحالة. يتم ذلك من خلال استدعاء startForeground()، الذي يأخذ معرف الإشعار وكائن Notification نفسه.

\n

بدءًا من Android 8.0 (API 26)، فرضت Google قيودًا صارمة على الخدمات الخلفية. الآن، إذا حاولت تشغيل خدمة مقدمة بدون إشعار تم تكوينه بشكل صحيح، سيرمي النظام استثناء ForegroundServiceStartNotAllowedException أو ببساطة سيتجاهل الاستدعاء. في Android 8.1، أصبحت هذه القيود أكثر صرامة، وأصبح خطأ startForeground fail واسع الانتشار.

\n\n

لماذا يحدث فشل startForeground في Android 8.1؟

\n

السبب الرئيسي هو غياب أو تكوين غير صحيح لقناة الإشعارات (Notification Channel). قبل Android 8.0، كان يمكن إنشاء الإشعارات بدون قنوات. بعد التحديث، ألزمت Google المطورين بإنشاء قناة واحدة على الأقل لكل نوع من الإشعارات. إذا قمت باستدعاء startForeground() مع إشعار ليس له قناة، فإن النظام ببساطة لا يعرف كيفية عرضه، ويرمي خطأ.

\n

السبب الثاني هو انتهاك التوقيت. يجب عليك استدعاء startForeground() خلال أول 5 ثوانٍ بعد بدء الخدمة. إذا لم تفعل ذلك، سيتم إنهاء الخدمة، وقد يتعطل التطبيق.

\n

السبب الثالث هو محاولة تشغيل الخدمة من الخلفية. بدءًا من Android 8.0، يُحظر تشغيل خدمة المقدمة من سياق خلفي (مثل BroadcastReceiver أو خدمة أخرى). الاستثناء الوحيد هو إذا كان التطبيق في المقدمة.

\n\n

كيفية الإصلاح: دليل خطوة بخطوة بلغة Kotlin

\n

دعنا نعيد كتابة خدمتك بحيث تعمل على Android 8.1 والإصدارات الأحدث. سنستخدم Kotlin - لغة حديثة وموجزة.

\n\n

الخطوة 1: إنشاء قناة إشعارات

\n

يجب إنشاء القناة قبل عرض الإشعار. أفضل مكان هو في طريقة onCreate() لخدمتك أو في فئة Application. إليك مثال:

\n
class MyForegroundService : Service() {\n    companion object {\n        const val CHANNEL_ID = "my_foreground_channel"\n        const val NOTIFICATION_ID = 1\n    }\n\n    override fun onCreate() {\n        super.onCreate()\n        createNotificationChannel()\n    }\n\n    private fun createNotificationChannel() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n            val channel = NotificationChannel(\n                CHANNEL_ID,\n                "Foreground Service Channel",\n                NotificationManager.IMPORTANCE_LOW\n            ).apply {\n                description = "Channel for foreground service notifications"\n            }\n            val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager\n            notificationManager.createNotificationChannel(channel)\n        }\n    }\n}
\n

لاحظ: نتحقق من إصدار SDK. على الأجهزة القديمة، القنوات غير مطلوبة، و

المدونات

توصيات الكتب