onesignal pushe.co s-3.664-0.699-5.062-2.099c-1.397-1.398-2.097-3.087-2.097-5.065s0.699-3.667,2.097-5.065c1.397-1.399,3.085-2.099,5.062-2.099 s3.664,0.699,5.062,2.099C223.888,120.556,224.587,122.244,224.587,124.223z"/>

راه اندازی پوش‌پل در Android Studio

نمونه‌کد و رفع‌خطا

  • برای مشاهده‌ی نمونه‌کد پروژه‌ی پوش‌پل در اندروید‌استودیو می‌توانید به گیت‌هاب پوش‌پل
  • در صورت وجود هرگونه مشکل ابتدا بخش عیب‌یابی را بررسی کنید و در صورت نبود راه‌حل آن‌را در issues گیت‌هاب و یا پشتیبانی گزارش دهید.

راه‌اندازی

اضافه کردن کتابخانه

  • در build.gradle مربوط به اپلیکیشن وارد شوید. مراقب باشید اشتباها به فایل gradle مربوط به پروژه وارد نشوید.
  • کد زیر را در dependencies اضافه کنید.
implementation 'com.pushpole.android:pushsdk:1.0.2'

برای استفاده از قابلیت های اندروید 8 مانند notification channel بایستی TargetSDK برابر 26 یا بالاتر باشد.

  • در بالای صفحه سمت راست sync را بزنید تا gradle سینک شود.

در فایل build.gradle مربوط به پروژه مطمئن شوید که لینک های لازم برای دریافت پوش‌پل و کتابخانه های ساپورت موجود هستند

allprojects {
    repositories {
        google()
        jcenter()
        //...
    }
}
  • در صورتی که هنگام سینک به خطایی برخوردید ابتدا به دنبال خطای خود در بخش عیب‌یابی بگردید.

تغییرات AndroidManifest.xml

  • وارد پنل کاربری پوش‌پل شوید و در قسمت اپلیکیشن‌ها، روی آیکون دریافت منیفست بزنید (این آیکون را با کلیک بر روی علامت سه نقطه‌ی گوشه‌ی کارت اپلیکیشن می توانید ببینید).
  • منیفست اندروید استودیو را انتخاب کنید و محتویات آن را با توجه به راهنمای موجود، در قسمت‌های مربوطه کپی کرده و به AndroidManifest.xml پروژه خود اضافه کنید.
  • برای امکان استفاده از سرویس‌های موقعیت‌محور پوش‌پل لازم است که دسترسی استفاده از موقعیت مکانی کاربر را در فایل منیفست پروژه خود قرار دهید.
    برای اضافه کردن این دسترسی، متن زیر را درون تگ manifest در فایل منیفست خود بگذارید.
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

کدام امکانات پوش‌پل موقعیت‌محور محسوب می‌شوند؟

امکانات زیر موقعیت‌محور هستند و برای استفاده از آن‌ها دسترسی موقعیت مکانی لازم است:

  • مشاهده آمار موقعیت جغرافیایی کاربران
  • ارسال اعلان به کاربران بر اساس موقعیت مکانی آن‌ها

تغییرات MainActivity.java

  • در قسمت import ، کد روبرو را وارد کنید.
import com.pushpole.sdk.PushPole;
  • در onCreate کد روبرو را وارد کنید.
PushPole.initialize(context,true);
  • اگر در تابع بالا مقدار true گذاشته شود و دستگاه کاربر شما گوگل پلی سرویس نداشته باشد و یا آن را غیرفعال کرده باشد دیالوگی باز می شود و به کاربر پیشنهاد نصب گوگل پلی سرویس داده می شود تا قابلیت دریافت و ارسال پوش نوتیفیکیشن فعال شود. اگر در تابع بالا false را قرار دهید، این دیالوگ برای کاربر باز نمی شود.

تست

پس از اینکه فایل کتابخانه را مطابق با آموزش داده شده نصب کردید، میتوانید پروژه را اجرا و بر روی دستگاه خود نصب و تست کنید.

  • به صفحه نصب ها بروید.
  • بعد از گذشت زمان کوتاهی یک ردیف مشخصات نصب به لیست نصب ها اضافه می شود که متعلق به گوشی شما است.
  • یک اعلان تست ارسال کنید.دقت کنید تلفن همراه شما به اینترنت متصل باشد.

اگر می خواهید اپلیکیشن را بر روی Emulator تست کنید، بر روی ایمولاتور شما باید Google API نصب باشد.

راه‌اندازی پیشرفته

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

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

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

