File
گزینهی import
را انتخاب کرده و از بخش Android
گزینهی Existing android code into workspace
را انتخاب کنید.Browse
فولدر اکسترکتشده را بیابید و تمام موارد را با فعالبودن تیک Copy projects into workspace
اضافهنمایید.Properties
را انتخاب کند.Android
بخش Library
با استفاده از گزینهی Add
تمام لایبرریهای اضافهشده را انتخاب و به Dependency
ها اضافهکنید.با توجه به اینکه اکلیپس نسخههای متعددی دارد و به روز بودن کتابخانه های آن برای اجرای پوشه اهمیت دارد، پیشنهاد ما دانلود و استفاده از نسخههای زیر است تا برای نصب با مشکلی مواجه نشوید.
برای استفاده از پوشه باید Android SDK خود را بروز نمایید.
AndroidManifest.xml
پروژه خود اضافه کنید.در صورتیکه هنگام اجرای پروژه لایبرری
android-support-v4
را قبلا داشتهاید، آنرا حذف کنید تا از لایبرری موجود در پوشه استفاده شود.
در اکتیویتی اصلی برنامهی خود ابتدا در بخش import
خط زیر را اضافه کنید:
import co.ronash.pushe.Pushe;
سپس در onCreate
کد زیر را اضافه کنید:
Pushe.initialize(this, true);
پوشه برای دریافت اعلان از از سرویس FCM گوگل استفاده میکند. در صورتی که پوشه تنها سرویسی در اپلیکیشن شما باشد که از این سرویس استفاده میکند، با دنبال کردن همان مراحلی که در قسمت راهاندازی توصیح داده شد همه چیز به درستی کار خواهد کرد و نیازی به انجام کار اضافهای برای راه اندازی FCM نیست.
ولی در مواردی که غیر از پوشه سرویس دیگری نیز بخواهد از FCM استفاده کند، مثلا اگر خود شما بخواهید مستقیما از Firebase استفاده کنید و پیغامهای FCM دریافت کنید، تداخل پیش خواهد آمد چرا که در هر اپلیکیشن تنها یک سرویس گوشدهنده به پیغامهای FCM میتواند وجود داشته باشد. اگر بیش از یک سرویس گوشدهنده تعریف شود، پیغامهایی که به اپلیکیشن میرسند به صورت تصادفی تنها به دست یکی از این سرویسها خواهد رسید و این باعث مختل شدن عملیات برنامه میشود.
برای رفع این مشکل لازم است مراحل زیر را در راه اندازی طی کنید:
با طی کردن این مراحل، تنها گوش دهنده به پیغامهای FCM گوش دهنده تعریف شده شما خواهد بود که همهی پیغامهای FCM را دریافت خواهد کرد و پیغامهای مربوط به پوشه را به کتابخانهی پوشه تحویل میدهد.
در ادامه نحوه اعمال این مراحل را قدم به فدم توضیح میدهیم:
برای غیر فعال کردن سرویس
FCM
پوشه، عبارت زیر را در تگ
<application>
فایل منیفست خود بگذارید:
<service
android:name="co.ronash.pushe.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 برای برنامهی خود ایجاد کردهاید میتوانید از این مرحله بگذرید.
یک کلاس جدید بسازید که از کلاس
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 (Pushe.getFcmHandler(this).onMessageReceived(remoteMessage)) {
// Message belongs to Pushe, no further action needed
return;
}
// Message does not belong to Pushe, process message...
}
@Override
public void onNewToken(String s) {
Pushe.getFcmHandler(this).onNewToken(s);
}
@Override
public void onMessageSent(String s) {
Pushe.getFcmHandler(this).onMessageSent(s);
}
@Override
public void onSendError(String s, Exception e) {
Pushe.getFcmHandler(this).onSendError(s, e);
}
@Override
public void onDeletedMessages() {
Pushe.getFcmHandler(this).onDeletedMessages();
}
}
هر بار که یک پیغام
FCM
به برنامه شما میرسد، تابع
onMessageReceived
کلاس شما صدا زده میشود. همانطور که در مثال بالا مشاهده میکنید در پیادهسازی این تابع، شما با استفاده از عبارت زیر پوشه را از دریافت پیغام مطلع میکنید:
Pushe.getFcmHandler(this).onMessageRecevied(remoteMessage)
با این کار پیغام به دست پوشه نیز میرسد و اگر پیغام مربوط به کتابخانهی پوشه باشد عملیات لازم بر روی آن انجام میشود. در صورتی که پیغام مربوط به پوشه باشد عبارت بالا مقدار
true
بر میگرداند و شما نیازی نیست عملیات بیشتری روی این پیغام انجام دهید. در صورتی که از عبارت بالا مقدار
false
گرفتید به این معنی است که پیغام مربوط به پوشه نیست و شما باید بسته به نیاز خود عملیات مورد نظر را برای آن انجام دهید.
سایر توابع کلاس تعریف شده زمان رخ دادن رویدادهای مختلف مربوط به FCM صدا زده میشوند. همانطور که در مثال بالا نشان داده شده، نیاز است که شما هنگام رخ دادن این رویدادها با صدا زدن تابع مربوطه از کتابخانهی پوشه، پوشه را از رخ دادن این رویدادها مطلع کنید.
این شناسه برای یکتاسازی دستگاههایی که پوشه در آنها رجیسترشده استفادهمیشود. برای گرفتن شناسهی پوشهی دستگاهی که برنامه در آن نصب شده از کد زیر استفاده کنید.
String pusheId = Pushe.getPusheId(context);
شما میتوانید از طریق پنل برای اپلیکیشن خود اطلاعات دلخواه در قالب یک JSON
ارسال کنید. برای اینکه بتوانید از این اطلاعات در اپلیکیشن خود استفاده کنید مراحل زیر را انجام دهید.
AndroidManifest.xml
داخل بدنه تگ <application>
اضافه کنید.<service
android:name=".MyPushListener"
android:exported="false">
<intent-filter>
<action android:name="co.ronash.pushe.RECEIVE" />
</intent-filter>
</service>
<!--PushListener can be somewhere else according to your packaging-->
class
جدید ایجاد کنید و برای آن یک نام انتخاب کنید. پیشنهاد ما نام MyPushListener
می باشد.PusheListenerService
و JSONObject
که به رنگ قرمز در آمده اند رفته و کلید Alt+Enter
را بزنید تا کتابخانههای مربوطه به پروژه شما اضافه شوند.public class MyPushListener extends PusheListenerService {
@Override
public void onMessageReceived(JSONObject customContent,JSONObject pushMessage){
android.util.Log.i("Pushe","Custom json Message: "+ customContent.toString());
// Your Code
}
}
JSON
دریافت میشود و با قرار دادن کد خود به جای // Your Code
میتوانید از آن استفاده کنید.PusheListenerService
ارث بری میکنید، داخل متد onMessageReceived
دو شیء از نوع JSONObject
دریافت میکنید که پارامتر اول JSON ارسالی و پارامتر دوم محتوای پوش نمایش داده شده است.JSON
ارسالی خود کلیدهای content
و title
را دارید و میخواهید آن را در LogCat
نشان دهید، این کد را اضافه میکنید:مثال: JSON
ارسال شده
{
"title": "تیتر",
"content": "متن"
}
public class MyPushListener extends PusheListenerService{
@Override
public void onMessageReceived(JSONObject customContent,JSONObject pushMessage) {
if (customContent == null || customContent.length() == 0)
return; //json is empty
android.util.Log.i("Pushe","Custom json Message: "+ customContent.toString()); //print json to logCat
//Do something with json
try{
String s1 = customContent.getString("title");
String s2 = customContent.getString("content");
android.util.Log.i("Pushe","Json Message\n title: " + s1 + "\n content: " + s2);
} catch (JSONException e) {
android.util.Log.e("TAG","Exception in parsing json" ,e);
}
}
به همین ترتیب اگر شما مقادیر int
یا boolean
در JSON
ارسالی گذاشته اید، با دستورهای
message.getInt(نام کلید)
message.getBoolean(نام کلید)
آن مقدار را از JSON
دریافتی میگیرید و برحسب اینکه میخواهید با آن چه کاری انجام دهید، کد لازم را اضافه میکنید.
شما میتوانید با ثبت یک رسیور در برنامهتان، از کلیک شدن یا رد کردن اعلان مطلع شوید. برای این کار یک BroadcastReceiver در فایل AndroidManifest.xml برنامه خودتان اضافه کنید و اینتنت فیلترهای زیر را در آن اضافه کنید. سه اینتنت فیلتر برای سه اتفاق زدن بر روی اعلان، رد کردن اعلان و کلیک شدن دکمهای از اعلان معرفی شده است. میتوانید هر سه را استفاده کنید یا فقط یکی یا دو تا را بسته به نیازمندی خودتان مشخص کنید.
این قابلیت برای نسخه های اندروید 8 و بالاتر کارایی ندارد.
<receiver android:name=".NotifBroadcastReceiver">
<intent-filter>
<action android:name="YOUR_PKG_NAME.pusheco.NOTIF_CLICKED"/>
<action android:name="YOUR_PKG_NAME.pusheco.NOTIF_DISMISSED" />
<action android:name="YOUR_PKG_NAME.pusheco.NOTIF_BTN_CLICKED" />
</intent-filter>
</receiver>
در کلاس BroadcastReceiver
هم کدی شبیه به زیر اضافه کنید:
YOUR_PKG_NAME
همان نام پکیج شماست.public class NotifBroadcastReceiver
extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("YOUR_PKG_NAME.pusheco.NOTIF_CLICKED")){
Log.i("Pushe","Broadcast YOUR_PKG_NAME.pusheco.NOTIF_CLICKED received");
//add your logic here
}
else if(intent.getAction().equals("YOUR_PKG_NAME.NOTIF_DISMISSED")){
Log.i("Pushe", "Broadcast YOUR_PKG_NAME.NOTIF_DISMISSED received");
//add your logic here
}
else if(intent.getAction().equals("YOUR_PKG_NAME.pusheco.NOTIF_BTN_CLICKED")){
String btnId = intent.getStringExtra("pushe_notif_btn_id");
Log.i("Pushe", "Broadcast YOUR_PKG_NAME.pusheco.NOTIF_BTN_CLICKED received. BtnId = "+btnId);
//add your logic here
}
}
}
در حالتی که یک دکمه اعلان کلیک شود، شناسه آن دکمه را که یکی از اعداد ۱ تا ۳ هست میتوانید داشته باشید و از روی آن اینکه چه دکمهای کلیک شده است را متوجه میشوید.
شما میتوانید کاربران خود را در تاپیک یا تاپیکهای متفاوت ثبت نام کنید و برحسب علاقمندی کاربران یا دستهبندی خودتان به تاپیک مرتبط پوش بفرستید. مثلا اگر شما اپلیکیشن خبری دارید و کاربرانی به اخبار ورزشی علاقمند هستند و عده ای به اخبار فرهنگی، می توانید دسته اول را در تاپیک ورزشی و دسته دوم را در تاپیک فرهنگی ثبت نام کنید و هنگام ارسال پوش، برحسب محتوای پوشتان به تاپیک مرتبط آن را ارسال کنید تا فقط کاربران علاقمند به آن موضوع آن را دریافت کنند.
برای استفاده از این امکان باید کاربران خود را در تاپیک مورد نظر عضو کنید. فرض کنید نام تاپیک مورد نظرتان sport
باشد. برای عضویت در این تاپیک از دستور زیر استفاده کنید:
Pushe.subscribe(context, "sport");
برای لغو عضویت از این تاپیک از دستور زیر استفاده کنید:
Pushe.unsubscribe(context, "sport");
توجه داشته باشید که توابع مربوط به عضو شدن و لغو عضویت در تاپیک باید بعد از پایان Pushe.initialize اجرا شوند. بنابراین آنها را بلافاصله بعد از Pushe.initialize قرار ندهید.
میتوانید نمایش پوش را غیرفعال کنید. مثلا در تنظیمات اپلیکیشن خود امکان دریافت نکردن پوش را برای کاربر قرار دهید و طبق انتخاب کاربر آن را فعال یا غیرفعال کنید. برای غیرفعال کردن نمایش پوش از دستور زیر استفاده کنید:
Pushe.setNotificationOff(context);
برای فعال سازی دوباره ی نمایش پوش از دستور زیر استفاده کنید:
Pushe.setNotificationOn(context);
میتوانید مستقیم از یک دستگاه به دستگاه دیگر اعلان بفرستید. برای این کار باید شناسهی پوشهی آن دستگاه یعنی pusheId
آن را داشته باشید. برای بدست آوردن شناسه هر دستگاه می توانید به روش زیر عمل کنید:
String pid = Pushe.getPusheId(context);
به این روش pid
هر دستگاه را می توانید بدست بیاورید و آنها را در سرور خود ذخیره کنید تا برای ارسال اعلان به دستگاه از آن استفاده کنید.
Pushe.sendSimpleNotifToUser(context, "pid_a0e3-82ac-a0", "title", "content");
context
، پارامتر دوم pusheId
است و پارامتر سوم و چهارم به ترتیب تیتر و متن اعلان هستند.Pushe.sendAdvancedNotifToUser(context, "pid_a0e3-82ac-a0", "{ \"title\":\"تست\", \"content\":\"پیام ارسالی از یک دستگاه \" }");
context
، پارامتر دوم pusheId
است و پارامتر سوم یک رشته با فرمت JSON
هست که مشخصات اعلان پیشرفته را تعیین می کند. برای دیدن فرمت JSON
به [اینجا]() مراجعه کنید.JSON
دلخواه از دستور زیر استفاده کنید:Pushe.sendCustomJsonToUser(context, "pid_a0e3-82ac-a0", "{ \"key1\":\"value1\", \"key2\":\"value2\" }");
در این حالت پارامتر سوم یک رشته با فرمت JSON
هست که اطلاعاتی که می خواهید ارسال کنید را به فرمت JSON
داخلش دارد.
نکته مهم: توابع ارسال اعلان به دستگاه دیگر و عضویت یا لغو عضویت در تاپیک را بعد از اطمینان از اینکه عملیات initialization
پوشه انجام شده است، صدا بزنید. برای این کار به روش زیر عمل کنید:
if (Pushe.isPusheInitialized(context)) {
Pushe.sendSimpleNotifToUser(context, "pid_a0e3-82ac-a0", "title", "content");
}
در اندروید ۸ به بعد قابلیتی برای تعریف کانال نوتیفیکیشن در اپلیکیشن ایجاد شده است. به این شکل که در برنامه خود یک یا چند کانال نوتیفیکیشن تعریف می کنید و در زمان ارسال اعلان پیشرفته با وارد کردن Channel-Id
آن کانال میتوانید اعلان را برای آن کانال خاص ارسال کنید.
مزیت این کار این هست که کاربر می تواند دریافت نوتیفیکیشن از بعضی کانالها را غیرفعال کند و همچنان میتواند از یک یا چند کانال دیگر اعلان بگیرد. فراخوانی تابع ایجاد یا حذف کانال در حالتی که برنامه شما روی اندروید زیر ۸ اجرا شود، اثری ندارد. همچنین اگر بیشتر از یکبار تابع ایجاد کانال را صدا بزنید هم فقط یکبار کانال ایجاد میشود و مشکلی ایجاد نمیکند.
با استفاده از دستور زیر در برنامه خود می توانید کانال نوتیفیکشن تعریف کنید:
Pushe.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)
);
در صوتی که قصد دارید پروگارد را فعال کنید کد زیر را در فایل پروگارد خود اضافه کنید.
# Ronash proguard
-keepattributes Exceptions
-keep public class co.ronash.pushe.Pushe {
public static void initialize(android.content.Context, boolean);
public static void subscribe(android.content.Context, java.lang.String);
public static void unsubscribe(android.content.Context, java.lang.String);
public static void setNotificationOff(android.content.Context);
public static void setNotificationOn(android.content.Context);
public static boolean isPusheInitialized(android.content.Context);
public static java.lang.String getPusheId(android.content.Context);
public static void sendCustomJsonToUser(android.content.Context, java.lang.String, java.lang.String);
public static void sendSimpleNotifToUser(android.content.Context, java.lang.String, java.lang.String, java.lang.String);
public static void sendAdvancedNotifToUser(android.content.Context, java.lang.String, java.lang.String);
public static void createNotificationChannel(android.content.Context, java.lang.String, java.lang.String, java.lang.String, int, boolean, boolean, boolean, int, long[]);
public static void removeNotificationChannel(android.content.Context, java.lang.String);
public static void sendEvent(android.content.Context, java.lang.String);
public static void sendEvent(android.content.Context, co.ronash.pushe.Event);
public static FcmHandler getFcmHandler(android.content.Context);
public static com.google.firebase.FirebaseApp getFirebaseApp(android.content.Context);
public static com.google.firebase.messaging.FirebaseMessaging getFirebaseMessaging(android.content.Context);
public static co.ronash.pushe.fcm.FcmHandler getFcmHandler(android.content.Context);
}
-keep public class co.ronash.pushe.fcm.FcmHandler { *; }
-keep class co.ronash.pushe.Event$* {
*;
}
-keep class co.ronash.pushe.Event { *; }
-keep class co.ronash.pushe.EventAction { *; }
-keep public class co.ronash.pushe.PusheListenerService {
public void onMessageReceived(org.json.JSONObject, org.json.JSONObject);
}
-keep public class co.ronash.pushe.receiver.UpdateReceiver
-keep public class co.ronash.pushe.receiver.PusheGcmReceiver
# google gms proguard
-keep public class com.google.android.gms.**
-dontwarn com.google.android.gms.**
# google paly services proguard
-keep class * extends java.util.ListResourceBundle {
protected java.lang.Object[][] getContents();
}
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
public static final *** NULL;
}
-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
@com.google.android.gms.common.annotation.KeepName *;
}
-keepnames class * implements android.os.Parcelable {
public static final ** CREATOR;}
-keep class **.R
-keep class **.R$* {
<fields>;
}
#evernote Job scheduler
-dontwarn com.evernote.android.job.gcm.**
-dontwarn com.evernote.android.job.util.GcmAvailableHelper
-keep public class com.evernote.android.job.v21.PlatformJobService
-keep public class com.evernote.android.job.v14.PlatformAlarmService
-keep public class com.evernote.android.job.v14.PlatformAlarmReceiver
-keep public class com.evernote.android.job.JobBootReceiver
-keep public class com.evernote.android.job.JobRescheduleService
# Firebase
-dontwarn com.google.android.gms.measurement.AppMeasurement*
-dontwarn com.google.firebase.components.Component$Instantiation
-keepclassmembers class * extends com.google.android.gms.internal.ads.zzbbo {
<fields>;
}
شما میتوانید خطاهای عمومی موجود در هنگام نصب در اندروید را در این لینک مشاهده نمایید. موارد عنوان شده در زیر تنها مربوط به اکلیپس هستند.
این مشکل به دلیل تکراری اضافهشدن یک لایبرری به پروژه رخ میدهد. برای حل این مشکل بایستی فایل jar تکراری را در پروژه یافته و یکی را نگهداشته و بقیه را حذف کنید.
برای مثال خطای زیر مربوط به لایبرری android-support-v4
است که در پوشه موجود است و در صورت وجودداشتن در پروژه این مشکل رخ میدهد:
Unable to execute dex: Multiple dex files define Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat;
در صورت حل نشدن مشکل با شرح آن به پشتیبانی پوشه مورد را اطلاع دهید.
عموما این مشکل به دلیل به روز نبودن فایل android-support-v4.jar در اکلیپس شما است. یکی از مقدمات مهم برای صحیح اجرا شدن کتابخانه پوشه، وجود داشتن و قدیمی نبودن فایل android-support-v4.jar می باشد. برای به روز رسانی این فایل را دانلود کنید و آن را جایگزین فایل android-support-v4.jar پروژه خود کنید. برای این کار به Workspace خود بروید و وارد فولدر پروژه و سپس وارد فولدر libs شوید و این فایل را جایگزین کنید و اگر این فایل از قبل موجود نیست آن را در این فولدر قرار دهید.
عموما این مشکل به دلیل به روز نبودن فایل android-support-v4.jar در اکلیپس شما است. یکی از مقدمات مهم برای صحیح اجرا شدن کتابخانه پوشه، وجود داشتن و قدیمی نبودن فایل android-support-v4.jar می باشد. برای به روز رسانی این فایل را دانلود کنید و آن را جایگزین فایل android-support-v4.jar پروژه خود کنید. برای این کار به Workspace خود بروید و وارد فولدر پروژه و سپس وارد فولدر libs شوید و این فایل را جایگزین کنید و اگر این فایل از قبل موجود نیست آن را در این فولدر قرار دهید.