شروع به کار با «پیام‌رسانی ابریِ Firebase» در برنامه‌های Android

انتخاب پلاتفرم: iOS+ Android وب Flutter Unity C++


این راهنما نحوه شروع به کار با Firebase Cloud Messaging را در برنامه‌های کارخواه Android شما شرح می‌دهد تا بتوانید پیام‌ها را به‌طور قابل‌اعتماد ارسال کنید.

FCM مشتریان به دستگاه‌های دارای Android نسخه ۷.۰ یا بالاتر نیاز دارند که برنامه «فروشگاه Google Play» نیز در آن‌ها نصب شده باشد، یا شبیه‌سازی که Android نسخه ۷.۰ را با Google API اجرا کند. توجه داشته باشید که شما محدود به استقرار برنامه‌های Android خود ازطریق «فروشگاه Google Play» نیستید.

راه‌اندازی کیت توسعه نرم‌افزار

اگر قبلاً این کار را نکرده‌اید، Firebase را به پروژه Android خود اضافه کنید.

برای داشتن تجربه بهینه با FCM، اکیداً توصیه می‌کنیم Google Analytics را در پروژه‌تان فعال کنید. Google Analytics برای گزارش‌دهی تحویل پیام برای FCM الزامی است.

ویرایش مانیفست برنامه

مورد زیر را به مانیفست برنامه‌تان اضافه کنید:

  • سرویسی که FirebaseMessagingService را گسترش می‌دهد. اگر می‌خواهید هرگونه مدیریت پیام فراتر از دریافت اعلان در برنامه‌های پس‌زمینه انجام دهید، این مورد الزامی است. برای دریافت اعلان در برنامه‌های پیش‌زمینه، دریافت بارداده، و غیره، باید این سرویس را گسترش دهید.
  • <service
        android:name=".java.MyFirebaseMessagingService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
  • (اختیاری) در عنصر برنامه، عناصر فراداده برای تنظیم نماد و رنگ اعلان پیش‌فرض. ‫Android هرگاه پیام‌های ورودی به‌طور صریح نماد یا رنگ را تنظیم نکنند از این مقادیر استفاده می‌کند.
  • <!-- Set custom default icon. This is used when no icon is set for incoming notification messages.
         See README(https://goo.gl/l4GJaQ) for more. -->
    <meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@drawable/ic_stat_ic_notification" />
    <!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
         notification message. See README(https://goo.gl/6BKBk7) for more. -->
    <meta-data
        android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/colorAccent" />
  • (اختیاری) از Android 8.0 (سطح میانای برنامه‌سازی کاربردی ۲۶) و بالاتر، کانال‌های اعلان پشتیبانی می‌شود و توصیه می‌شود. ‫FCM کانال اعلان پیش‌فرضی با تنظیمات پایه ارائه می‌دهد. اگر ترجیح می‌دهید کانال پیش‌فرض خودتان را ایجاد و استفاده کنید، default_notification_channel_id را روی شناسه شیء کانال اعلان خودتان تنظیم کنید، همان‌طور که نشان داده شده است؛ FCM هرگاه پیام‌های ورودی به‌طور صریح کانال اعلانی را تنظیم نکنند، از این مقدار استفاده خواهد کرد. برای کسب اطلاعات بیشتر، مدیریت کانال‌های اعلان را ببینید.
  • <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="@string/default_notification_channel_id" />

درخواست اجازه اعلان زمان اجرا در Android 13 و نسخه‌های بالاتر

‫Android 13 اجازه زمان اجرای جدیدی برای نمایش اعلان‌ها معرفی می‌کند. این موضوع بر همه برنامه‌هایی که در Android نسخه ۱۳ یا بالاتر اجرا می‌شوند و از اعلان‌های FCM استفاده می‌کنند تأثیر می‌گذارد.

به‌طور پیش‌فرض، کیت توسعه نرم‌افزار FCM (نسخه ۲۳.۰.۶ یا بالاتر) شامل اجازه POST_NOTIFICATIONS تعریف‌شده در مانیفست است. بااین‌حال، برنامه شما باید نسخه زمان اجرای این اجازه را نیز بااستفاده از ثابت android.permission.POST_NOTIFICATIONS درخواست کند. تا زمانی‌که کاربر این اجازه را اعطا نکرده باشد، برنامه‌تان مجاز به نمایش اعلان‌ها نخواهد بود.

برای درخواست اجازه زمان اجرای جدید:

Kotlin

// Declare the launcher at the top of your Activity/Fragment:
private val requestPermissionLauncher = registerForActivityResult(
    ActivityResultContracts.RequestPermission(),
) { isGranted: Boolean ->
    if (isGranted) {
        // FCM SDK (and your app) can post notifications.
    } else {
        // TODO: Inform user that that your app will not show notifications.
    }
}

private fun askNotificationPermission() {
    // This is only necessary for API level >= 33 (TIRAMISU)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
            PackageManager.PERMISSION_GRANTED
        ) {
            // FCM SDK (and your app) can post notifications.
        } else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
            // TODO: display an educational UI explaining to the user the features that will be enabled
            //       by them granting the POST_NOTIFICATION permission. This UI should provide the user
            //       "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.
            //       If the user selects "No thanks," allow the user to continue without notifications.
        } else {
            // Directly ask for the permission
            requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
        }
    }
}