برای رفع این مشکل لازم است مراحل زیر را در راه اندازی طی کنید:

  1. سرویس گوش دهنده FCM پوش‌پل را غیر فعال کنید
  2. سرویس گوش دهنده FCM خود را فعال کنید
  3. با دریافت پیغام‌های FCM و رخ دادن رویداد‌های مربوط به آن در سرویس خود، پوش‌پل را مطلع کنید

با طی کردن این مراحل، تنها گوش دهنده به پیغام‌های FCM گوش دهنده تعریف شده شما خواهد بود که همه‌ی پیغام‌های FCM را دریافت خواهد کرد و پیغام‌های مربوط به پوش‌پل را به کتابخانه‌ی پوش‌پل تحویل می‌دهد.

در ادامه نحوه اعمال این مراحل را قدم به فدم توضیح می‌دهیم:

۱. غیر فعال کردن سرویس FCM پوش‌پل

برای غیر فعال کردن سرویس FCM پوش‌پل، عبارت زیر را در تگ <application> فایل منیفست خود بگذارید:

<service
    android:name="com.pushpole.sdk.fcm.FcmService" 
    tools:node="remove" />

در صورتی که با پیغام خطا مواجه شدید بررسی کنید که عبارت xmlns:tools="http://schemas.android.com/tools" در پارامتر‌های تگ <manifest> ابتدای فایل وجود داشته باشد، به این شکل:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="..."/>

۲. ایجاد سرویس FCM برنامه

در صورتی که از قبل سرویس FCM برای برنامه‌ی خود ایجاد کرده‌اید می‌توانید از این مرحله بگذرید.

یک کلاس جدید بسازید که از کلاس FirebaseMessagingService ارث می‌برد. در مثال زیر اسم کلاس را MyFcmService گذاشتیم ولی شما می‌توانید اسم دلخواه خود را استفاده کنید.

public class MyFcmService extends FirebaseMessagingService {

}

سرویس جدید را با گذاشتن عبارت زیر در تگ <application> فایل منیفست خود فعال کنید. توجه داشته باشید که نام کلاس را با نام کلاس تعریف شده خود جایگزین کنید.

<service android:name=".MyFcmService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

۳. رساندن پیغام‌ها و رویداد‌ها به پوش‌پل

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

public class MyFcmService extends FirebaseMessagingService {
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        if (PushPole.getFcmHandler(this).onMessageReceived(remoteMessage)) {
            // Message belongs to PushPole, no further action needed
            return;   
        }

        // Message does not belong to PushPole, process message...
    }

    @Override
    public void onNewToken(String s) {
        PushPole.getFcmHandler(this).onNewToken(s);
    }

    @Override
    public void onMessageSent(String s) {
        PushPole.getFcmHandler(this).onMessageSent(s);
    }

    @Override
    public void onSendError(String s, Exception e) {
        PushPole.getFcmHandler(this).onSendError(s, e);
    }

    @Override
    public void onDeletedMessages() {
        PushPole.getFcmHandler(this).onDeletedMessages();
    }    
}

هر بار که یک پیغام FCM به برنامه شما می‌رسد، تابع onMessageReceived کلاس شما صدا زده می‌شود. همانطور که در مثال بالا مشاهده می‌کنید در پیاده‌سازی این تابع، شما با استفاده از عبارت زیر پوش‌پل را از دریافت پیغام مطلع می‌کنید:

PushPole.getFcmHandler(this).onMessageRecevied(remoteMessage)

با این کار پیغام به دست پوش‌پل نیز می‌رسد و اگر پیغام مربوط به کتابخانه‌ی پوش‌پل باشد عملیات لازم بر روی آن انجام می‌شود. در صورتی که پیغام مربوط به پوش‌پل باشد عبارت بالا مقدار true بر می‌گرداند و شما نیازی نیست عملیات بیشتری روی این پیغام انجام دهید. در صورتی که از عبارت بالا مقدار false گرفتید به این معنی است که پیغام مربوط به پوش‌پل نیست و شما باید بسته به نیاز خود عملیات مورد نظر را برای آن انجام دهید.

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

امکانات

PushPoleId

این شناسه برای یکتاسازی دستگاه‌هایی که پوش‌پل در آن‌ها رجیسترشده استفاده‌می‌شود. برای گرفتن شناسه‌ی پوش‌پل دستگاهی که برنامه در آن نصب شده از کد زیر استفاده کنید.

String pushpoleId = PushPole.getId(context);

آن مقدار را از JSON دریافتی می‌گیرید و برحسب اینکه می‌خواهید با آن چه کاری انجام دهید، کد لازم را اضافه می‌کنید.

