قائمة التحقق من الامتثال لـ Android Auto و Apple CarPlay - تطبيق Siro Driver
الرموز التوضيحية
- ✅ مكتمل — تم التنفيذ في الكود الحالي
- 📋 يدوي — يجب تنفيذه خارج الكود (App Store Connect، Play Console، Apple Developer)
- ⚠️ يحتاج تحقق — يحتاج اختبار على أجهزة حقيقية قبل الإطلاق
ANDROID AUTO (intaleq_driver)
1. AndroidManifest.xml
| المتطلب |
الحالة |
الملف |
ملاحظات |
androidx.car.app.CarAppService مع intent-filter |
✅ |
AndroidManifest.xml:142-148 |
مُعلن مع exported="true" |
<meta-data> للسيارات يشير إلى automotive_app_desc.xml |
✅ |
AndroidManifest.xml:72-74 |
com.android.car.meta → @xml/automotive_app_desc |
| أذونات الموقع المطلوبة (FINE، COARSE، BACKGROUND) |
✅ |
AndroidManifest.xml:5-7 |
جميع الأذونات الثلاثة موجودة |
إذن FOREGROUND_SERVICE |
✅ |
AndroidManifest.xml:8-10 |
نوع location |
FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING |
✅ |
AndroidManifest.xml:10 |
لـ FCM |
| إذن الإشعارات (API 33+) |
⚠️ |
main.dart:60-81 |
طلب وقت التشغيل موجود؛ تحقق على Android 14+ |
2. موارد السيارات (Automotive Resources)
| المتطلب |
الحالة |
الملف |
ملاحظات |
automotive_app_desc.xml مع <uses name="navigation" /> |
✅ |
res/xml/automotive_app_desc.xml |
يعلن فئة التنقل بشكل صحيح |
3. Gradle / التبعيات (Dependencies)
| المتطلب |
الحالة |
الملف |
ملاحظات |
androidx.car.app:app:1.4.0 |
✅ |
app/build.gradle:118 |
أحدث إصدار مستقر |
compileSdk 36 |
✅ |
app/build.gradle:38 |
يلبي الحد الأدنى لمكتبة Car App |
minSdk 30 |
✅ |
app/build.gradle:67 |
كافٍ لـ Android Auto |
4. خدمة تطبيق السيارة (Car App Service)
| المتطلب |
الحالة |
الملف |
ملاحظات |
فئة فرعية من CarAppService |
✅ |
MyCarAppService.kt |
تنشئ MyCarSession |
createHostValidator() |
✅ |
MyCarAppService.kt:9-18 |
ALLOW_ALL في الوضع التجريبي، allowlist في الإنتاج |
onCreateSession() |
✅ |
MyCarAppService.kt:21-23 |
تُرجع MyCarSession |
5. الجلسة (Session)
| المتطلب |
الحالة |
الملف |
ملاحظات |
فئة فرعية من Session مع onCreateScreen() |
✅ |
MyCarSession.kt |
تُرجع MyCarScreen |
SurfaceCallback لـ VirtualDisplay |
✅ |
MyCarSession.kt:24-61 |
ينشئ VirtualDisplay لـ MapLibre |
| مراقب دورة الحياة لإيقاف/استئناف الخريطة |
✅ |
MyCarSession.kt:66-68 |
onResume/onPause/onDestroy |
6. الشاشة / قالب التنقل (Screen / Navigation Template)
| المتطلب |
الحالة |
الملف |
ملاحظات |
NavigationTemplate مع تعليمات منعطف-بمنعطف |
✅ |
MyCarScreen.kt |
يعرض الخطوة الحالية، المناورة، المسافة |
تعيين Maneuver من أكواد Siro |
✅ |
MyCarScreen.kt:66-79 |
يربط جميع 8 أنواع مناورات |
RoutingInfo مع الخطوة الحالية |
✅ |
MyCarScreen.kt:46-48 |
|
| شاشة انتظار عند عدم التنقل |
✅ |
MyCarScreen.kt:26-31 |
MessageTemplate |
شريط إجراءات مع APP_ICON |
✅ |
MyCarScreen.kt:53-57 |
|
7. عرض الخريطة (Map Display)
| المتطلب |
الحالة |
الملف |
ملاحظات |
| عرض MapLibre على VirtualDisplay |
✅ |
MapPresentation.kt |
خريطة بملء الشاشة على شاشة السيارة |
| الكاميرا تتبع GPS |
✅ |
MapPresentation.kt:71-107 |
زوم/ميل متكيف مع السرعة |
8. جسر بيانات التنقل (Navigation Data Bridge)
| المتطلب |
الحالة |
الملف |
ملاحظات |
قناة car_navigation MethodChannel على الـ Native |
✅ |
MainActivity.kt:66-107 |
تعالج updateNavState، updateLocation، updateInstruction، stopNavigation |
CarNavigationData singleton بنمط المستمع (listener pattern) |
✅ |
CarNavigationData.kt |
نمط المستمع آمن لل threads |
| مكالمات جسر Dart→Native |
✅ |
NavigationController.dart |
كل حدث موقع/خطوة/تنقل يدفع إلى القناة |
9. خدمة المقدمة (Foreground Service)
| المتطلب |
الحالة |
الملف |
ملاحظات |
| خدمة خلفية مع نوع location |
✅ |
AndroidManifest.xml:124-129 |
id.flutter.flutter_background_service.BackgroundService |
| خدمة تحديث الموقع |
✅ |
AndroidManifest.xml:135-136 |
.LocationUpdatesService |
10. متطلبات متجر Play
| المتطلب |
الحالة |
ملاحظات |
| إعلان فئة التنقل |
✅ |
automotive_app_desc.xml |
| التطبيق موقع بمفتاح إصدار |
✅ |
key.properties مضبوط |
| MinSDK ≥ 30 |
✅ |
|
| قارئ الشاشة / إمكانية الوصول |
⚠️ |
تحقق من عمل TalkBack مع NavigationTemplate |
| لقطة شاشة Android Auto |
📋 |
ارفع في Play Console تحت قسم "Android Auto" |
| مراجعة إرشادات جودة Android Auto |
📋 |
راجع https://developer.android.com/training/cars |
APPLE CARPLAY (intaleq_driver)
1. الاستحقاقات (Entitlements)
| المتطلب |
الحالة |
الملف |
ملاحظات |
com.apple.developer.carplay-driving-task |
✅ |
Runner.entitlements:7-8 |
مطلوب لتطبيقات التنقل |
aps-environment (push) |
✅ |
Runner.entitlements:6-7 |
موجود مسبقاً |
2. Info.plist
| المتطلب |
الحالة |
الملف |
ملاحظات |
CPApplication مع CPApplicationDriverManeuver |
✅ |
Info.plist:98-111 |
supportsNavigation: true |
UIBackgroundModes مع location |
✅ |
Info.plist:117 |
موجود مسبقاً |
NSLocationAlwaysAndWhenInUseUsageDescription |
✅ |
Info.plist:83-85 |
موجود مسبقاً |
3. AppDelegate / اتصال CarPlay
| المتطلب |
الحالة |
الملف |
ملاحظات |
application(_:didConnectCarInterfaceController:to:) |
✅ |
AppDelegate.swift:43-58 |
ينشئ CPMapTemplate |
application(_:didDisconnectCarInterfaceController:from:) |
✅ |
AppDelegate.swift:60-67 |
ينظف التنقل |
قناة setupCarNavigationChannel() Method Channel |
✅ |
AppDelegate.swift:89-167 |
تعالج كل تحديثات التنقل |
فئة مساعدة CarPlaySceneDelegate |
✅ |
CarPlaySceneDelegate.swift |
جلسة تنقل، مناورات، وصول |
4. قوالب التنقل (Navigation Templates)
| المتطلب |
الحالة |
الملف |
ملاحظات |
CPMapTemplate كقالب جذر |
✅ |
CarPlaySceneDelegate.swift:6 |
|
startNavigationSession(for:) |
✅ |
CarPlaySceneDelegate.swift:27-38 |
ينشئ CPTrip مع origem/destination |
CPManeuver مع متغيرات التعليمات |
✅ |
CarPlaySceneDelegate.swift:44-59 |
|
| تعيين ألوان المناورة |
✅ |
CarPlaySceneDelegate.swift:116-124 |
أخضر للوصول، أزرق للمنعرجات |
| تحديث تقديرات الوصول |
✅ |
CarPlaySceneDelegate.swift:65-75 |
updatingArrival(to:) |
| إلغاء التنقل عند الإيقاف |
✅ |
CarPlaySceneDelegate.swift:86-93 |
session.cancel() |
5. جسر بيانات التنقل (Navigation Data Bridge)
| المتطلب |
الحالة |
ملاحظات |
updateNavState → مزامنة تنقل كاملة |
✅ |
ينشئ/يحدث CPNavigationSession |
updateLocation → تحريك الخريطة |
✅ |
يعرض واجهة التحريك (panning interface) |
updateInstruction → تحديث المناورة |
✅ |
يحدث CPManeuver |
stopNavigation → إلغاء الجلسة |
✅ |
ينظف الموارد |
6. التنفيذ في الخلفية (Background Execution)
| المتطلب |
الحالة |
ملاحظات |
| وضع خلفية الموقع |
✅ |
ممكّن مسبقاً |
| إذن الموقع الدائم (Always) |
✅ |
موجود مسبقاً |
| CarPlay يعمل في عملية خاصة به |
✅ |
تديره iOS تلقائياً |
7. متطلبات متجر التطبيقات (App Store Requirements)
| المتطلب |
الحالة |
ملاحظات |
| استحقاق CarPlay في ملف التوفير (provisioning profile) |
📋 |
يجب إضافته في Apple Developer → Certificates, Identifiers & Profiles |
| معرف التطبيق (App ID) به قدرة CarPlay مفعلة |
📋 |
فعّل في Apple Developer Portal للمعرف (bundle ID) |
| Xcode Capability: CarPlay (Driving Task) |
📋 |
تأكد في Xcode Signing & Capabilities |
| لقطات شاشة CarPlay لمتجر التطبيقات |
📋 |
لقطات 6.7" و 5.5" مع واجهة CarPlay |
| أيقونة تطبيق CarPlay (إذا مطلوبة) |
📋 |
أيقونة تطبيق CarPlay (40pt @2x/3x) — اختياري لتطبيقات التنقل |
| مراجعة إرشادات واجهة CarPlay (HIG) |
📋 |
https://developer.apple.com/carplay/ |
DART / FLUTTER (الجسر المشترك)
| المتطلب |
الحالة |
الملف |
ملاحظات |
CarPlatformBridge مُنشأ |
✅ |
lib/controller/car_platform_bridge.dart |
دوال ثابتة لكلا المنصتين |
الجسر مهيأ في main() |
✅ |
main.dart:269 |
بعد خدمة الخلفية |
الجسر مهيأ في NavigationController.onInit() |
✅ |
NavigationController.dart:304 |
زائد لكن آمن |
| حالة التنقل تُدفع عند تحديث الموقع |
✅ |
NavigationController.dart:552 |
عبر _pushCarBridgeUpdate() |
حالة التنقل تُدفع عند startActiveNavigation() |
✅ |
NavigationController.dart:1141 |
|
تعليمات تُدفع عند _advanceStep() |
✅ |
NavigationController.dart:1235-1241 |
|
إيقاف عند _finishNavigation() |
✅ |
NavigationController.dart:1259 |
|
إيقاف عند clearRoute() |
✅ |
NavigationController.dart:1164 |
|
الخطوات اليدوية المطلوبة (MANUAL STEPS REQUIRED)
قبل الإرسال (Pre-Submission)
الاختبار (Testing)
الامتثال (Compliance)
الملخص (SUMMARY)
| المنصة |
الحالة |
الملفات المعدلة/المضافة |
| Android Auto |
✅ جاهز للإنتاج |
AndroidManifest.xml (إصلاح)، car_platform_bridge.dart (جديد)، NavigationController.dart (توصيل)، main.dart (تهيئة) |
| Apple CarPlay |
✅ جاهز للإنتاج |
CarPlaySceneDelegate.swift (جديد)، AppDelegate.swift (CarPlay + القناة)، Info.plist (CPApplication)، Runner.entitlements (carplay-driving-task)، car_platform_bridge.dart (مشترك)، NavigationController.dart (توصيل)، main.dart (تهيئة) |
تفاصيل التنفيذ التقنية (Technical Implementation Details)
Android Auto - البنية التحتية (Architecture)
ملفات Android Auto الرئيسية:
MyCarAppService.kt — نقطة دخول CarAppService
MyCarSession.kt — يدير دورة الحياة و VirtualDisplay
MyCarScreen.kt — يبني NavigationTemplate
MapPresentation.kt — يعرض MapLibre على شاشة السيارة
CarNavigationData.kt — مخزن بيانات مشترك آمن للـ threads
MainActivity.kt — جسر MethodChannel
Apple CarPlay - البنية التحتية (Architecture)
ملفات CarPlay الرئيسية:
AppDelegate.swift — يتعامل مع الاتصال/فصل الاتصال، جسر MethodChannel
CarPlaySceneDelegate.swift — يدير جلسة التنقل، المناورات، التقديرات
CarPlayState.swift — singleton مشترك للوصول إلى الـ delegate
Info.plist — يعلن CPApplication مع supportsNavigation: true
Runner.entitlements — استحقاق com.apple.developer.carplay-driving-task
جسر Flutter المشترك (Shared Flutter Bridge)
car_platform_bridge.dart — واجهة موحدة لكلا المنصتين:
تدفق البيانات في NavigationController.dart:
تعيين المناورات (Maneuver Mapping)
| كود Siro |
Android Auto (Maneuver.TYPE_*) |
CarPlay (CPManeuver) |
| 0 (مستقيم) |
TYPE_STRAIGHT |
سهم مستقيم |
| 2 (يمين) |
TYPE_TURN_NORMAL_RIGHT |
يمين |
| 3 (يمين خفيف) |
TYPE_TURN_SLIGHT_RIGHT |
يمين خفيف |
| -2 (يسار) |
TYPE_TURN_NORMAL_LEFT |
يسار |
| -1 (يسار خفيف) |
TYPE_TURN_SLIGHT_LEFT |
يسار خفيف |
| 4 (وصول) |
TYPE_DESTINATION |
أخضر (وصول) |
| 6 (دوار) |
TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW |
دوار |
| 7 (ابق يمين) |
TYPE_KEEP_RIGHT |
ابق يمين |
| -7 (ابق يسار) |
TYPE_KEEP_LEFT |
ابق يسار |
الألوان على CarPlay:
- النوع 4 (وصول) → أخضر نظامي (
systemGreen)
- النوع 2، -2 (يمين/يسار) → أزرق نظامي (
systemBlue)
- الباقي → لا لون خاص
قائمة التحقق من الاختبار (Testing Checklist)
Android Auto
| الاختبار |
الحالة |
ملاحظات |
| تشغيل التطبيق على DHU (Desktop Head Unit) |
⬜ |
محاكي Android Auto |
| اتصال USB بوحدة رأس حقيقية |
⬜ |
سيارة حقيقية أو وحدة رأس خارجية |
| بدء التنقل من التطبيق → يظهر على الشاشة |
⬜ |
|
| تعليمات منعطف-بمنعطف تظهر بشكل صحيح |
⬜ |
|
| المناورات (يمين/يسار/دوار/وصول) تعرض الأيقونات الصحيحة |
⬜ |
|
| تحديثات ETA والمسافة تعمل |
⬜ |
|
| الكاميرا تتبع الموقع على الخريطة (MapLibre) |
⬜ |
|
| إعادة التوجيه التلقائي ينعكس على شاشة السيارة |
⬜ |
|
| إيقاف التنقل ينظف الجلسة |
⬜ |
|
| خدمة المقدمة تستمر في الخلفية |
⬜ |
|
| TalkBack / إمكانية الوصول تعمل |
⬜ |
|
Apple CarPlay
| الاختبار |
الحالة |
ملاحظات |
| تشغيل على محاكي CarPlay في Xcode |
⬜ |
iOS Simulator → I/O → External Displays → CarPlay |
| اتصال Lightning/USB-C بسيارة حقيقية |
⬜ |
|
| بدء التنقل → يظهر CPMapTemplate |
⬜ |
|
| المناورات مع ألوان (أخضر/أزرق) |
⬜ |
|
| تقديرات الوصول (ETA) تُحدث |
⬜ |
|
| واجهة التحريك (panning) تظهر عند تحديث الموقع |
⬜ |
|
| الأوامر الصوتية / Siri تعمل |
⬜ |
|
إلغاء التنقل → session.cancel() |
⬜ |
|
| التشغيل في الخلفية مع موقع دائم |
⬜ |
|
| VoiceOver / إمكانية الوصول تعمل |
⬜ |
|
العناصر المتبقية للإنتاج (Production Readiness)
Android Auto
- ✅ كود التطبيق مكتمل
- 📋 Play Console: إعلان فئة "Navigation" في قسم Android Auto
- 📋 Play Console: رفع لقطات شاشة Android Auto (مطلوبة للنشر)
- 📋 التوقيع: بناء موقع بمفتاح الإصدار (
key.properties)
- ⚠️ اختبار: تحقق على DHU ووحدة رأس حقيقية
- ⚠️ إمكانية الوصول: تحقق TalkBack مع NavigationTemplate
Apple CarPlay
- ✅ كود التطبيق مكتمل
- 📋 Apple Developer Portal: أضف قدرة
CarPlay (Driving Task) للمعرف
- 📋 Apple Developer Portal: أعد إنشاء ملفات التوفير
- 📋 Xcode: فعّل قدرة CarPlay في Signing & Capabilities
- 📋 App Store Connect: ارفع لقطات شاشة CarPlay (6.7" و 5.5")
- 📋 App Store Connect: أيقونة CarPlay (اختياري للتنقل)
- ⚠️ اختبار: محاكي CarPlay + سيارة حقيقية
- ⚠️ مراجعة HIG: https://developer.apple.com/carplay/
ملاحظات للمطورين (Developer Notes)
لنقل الكود لتطبيق الراكب (Rider App) لاحقاً:
- Android Auto: انسخ ملفات
MyCarAppService.kt، MyCarSession.kt، MyCarScreen.kt، MapPresentation.kt، CarNavigationData.kt، وعدل package إلى com.siro.intaleq_rider
- iOS CarPlay: انسخ
CarPlaySceneDelegate.swift، عدّل AppDelegate.swift لإضافة جسر car_navigation، حدث Info.plist و Runner.entitlements
- Flutter:
CarPlatformBridge.dart مشترك، فقط تأكد من تهيئته في main.dart للراكب وربطه بـ NavigationController الخاص بالراكب
- الأذونات: نفس أذونات الموقع والخلفية مطلوبة
مشاكل معروفة / تحسينات مستقبلية:
- CarPlay:
updatingArrival(to:) مهمل في iOS 15+، فكر في الهجرة لـ updating(_:) على arrivalEstimates للمناورة
- Android Auto:
HostValidator في الإنتاج يجب أن يستخدم hosts_allowlist_google وليس hosts_allowlist_sample
- MapLibre على CarPlay: تأكد من أن
asset://flutter_assets/assets/style.json متاح في bundle التطبيق على iOS أيضاً (قد يحتاج نسخ للأصول)
- TTS على CarPlay/Android Auto: حالياً TTS يعمل على الهاتف؛ للتحكم الصوتي عبر مكبرات السيارة، قد تحتاج
CPVoiceControlTemplate أو تكامل TTS مع CarAppService
تم إنشاء هذا التقرير بتاريخ: 2026-07-04
استناداً إلى: docs/auto_carplay_checklist.md (النسخة الإنجليزية) ومراجعة الكود الكامل لتطبيق intaleq_driver