Java

// Declare the launcher at the top of your Activity/Fragment:
private final ActivityResultLauncher<String> requestPermissionLauncher =
        registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
            if (isGranted) {
                // FCM SDK (and your app) can post notifications.
            } else {
                // TODO: Inform user that that your app will not show notifications.
            }
        });

private void askNotificationPermission() {
    // This is only necessary for API level >= 33 (TIRAMISU)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
                PackageManager.PERMISSION_GRANTED) {
            // FCM SDK (and your app) can post notifications.
        } else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
            // TODO: display an educational UI explaining to the user the features that will be enabled
            //       by them granting the POST_NOTIFICATION permission. This UI should provide the user
            //       "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.
            //       If the user selects "No thanks," allow the user to continue without notifications.
        } else {
            // Directly ask for the permission
            requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS);
        }
    }
}

به‌طور کلی، باید واسط کاربری‌ای نمایش دهید که ویژگی‌هایی را که درصورت اعطای اجازه به برنامه برای پست کردن اعلان‌ها فعال خواهد شد برای کاربر توضیح دهد. این واسط کاربر باید گزینه‌هایی برای موافقت یا رد کردن دراختیار کاربر قرار دهد، مثل دکمه‌های بسیارخوب و نه، سپاس. اگر کاربر تأیید را انتخاب کرد، مستقیماً اجازه را درخواست کنید. اگر کاربر نه، متشکرم را انتخاب کرد، به کاربر اجازه دهید بدون اعلان ادامه دهد.

برای روال‌های مطلوب بیشتر درباره اینکه برنامه‌تان چه زمانی باید اجازه POST_NOTIFICATIONS را از کاربر درخواست کند، به اجازه زمان اجرای اعلان مراجعه کنید.

اجازه‌های اعلان برای برنامه‌هایی که Android 12L (سطح میانای برنامه‌سازی کاربردی ۳۲) یا پایین‌تر را هدف‌یابی می‌کنند