رسیورهای دریافت رویدادهای اعلان

ترجیحا کد زیر را در Application خود در متد onCreate قرار دهید:

PushPole.setNotificationListener(new PushPole.NotificationListener() {
    @Override
    public void onNotificationReceived(@NonNull NotificationData notificationData) {
        // receive
    }
    @Override
    public void onNotificationClicked(@NonNull NotificationData notificationData) {
        // click
    }
    @Override
    public void onNotificationButtonClicked(@NonNull NotificationData notificationData, @NonNull NotificationButtonData clickedButton) {
        // button click
    }
    @Override
    public void onCustomContentReceived(@NonNull JSONObject customContent) {
        // custom content (JSON) received
    }
    @Override
    public void onNotificationDismissed(@NonNull NotificationData notificationData) {
        // dismissed
    }
});

دسته‌بندی‌کاربران (Topic)

شما می‌توانید کاربران خود را در تاپیک یا تاپیک‌های متفاوت ثبت نام کنید و برحسب علاقمندی کاربران یا دسته‌بندی خودتان به تاپیک مرتبط پوش بفرستید. مثلا اگر شما اپلیکیشن خبری دارید و کاربرانی به اخبار ورزشی علاقمند هستند و عده ای به اخبار فرهنگی، می توانید دسته اول را در تاپیک ورزشی و دسته دوم را در تاپیک فرهنگی ثبت نام کنید و هنگام ارسال پوش، برحسب محتوای پوش‌تان به تاپیک مرتبط آن را ارسال کنید تا فقط کاربران علاقمند به آن موضوع آن را دریافت کنند. برای استفاده از این امکان باید کاربران خود را در تاپیک مورد نظر عضو کنید. فرض کنید نام تاپیک مورد نظرتان ‍‍‍sport باشد. برای عضویت در این تاپیک از دستور زیر استفاده کنید:

PushPole.subscribe(context, "sport");

برای لغو عضویت از این تاپیک از دستور زیر استفاده کنید:

PushPole.unsubscribe(context, "sport");

توجه داشته باشید که توابع مربوط به عضو شدن و لغو عضویت در تاپیک باید بعد از پایان PushPole.initialize اجرا شوند. بنابراین آنها را بلافاصله بعد از PushPole.initialize قرار ندهید.

غیرفعال کردن نمایش پوش

می‌توانید نمایش پوش را غیرفعال کنید. مثلا در تنظیمات اپلیکیشن خود امکان دریافت نکردن پوش را برای کاربر قرار دهید و طبق انتخاب کاربر آن را فعال یا غیرفعال کنید. برای غیرفعال کردن نمایش پوش از دستور زیر استفاده کنید:

PushPole.setNotificationOff(context);

برای فعال سازی دوباره ی نمایش پوش از دستور زیر استفاده کنید:

PushPole.setNotificationOn(context);

ارسال پوش از یک دستگاه به دستگاه دیگر

می‌توانید مستقیم از یک دستگاه به دستگاه دیگر اعلان بفرستید. برای این کار باید شناسه‌ی پوش‌پل آن دستگاه یعنی PushPole id آن را داشته باشید. برای بدست آوردن شناسه هر دستگاه می توانید به روش زیر عمل کنید:

String devicePushPoleId = PushPole.getId(context);

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

  • برای ارسال اعلان ساده از دستور زیر استفاده کنید:
String pushpoleId = "some_thing";
PushPole.sendSimpleNotifToUser(context, pushpoleId, "title", "content");
  • پارمتر اول context، پارامتر دوم pushpoleId است و پارامتر سوم و چهارم به ترتیب تیتر و متن اعلان هستند.
  • برای ارسال اعلان پیشرفته از این دستور استفاده کنید:
String pushpoleId = "some_thing";
PushPole.sendAdvancedNotifToUser(context, pushpoleId, "{ \"title\":\"Hello\", \"content\":\"World!\" }");
  • پارمتر اول context، پارامتر دوم pushpoleId است و پارامتر سوم یک رشته با فرمت JSON هست که مشخصات اعلان پیشرفته را تعیین می کند.

نمونه‌ی یک جیسون کامل برای ارسال:

