السلسلة: هذا الدرس جزء من سلسلة Flutter. اقرأ المقال الرئيسي.
نشر تطبيق Flutter على Google Play طقس عبور. صيغة Android App Bundle (AAB) المفروضة من Google منذ 2021، التوقيع على مستويين عبر Play App Signing، tracks النشر التدريجي والإلزام باستهداف Android 15 أدنى.
المتطلبات
- Flutter SDK 3.41+ شغّال
- تطبيق Flutter يُصرَّف بلا خطأ في debug
- JDK 17 متاح (مدمج في Android Studio حديث)
- حساب Google Play Developer نشط (25 USD مرة واحدة، بطاقة)
- اسم package فريد (مثل
com.votresociete.votreapp) — يُجمَّد بعد أول upload - 2-3 ساعات أول مرة
الخطوة 1 — توليد upload keystore
سلسلة توقيع Play تتكوّن من مفتاحين: upload key الذي تحفظه محلياً، وapp signing key الذي يديره Google. هذا النظام المزدوج يحميك: إن فقدت upload key، Google يُولّد لك جديداً.
# macOS / Linux
keytool -genkey -v -keystore ~/upload-keystore.jks \
-keyalg RSA -keysize 2048 -validity 10000 \
-alias upload -storetype JKS
# Windows
keytool -genkey -v -keystore $env:USERPROFILE\upload-keystore.jks `
-keyalg RSA -keysize 2048 -validity 10000 `
-alias upload -storetype JKS
الأداة تطلب كلمة سر لـ keystore (احفظها)، الاسم، المنظمة. أحفظ الملف بأمان.
الخطوة 2 — إنشاء android/key.properties
storePassword=mot-de-passe-keystore
keyPassword=mot-de-passe-cle
keyAlias=upload
storeFile=/Users/votrenom/upload-keystore.jks
على Windows، المسار بـ double backslash. أضف فوراً android/key.properties إلى .gitignore:
echo "android/key.properties" >> .gitignore
الخطوة 3 — توصيل التوقيع في build.gradle
المشاريع الحديثة تستخدم Gradle Kotlin DSL. افتح android/app/build.gradle.kts وأضف في الأعلى:
import java.util.Properties
import java.io.FileInputStream
val keystoreProperties = Properties()
val keystorePropertiesFile = rootProject.file("key.properties")
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}
داخل android { ... }:
android {
signingConfigs {
create("release") {
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["keyPassword"] as String
storeFile = keystoreProperties["storeFile"]?.let { file(it as String) }
storePassword = keystoreProperties["storePassword"] as String
}
}
buildTypes {
release {
signingConfig = signingConfigs.getByName("release")
}
}
}
الخطوة 4 — Versioning مع pubspec.yaml
version: 1.0.0+1
الصيغة MAJOR.MINOR.PATCH+BUILD. ما قبل + هو versionName، ما بعد + هو versionCode (عدد متزايد). Google Play لا يقبل إعادة استخدام رقم منشور.
الخطوة 5 — تحقّق من targetSdk
منذ 31 أغسطس 2025، Google Play يفرض Android 15 (API 35) أدنى.
defaultConfig {
applicationId = "com.votresociete.votreapp"
minSdk = 23
targetSdk = 35
versionCode = flutter.versionCode
versionName = flutter.versionName
}
الخطوة 6 — بناء App Bundle
flutter clean
flutter pub get
flutter build appbundle
البناء يدوم 2-5 دقائق. النتيجة في:
build/app/outputs/bundle/release/app-release.aab
الملف يزن نمطياً 15-40 ميغا. لتفعيل obfuscation كود Dart:
flutter build appbundle --obfuscate \
--split-debug-info=build/app/outputs/symbols
الرموز في --split-debug-info تخدم لفكّ obfuscation stack traces في الإنتاج — احفظها، بدونها تقارير Crashlytics غير مقروءة.
الخطوة 7 — اختبار AAB محلياً بـ bundletool
# نزّل bundletool من github.com/google/bundletool/releases
java -jar bundletool.jar build-apks \
--bundle=app-release.aab \
--output=app.apks \
--mode=universal
java -jar bundletool.jar install-apks --apks=app.apks
وضع universal يولّد APK واحدة بكل المعماريات. --mode=default لقياس الحجم الحقيقي المُسلَّم.
الخطوة 8 — إنشاء التطبيق في Play Console
اتّصل بـ play.google.com/console. انقر «Créer une application». املأ: الاسم (30 حرف)، اللغة، نوع التطبيق، مجاني أم مدفوع (نهائي)، التصريحات.
الخطوة 9 — Upload على track Internal testing
- Internal testing — حتى 100 مختبر، متاح في دقائق. مثالي لاختبار build بلا review.
- Closed testing — قوائم مختبرين بإيميل، خاضع لـ review.
- Open testing — متاح لكل من له الرابط.
- Production — متاح على Play Store. review إلزامي (2-7 أيام).
ابدأ دائماً بـ Internal testing. Test ← Tests internes، «Créer une nouvelle version»، حمّل app-release.aab، release notes، ثم «Démarrer le déploiement».
الخطوة 10 — الترقية التدريجية نحو الإنتاج
اضبط rollout تدريجي: 5% في يوم 1، ثم 20%، 50%، 100% على بضعة أيام. راقب tab Android Vitals: عتبات Google 1.09% sessions بـ crash و0.47% بـ ANR. منتج صحي حوالي 0.2% crashes.
تحسين بطاقة Play Store
العنوان 30 حرف. كن صريحاً حول الوظيفة. الوصف القصير 80 حرف. الوصف الطويل حتى 4000 حرف. اللقطات 2-8 لكل جهاز؛ إضافة عنوان قصير على كل لقطة يربح 30-50% معدل نقر. الأيقونة مقروءة عند 48×48.
الامتثال لسياسات Google Play
- الأذون الحساسة — كل أذن يجب تبريره باستخدام مرئي.
- سياسة الخصوصية — إلزامية بمجرد جمع بيانات شخصية. URL عام مستقرّ.
- قسم «Sécurité des données» — إعلان صريح لكل نوع بيانات.
- القاصرون والصحة — قواعد إضافية (COPPA/HIPAA).
ومع iOS؟
المسار المتوازي: flutter build ipa بدل flutter build appbundle، توقيع عبر شهادة توزيع Apple، رفع عبر Xcode أو Transporter. Apple يطلب Mac فيزيائياً؛ على Windows/Linux، Codemagic أو GitHub Actions مع macOS runner.
أخطاء شائعة
| الخطأ | السبب | الحل |
|---|---|---|
| «Keystore was tampered with» | كلمة سر خاطئة | تحقّق storePassword وkeyPassword |
| «signed with a key not previously used» | غيّرت upload key | احفظ واحدة. للفقدان، اتصل بدعم Play |
| «R8: Type not present» | R8 يحذف class مستخدم بـ reflection | أضف -keep class في proguard-rules.pro |
| «Version code already used» | versionCode ≤ منشور | زِد الجزء بعد + في pubspec.yaml |
| «Target SDK too low» | أقل من 35 | targetSdk = 35 |
| Bundle > 200 ميغا | حد Play Store (انتقل من 150 إلى 200 ميغا يناير 2026) | Play Asset Delivery أو احذف موارد |
أسئلة شائعة
هل يمكن نشر APK بدل AAB؟ لا لتطبيق جديد. Play يرفض APKs منذ أغسطس 2021.
كم تستغرق review؟ للنشر الأول 3-7 أيام. للتحديثات ساعات إلى يوم.
كيف نؤتمت build وupload؟ fastlane مع ملحق supply؛ أو Codemagic/Bitrise.
ماذا أفعل إن فقدت upload keystore؟ اتصل بدعم Play Console. يولّدون upload key جديد مرتبط بـ app signing key الموجود.
كم تكلف Play Console؟ 25 USD مرة واحدة. لا رسوم متكرّرة. Apple 99 USD/سنة بالمقارنة.