Android به‌طور خودکار اولین باری که برنامه‌تان کانال اعلان ایجاد می‌کند، از کاربر اجازه می‌خواهد، به‌شرطی که برنامه در پیش‌زمینه باشد. بااین‌حال، هشدارهای مهمی درباره زمان ایجاد کانال و درخواست‌های اجازه وجود دارد:

  • اگر برنامه‌تان اولین کانال اعلان خود را هنگام اجرا در پس‌زمینه ایجاد کند (که کیت توسعه نرم‌افزار FCM هنگام دریافت اعلان FCM این کار را انجام می‌دهد)، Android اجازه نمی‌دهد اعلان نمایش داده شود و تا دفعه بعدی که برنامه‌تان باز می‌شود، از کاربر درخواست اجازه اعلان نمی‌کند. این یعنی هر اعلانی که قبل‌از باز شدن برنامه‌تان و پذیرفتن اجازه توسط کاربر دریافت شود ازدست خواهد رفت.
  • اکیداً توصیه می‌کنیم برنامه‌تان را به‌روز کنید تا Android نسخه ۱۳ یا بالاتر را هدف قرار دهد و بتواند از میاناهای برنامه‌سازی کاربردی پلاتفرم برای درخواست اجازه استفاده کند. اگر این کار امکان‌پذیر نیست، برنامه‌تان باید قبل‌از ارسال هرگونه اعلان به برنامه، کانال‌های اعلان ایجاد کند تا کادر گفتگوی اجازه اعلان را راه‌اندازی کند و مطمئن شود هیچ اعلانی ازدست نمی‌رود. برای اطلاعات بیشتر، اجازه اعلان بهترین روش‌ها را ببینید.

اختیاری: برداشتن اجازه POST_NOTIFICATIONS

به‌طور پیش‌فرض، کیت توسعه نرم‌افزار FCM شامل اجازه POST_NOTIFICATIONS است. اگر برنامه‌تان از پیام‌های اعلان استفاده نمی‌کند (چه ازطریق اعلان‌های FCM، چه ازطریق کیت توسعه نرم‌افزار دیگری، یا مستقیماً توسط برنامه‌تان پست شده باشد) و نمی‌خواهید برنامه‌تان این اجازه را داشته باشد، می‌توانید آن را بااستفاده از نشانگر remove ادغام‌کننده مانیفست بردارید. به‌خاطر داشته باشید که برداشتن این اجازه مانع از نمایش همه اعلان‌ها می‌شود، نه فقط اعلان‌های FCM. موارد زیر را به فایل مانیفست برنامه‌تان اضافه کنید:

<uses-permission android:name="android.permission.POST_NOTIFICATIONS" tools:node="remove"/>

دسترسی به «شناسه نصب Firebase»

در راه‌اندازی اولیه برنامه‌تان، کیت توسعه نرم‌افزار FCM نمونه برنامه را در FCM ثبت می‌کند و شناسه‌ای برای نمونه برنامه برمی‌گرداند. اگر می‌خواهید نمونه‌های برنامه را هدف‌یابی کنید، باید با گسترش دادن FirebaseMessagingService و ملغی کردن onRegistered() به این شناسه دسترسی پیدا کنید. به‌عنوان روال مطلوب، جدیدترین شناسه به‌روزرسانی‌شده را بازیابی کنید زیرا شناسه می‌تواند پس‌از راه‌اندازی اولیه تغییر کند.

فعال کردن ثبت‌نام ازطریق «شناسه نصب Firebase»

برای فعال کردن ثبت نمونه برنامه با FCM بااستفاده از شناسه نصب Firebase (FID)، پرچم فراداده زیر را به فایل AndroidManifest.xml اضافه کنید:
<meta-data
    android:name="firebase_messaging_installation_id_enabled"
    android:value="true" />

پیاده‌سازی پاسخ تماس onRegistered()

نمونه‌های برنامه پس‌از ثبت شدن در FCM بااستفاده از «شناسه نصب Firebase» (FID) هدف‌یابی می‌شوند. برای بازیابی FID پس‌از ثبت‌نام، onRegistered() را پیاده‌سازی کنید. پس‌از ثبت نمونه برنامه، FCM SDK به‌طور خودکار تغییرات FID را پایش می‌کند و وقتی تغییری تشخیص داده شود، با تابع برگشتی تماس می‌گیرد. وقتی مقداردهی اولیه خودکار فعال باشد، کیت توسعه نرم‌افزار FCM به‌طور خودکار با پسای FCM همگام‌سازی می‌شود تا ثبت را تازه نگه دارد و فراخوانی برگشتی را فرا می‌خواند تا مطمئن شود سرور برنامه شما شناسه فعلی را دارد. برای محافظت دربرابر ازدست رفتن FID یا قدیمی شدن FID، باید هرگاه این برگشت به تماس راه‌اندازی می‌شود، FID را به سرور برنامه‌تان ارسال کنید.