{
  "title": "عنوان",
  "content": "تیتر",
  "big_title": "تیتر کامل",
  "big_content": "متن بزرگ",
  "summary": "چکیده ",
  "image": "http://url/name.png",
  "icon": "http://url/name.png",
  "ticker": "متن نوار اعلان",
  "notif_icon": "file_download",
  "wake_screen": true,
  "sound_url": "http://static.pushpole.co/mp3/2.mp3",
  "visibility": true,
  "led_color": "-8206336",
  "show_app": true,
  "led_on": 300,
  "led_off": 500,
  "delay_until": true,
  "action": {
    "url": "tg://join?invite=sdfdsfdsfds",
    "action_type": "U"
  },
  "buttons": [
    {
      "btn_icon": "fileـdownload",
      "btn_order": 1,
      "btn_content": "متن دکمه",
      "btn_action": {
        "url": "tg://join?invite=fdsfdsfds",
        "action_type": "U"
      }
    },
    {
      "btn_icon": "local_cafe",
      "btn_order": 2,
      "btn_content": "متن دکمه",
      "btn_action": {
        "url": "http://fgfdgfdg.com",
        "action_type": "U"
      }
    },
    {
      "btn_icon": "phone_android",
      "btn_order": 3,
      "btn_content": "متن دکمه",
      "btn_action": {
        "url": "call:a_number",
        "action_type": "U"
      }
    }
  ]
}

برای اطلاعات بیشتر در مورد کلید‌ها و نحوه‌ی آنها به ارسال با استفاده از API مراجعه کنید.

  • برای ارسال JSON دلخواه از دستور زیر استفاده کنید:
String pushpoleId = "some_thing";
PushPole.sendCustomJsonToUser(context, pushpoleId, "{ \"key1\":\"value1\", \"key2\":\"value2\" }");

در این حالت پارامتر سوم یک رشته با فرمت JSON هست که اطلاعاتی که می خواهید ارسال کنید را به فرمت JSON داخلش دارد. نکته مهم: توابع ارسال اعلان به دستگاه دیگر و عضویت یا لغو عضویت در تاپیک را بعد از اطمینان از اینکه عملیات initialization پوش‌پل انجام شده است، صدا بزنید. برای این کار به روش زیر عمل کنید:

if (PushPole.isPushPoleInitialized(context)) {
    PushPole.sendSimpleNotifToUser(context, "pid_a0e3-82ac-a0", "title", "content");
}

در صورتی که قصد دارید که به دیوایسی که در حال اجرای این کد است اعلان بفرستید کافیست که شناسه‌ی ورودی را برابر شناسه‌ی دستگاه قرار دهید:

PushPole.sendSimpleNotifToUser(PushPole.getId(context), title, content);

ایجاد و حذف کانال نوتیفیکیشن در اپلیکیشن (Android 8.0+ only)

در اندروید ۸ به بعد قابلیتی برای تعریف کانال نوتیفیکیشن در اپلیکیشن ایجاد شده است. به این شکل که در برنامه خود یک یا چند کانال نوتیفیکیشن تعریف می کنید و در زمان ارسال اعلان پیشرفته با وارد کردن Channel-Id آن کانال می‌توانید اعلان را برای آن کانال خاص ارسال کنید. مزیت این کار این هست که کاربر می تواند دریافت نوتیفیکیشن از بعضی کانال‌ها را غیرفعال کند و همچنان می‌تواند از یک یا چند کانال دیگر اعلان بگیرد. فراخوانی تابع ایجاد یا حذف کانال در حالتی که برنامه شما روی اندروید زیر ۸ اجرا شود، اثری ندارد. همچنین اگر بیشتر از یکبار تابع ایجاد کانال را صدا بزنید هم فقط یکبار کانال ایجاد می‌شود و مشکلی ایجاد نمی‌کند. با استفاده از دستور زیر در برنامه خود می توانید کانال نوتیفیکشن تعریف کنید:

    PushPole.createNotificationChannel(
                context,
                "MY_CHANNEL_ID", //channelId
                "all news channel", //Channel Name
                "", //description about channel
                4, //importance: Number between 0 to 5 (5 is the most important)
                true, //enableLight
                true, //enableViberation
                true, //showBadge
                Color.BLUE, //led color
                new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400} // Vibrate mode (can be Nullable)
    );

با استفاده از تابع زیر در برنامه خود می‌توانید کانال نوتیفیکشنی که قبلا ایجاد کردید را حذف کنید:

    PushPole.removeNotificationChannel(
                context,
                "MY_CHANNEL_ID"
    );

عیب یابی

شما می‌توانید خطاهای عمومی موجود در هنگام نصب در اندروید را در این لینک مشاهده نمایید. موارد عنوان شده در زیر تنها مربوط به اندروید استودیو هستند.
در صورتی که خطای خود را در عیب‌یابی نیافتید به ما اطلاع‌دهید تا آن را اضافه‌کنیم.



Error: Failed to resolve: com.pushpole.android:pushsdk