Kotlin

  /**
   * There are three scenarios when `onRegistered` is called:
   * 1) Every time a manual `register()` call finishes successfully
   * 2) Whenever the FID is changed and the app is re-registered with FCM via the new FID.
   * 3) Automatically on app startup or routine sync when auto-initialization is enabled.
   * Under #2, there are three scenarios when the existing FID is changed:
   * A) App is restored to a new device
   * B) User uninstalls/reinstalls the app
   * C) User clears app data
   */
  override fun onRegistered(installationId: String) {
      Log.d(TAG, "Registered installation ID: $installationId")

      // Send the Firebase Installation ID to your app server.
      sendRegistrationToServer(installationId)
  }
    

جاوا

  /**
   * There are three scenarios when `onRegistered` is called:
   * 1) Every time a manual `register()` call finishes successfully
   * 2) Whenever the FID is changed and the app is re-registered with FCM via the new FID
   * 3) Automatically on app startup or routine sync when auto-initialization is enabled.
   * Under #2, there are three scenarios when the existing FID is changed:
   * A) App is restored to a new device
   * B) User uninstalls/reinstalls the app
   * C) User clears app data
   */
  @Override
  public void onRegistered(@NonNull String installationId) {
      Log.d(TAG, "Registered installation ID: " + installationId);

      // Send the Firebase Installation ID to your app server.
      sendRegistrationToServer(installationId);
  }
    

ثبت دستی هنگام غیرفعال بودن مقداردهی اولیه خودکار

اگر باید مقداردهی اولیه خودکار را غیرفعال کنید، FCM SDK به‌طور خودکار همگام‌سازی نمی‌شود یا onRegistered() فراخوانی برگشتی را در راه‌اندازی راه‌اندازی نمی‌کند. اکیداً توصیه می‌شود که پس‌از اعطای اجازه‌های اعلان، راه‌اندازی خودکار را دوباره فعال کنید. برای کسب اطلاعات بیشتر، به فعال کردن مجدد مقداردهی اولیه خودکار مراجعه کنید.

اگر باید مقداردهی اولیه خودکار غیرفعال بماند، FirebaseMessaging.getInstance().register() را در راه‌اندازی برنامه فراخوانی کنید تا ثبت‌نام و ارائه FID ازطریق onRegistered() بازخوان فعال شود. می‌توانید این تماس را در onCreate() روش اصلی‌تان Activity اجرا کنید.

Kotlin

  // Trigger manual registration if auto-initialization is turned off.
  // Consider calling this every time the app starts to guarantee sync status.
  FirebaseMessaging.getInstance().register()
      .addOnCompleteListener(this) { task ->
        if (!task.isSuccessful()) {
          // Registration failed. Consider retrying the registration with exponential backoff.
          Log.w(TAG, "Failed to register with Firebase Cloud Messaging", task.exception)
        }
        // Success! The Firebase Installation ID can be used to target messages to this app
        // instance and will be delivered asynchronously to your `onRegistered()` callback.
      }
    

جاوا

  // Trigger manual registration if auto-initialization is turned off.
  // Consider calling this every time the app starts to guarantee sync status.
  FirebaseMessaging.getInstance().register()
      .addOnCompleteListener(task -> {
        if (!task.isSuccessful()) {
          // Registration failed. Consider retrying the registration with exponential backoff.
          Log.w(TAG, "Failed to register with Firebase Cloud Messaging", task.exception)
        }
        // Success! The Firebase Installation ID can be used to target messages to this app
        // instance and will be delivered asynchronously to your `onRegistered()` callback.
      });
    

دسترسی به کد ثبت FCM (منسوخ)

در راه‌اندازی اولیه برنامه‌تان، کیت توسعه نرم‌افزار FCM یک کد ثبت برای نمونه برنامه کارخواه تولید می‌کند. اگر می‌خواهید نمونه‌های تک‌برنامه‌ای را هدف‌یابی کنید یا گروه‌های دستگاه ایجاد کنید، باید با گسترش دادن FirebaseMessagingService و ملغی کردن onNewToken به این کد دسترسی پیدا کنید. چون ممکن است پس‌از راه‌اندازی اولیه، ژتون چرخش داشته باشد، اکیداً توصیه می‌شود جدیدترین ژتون ثبت به‌روزشده را بازیابی کنید.

در شرایط زیر ممکن است کد ثبت تغییر کند:

  • برنامه در دستگاه جدیدی بازیابی می‌شود
  • کاربر برنامه را حذف نصب/بازنصب می‌کند
  • کاربر داده‌های برنامه را پاک کند.

بازیابی کد ثبت کنونی

وقتی لازم است داده‌واحد فعلی را بازیابی کنید، FirebaseMessaging.getInstance().getToken() را فراخوانی کنید:

Kotlin

FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
    if (!task.isSuccessful) {
        Log.w(TAG, "Fetching FCM registration token failed", task.exception)
        return@OnCompleteListener
    }

    // Get new FCM registration token
    val token = task.result

    // Log and toast
    val msg = getString(R.string.msg_token_fmt, token)
    Log.d(TAG, msg)
    Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
})

Java

FirebaseMessaging.getInstance().getToken()
    .addOnCompleteListener(new OnCompleteListener<String>() {
        @Override
        public void onComplete(@NonNull Task<String> task) {
          if (!task.isSuccessful()) {
            Log.w(TAG, "Fetching FCM registration token failed", task.getException());
            return;
          }

          // Get new FCM registration token
          String token = task.getResult();

          // Log and toast
          String msg = getString(R.string.msg_token_fmt, token);
          Log.d(TAG, msg);
          Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
        }
    });

نظارت بر تولید کد

هرگاه کد جدیدی تولید شود، فراخوانی برگشتی onNewToken اجرا می‌شود.

Kotlin

/**
 * Called if the FCM registration token is updated. This may occur if the security of
 * the previous token had been compromised. Note that this is called when the
 * FCM registration token is initially generated so this is where you would retrieve the token.
 */
override fun onNewToken(token: String) {
    Log.d(TAG, "Refreshed token: $token")

    // If you want to send messages to this application instance or
    // manage this apps subscriptions on the server side, send the
    // FCM registration token to your app server.
    sendRegistrationToServer(token)
}

Java

/**
 * There are two scenarios when onNewToken is called:
 * 1) When a new token is generated on initial app startup
 * 2) Whenever an existing token is changed
 * Under #2, there are three scenarios when the existing token is changed:
 * A) App is restored to a new device
 * B) User uninstalls/reinstalls the app
 * C) User clears app data
 */
@Override
public void onNewToken(@NonNull String token) {
    Log.d(TAG, "Refreshed token: " + token);

    // If you want to send messages to this application instance or
    // manage this apps subscriptions on the server side, send the
    // FCM registration token to your app server.
    sendRegistrationToServer(token);
}

پس‌از دریافت کد، می‌توانید آن را به سرور برنامه‌تان ارسال کنید و بااستفاده از روش دلخواهتان آن را ذخیره کنید.

بررسی «خدمات Google Play»

برنامه‌هایی که به کیت توسعه نرم‌افزار «خدمات Play» متکی هستند باید همیشه قبل‌از دسترسی به ویژگی‌های «خدمات Google Play»، دستگاه را ازنظر وجود APK سازگار با «خدمات Google Play» بررسی کنند. برای کسب اطلاعات بیشتر، راه‌اندازی خدمات Google Play را ببینید. توصیه می‌شود این کار را در دو جا انجام دهید: در روش onCreate() فعالیت اصلی، و در روش onResume() آن. بررسی در onCreate() تضمین می‌کند که برنامه بدون بررسی موفقیت‌آمیز قابل‌استفاده نباشد. بررسی در onResume() تضمین می‌کند که اگر کاربر ازطریق روش دیگری، مثلاً ازطریق دکمه بازگشت، به برنامه درحال اجرا برگردد، بررسی همچنان انجام شود.