با توجه به اینکه سایت Jcenter خدمات به ایران را محدود کرده است در صورتی که با این خطا مواجه شده‌اید، پراکسی شما مشکل دارد و باید از پراکسی مناسب استفاده کنید.


Failed to resolve "core" هنگام سینک گریدل

این خطا غالبا به دلیل مشکلی که برای گریدل به‌وجود آمده، رخ می‌دهد و به این دلیل است که گریدل در دریافت و قراردادنِ یک لایبرری به مشکل برخورده‌است. برای حل این مشکل می‌توانید موارد زیر را امتحان کنید:

  • از منوی فایل گزینه‌ی ‌Invalidate cache and restart را انتخاب کنید.
  • کش گریدل را پاک کنید. بسته به پلتفرم آدرس کش متفاوت است. Windows: C:\Users\user_name\.gradle\caches
    Linux: /home/user_name/.gradle/caches
  • نسخه‌ی گریدل را در فایل ‌build.gradle تغییر دهید.


استفاده از AndroidX

در صورتی که از AndroidX در برنامه استفاده می‌کنید باید در نظر داشته‌باشید پوش‌پل از android support library استفاده می‌کند و برای جلوگیری از خطاهای مربوط، Jettifier را فعال کنید. به فایل gradle.properties خطوط زیر را اضافه کنید (فایل مختص پروژه و نه Global).

android.useAndroidX=true
android.enableJetifier=true


مشکل نسخه‌های متفاوت برای کتابخانه‌ها در گریدل

در صورتی که پس از اضافه‌کردن پوش‌پل یک کتابخانه با دو نسخه‌ی متفاوت اضافه‌شدند و خطای نسخه‌ی متفاوت رخ‌داد، بایستی کتابخانه را با نسخه‌ی بالاتر به گریدل اضافه کنید. پوش‌پل از کتابخانه‌ی فایربیس نسخه‌ی ۱۷.۴.۰ استفاده می‌کند و شما یک کتابخانه‌ی دیگر از نسخه‌ی پایینتری مثلا ۱۶.۰.۱ استفاده می‌کنید. برای حل مشکل، در صورتی که کتابخانه‌ی ذکرشده توسط شما اضافه‌شده، نسخه‌ی آنرا به نسخه‌ی پوش‌پل برسانید و در صورتی که توسط یک کتابخانه‌ی دیگر اضافه‌شده، خودتان آن کتابخانه‌ را اضافه کنید و نسخه‌ی بالاتر را برای آن قرار دهید.


Error: Failed to resolve: com.android.support:support-v4:26.0.2

در پوش‌پل از کتابخانه ی support-v4 استفاده شده است. لذا اندروید استودیو اقدام به دانلود ملزومات کتابخانه از ریپازیتوری مربوطه خواهد کرد. در صورتی که به هردلیل در انجام این امر ناموفق باشد خطای بالا را خواهید دید. برای اطلاعات بیشتر میتوانید سوال مربوط به آن در سایت استک اور فلو را بررسی کنید.


برخی مارکت ها به دسترسی Access Coarse Location حساسند.

این دسترسی برای ارسال اعلان برحسب موقعیت مکانی کاربر هست. می توانید آن را حذف کنید اما دراینصورت اعلان پیشرفته برحسب مکان کاربر برای شما درست کار نخواهد کرد.

با اضافه کردن تگ زیر به Manifest می توانید این دسترسی را حذف کنید:

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

با اضافه‌کردن این خط پرمیشن از مانیفست نهایی حذف خواهد شد.


The Google Mobile Ads SDK was initialized incorrectly.

در صورتی که از نسخه ی 17 سرویس های لوکیشن، gcm و ad استفاده کنید ممکن است به این خطا برخورد کنید. برای رفع آن بایستی متادیتای زیر را داخل تگ اپلیکیشن در مانیفست اضافه کنید.

<meta-data
android:name="com.google.android.gms.ads.AD_MANAGER_APP"
android:value="true" />‍‍‍

در این صورت موارد لازم برای ادامه‌ی کار مهیا خواهند شد.


Multiple dex files define X

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


Too many field references: 131000; max is 65536 (خطای مالتی‌دکس)

این مورد بدین معنی ست که تعداد متد‌های ساخته‌شده بیشتر از تعدادی‌ست که ماشین‌مجازی اندروید می‌تواند آدرس‌دهی کند. برای حل این موضوع باید مالتی‌دکس را در پروژه فعال کنید. برای اطلاعات بیشتر می‌توانید به داکیومنت‌های اندروید مراجعه کنید.