اگر دستگاه نسخه سازگاری از «خدمات Google Play» نداشته باشد، برنامه شما می‌تواند GoogleApiAvailability.makeGooglePlayServicesAvailable() را فراخوانی کند تا به کاربران اجازه دهد «خدمات Google Play» را از «فروشگاه Play» بارگیری کنند.

جلوگیری از مقداردهی اولیه خودکار

وقتی ثبت FCM ایجاد می‌شود، کتابخانه شناسه و داده‌های پیکربندی را در Firebase بارگذاری می‌کند. اگر ترجیح می‌دهید از ثبت خودکار جلوگیری کنید، با افزودن این مقادیر فراداده به AndroidManifest.xml، جمع‌آوری Analytics و مقداردهی اولیه خودکار FCM را غیرفعال کنید (باید هر دو را غیرفعال کنید):

<meta-data
    android:name="firebase_messaging_auto_init_enabled"
    android:value="false" />
<meta-data
    android:name="firebase_analytics_collection_enabled"
    android:value="false" />

فعال کردن مجدد مقداردهی اولیه خودکار

برای فعال کردن مجدد مقداردهی اولیه خودکار FCM، تماس زمان اجرا برقرار کنید:

Kotlin

Firebase.messaging.isAutoInitEnabled = true

Java

FirebaseMessaging.getInstance().setAutoInitEnabled(true);

برای فعال کردن مجدد مجموعه Analytics، روش setAnalyticsCollectionEnabled() کلاس FirebaseAnalytics را فراخوانی کنید. برای مثال:

setAnalyticsCollectionEnabled(true);

این مقادیر پس‌از تنظیم شدن، در بازراه‌اندازی‌های برنامه حفظ می‌شوند.

ارسال پیام اعلان

برای اطمینان از اینکه کارخواه Android شما به‌درستی راه‌اندازی شده است، می‌توانید بااستفاده از دستورالعمل‌های زیر، پیام اعلان آزمایشی ارسال کنید:

  1. برنامه را در دستگاه هدف نصب و اجرا کنید.

  2. مطمئن شوید برنامه در پس‌زمینه دستگاه باشد.

  3. در کنسول Firebase، به DevOps و تعامل > پیام‌رسانی بروید

  4. پویشی ایجاد کنید.

    • اگر این اولین پیام شما است:

      1. ایجاد اولین پویش را انتخاب کنید.

      2. پیام‌های اعلان Firebase را انتخاب کنید و سپس ایجاد را انتخاب کنید.

    • اگر قبلاً پویش ایجاد کرده‌اید:

      1. در برگه پویش‌ها، پویش جدید را انتخاب کنید.

      2. روی اعلان‌ها کلیک کنید.

  5. نوشتار پیام را وارد کنید. همه فیلدهای دیگر اختیاری هستند.

  6. ارسال پیام آزمایشی را از قاب سمت راست انتخاب کنید.

  7. در فیلد برچسب‌گذاری‌شده افزودن کد ثبت FCM، کد ثبت را که در بخش قبلی این راهنما دریافت کرده‌اید وارد کنید.

  8. آزمایش را انتخاب کنید.

دستگاه کارخواه هدف، با برنامه در پس‌زمینه، باید اعلان را دریافت کند.

برای دریافت اطلاعات آماری درباره تحویل پیام به برنامه‌تان، به داشبورد DevOps و تعامل > پیام‌رسانی > گزارش‌ها در کنسول Firebase بروید. این داشبورد تعداد پیام‌های ارسال‌شده و بازشده در دستگاه‌های Apple و Android را به‌همراه داده‌های «ظهورها» (اعلان‌هایی که کاربران دیده‌اند) برای برنامه‌های Android ثبت می‌کند.

مراحل بعدی

پس‌از تکمیل مراحل راه‌اندازی، چند گزینه برای ادامه کار با FCM برای Android وجود دارد: