ساخت اپلیکیشن چت با استفاده از فایربیس و PHP قسمت دوم
ساخت اپلیکیشن چت با استفاده از فایربیس و PHP قسمت دوم

در قسمت اول، پیاده‌سازی سمت سرور برنامه، که شامل REST API و برنامه‌ی سرور بود آموزش داده شد. در این قسمت می‌خواهیم GCM را با برنامه‌ی اندروید موجود یکپارچه کنیم. در قسمت سوم هم با ماژولهای نهایی برنامه‌ی چت یکپارچه آشنا خواهید شد. حال در مقاله ساخت اپلیکیشن چت با فایربیس یک رابط تست می‌سازید که با آن می‌توانید هر یک از برنامه‌های gcm خود را با ارسال یک پیام Push Notification نمونه تست کنید. با مقاله ساخت اپلیکیشن فایربیس و PHP باما همراه باشید.

ساخت اپلیکیشن چت با فایربیس

پروژه‌ یکپارچه‌سازی GCM

وقتی که شما ساختار پروژه را به طور کامل درک کردید. شروع به اضافه کردن gcm به برنامه‌ خود کنید.

  1. یک پروژه‌ی جدید در اندروید استدیو ایجاد کنید و جزئیات لازم را تکمیل کنید. وقتی که از شما نوع activity را درخواست کرد، Blank Activity را انتخاب کنید.
  2. قدم بعدی این است که فایل google-services.json را دانلود کنید. این فایل پیکربندی شامل اطلاعات خدمات گوگل مرتبط با برنامه‌ی شما است. شما می‌توانید خدمات گوگل مثل پیامرسانی ابری، گوگل آنالیتیکس، admob ، sign in با گوگل در همان فایل را پیکربندی کنید. اما در این مقاله ما فقط gcm را انتخاب می‌کنیم.

حالا در این صفحه برروی Get a configuration file کلیک کنید.

  1. در کنسول توسعه‌ دهنده، پروژه‌ای را که قبلاً در قسمت یک ایجاد کردید انتخاب کنید و نام پکیج پروژه‌ی فعلی را تکمیل نمایید.حال Google Cloud Messaging را فعال کنید و برروی Download google-services.json کلیک کنید.
  2. تا فایل google-services.json دانلود شود و سپس فایل دانلودی را در داخل پوشه‌ی app پروژه‌ وارد کنید. مطمئن شوید که این فایل json را دقیقاً زیر پوشه‌ی app قرار ‌داده اید. در غیر این صورت شما موفق به پیاده‌سازی gcm نخواهید بود.
  3. فایل build.gradle که زیر پوشه‌ی app قرارداد را باز کنید و تغییرات زیر را در آن اعمال کنید.
  • apply plugin: ‘com.google.gms.google-services’  در بالا اضافه کنید
  • وابستگی com.google.android.gms:play-services:8.3.0  را اضافه کنید
build.gradle
apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
 
android {
    compileSdkVersion 'Google Inc.:Google APIs:23'
    buildToolsVersion "23.0.2"
 
    defaultConfig {
        applicationId "tik4.gcm"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
 
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.+'
    compile 'com.android.support:design:23.+'
    compile "com.google.android.gms:play-services:8.3.0"
  1. حال فایل build.gradle که در پوشه‌ی ریشه قرار دارد را باز کنید و موارد زیر را در قسمت وابستگی‌ها، اضافه کنید.
  • classpath ‘com.google.gms:google-services:1.5.0-beta2’
  • classpath ‘com.android.tools.build:gradle:2.0.0-alpha6’
  • و از Build => Clean Project پروژه را تمیز کنید
build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
 
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.0.0-alpha6'
        classpath 'com.google.gms:google-services:1.5.0-beta2'
 
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}
 
allprojects {
    repositories {
        jcenter()
    }
}
 
task clean(type: Delete) {
    delete rootProject.buildDir
  1. حالا زیر پکیج اصلی پروژه، چهار پکیج با نامهای activity، app، gcm و helper بسازید. کلاس Activity اصلی خود را به پکیج activity منتقل کنید.

8.یک کلاس به نام Config.java را زیر پکیج app بسازید. این کلاس شامل اطلاعات پیکربندی برنامه مرتبط با gcm است.

Config.java
package info.tik4.gcm.app;
 
/**
 * Created by Lincoln on 05/01/16.
 */
public class Config {
 
    // flag to identify whether to show single line
    // or multi line text in push notification tray
    public static boolean appendNotificationMessages = true;
 
    // global topic to receive app wide push notifications
    public static final String TOPIC_GLOBAL = "global";
 
    // broadcast receiver intent filters
    public static final String SENT_TOKEN_TO_SERVER = "sentTokenToServer";
    public static final String REGISTRATION_COMPLETE = "registrationComplete";
    public static final String PUSH_NOTIFICATION = "pushNotification";
 
    // type of push messages
    public static final int PUSH_TYPE_CHATROOM = 1;
    public static final int PUSH_TYPE_USER = 2;
 
    // id to handle the notification in the notification try
    public static final int NOTIFICATION_ID = 100;
    public static final int NOTIFICATION_ID_BIG_IMAGE = 101;
  1. زیر پکیج helper یک کلاس به نام MyPreferenceManager.java ایجاد کنید، این کلاس داده‌ها را در ذخیره می‌کند. در این قسمت پوش نوتیفیکیشن‎های خوانده نشده را به طور موقت ذخیره می‌کنیم برای اینکه آنها را به پیام های جدید ضمیمه کنیم.
MyPreferenceManager.java
package info.tik4.gcm.helper;
 
import android.content.Context;
import android.content.SharedPreferences;
 
public class MyPreferenceManager {
 
    private String TAG = MyPreferenceManager.class.getSimpleName();
 
    // Shared Preferences
    SharedPreferences pref;
 
    // Editor for Shared preferences
    SharedPreferences.Editor editor;
 
    // Context
    Context _context;
 
    // Shared pref mode
    int PRIVATE_MODE = 0;
 
    // Sharedpref file name
    private static final String PREF_NAME = "tik4_gcm";
 
    // All Shared Preferences Keys
    private static final String KEY_USER_ID = "user_id";
    private static final String KEY_USER_NAME = "user_name";
    private static final String KEY_USER_EMAIL = "user_email";
    private static final String KEY_NOTIFICATIONS = "notifications";
 
    // Constructor
    public MyPreferenceManager(Context context) {
        this._context = context;
        pref = _context.getSharedPreferences(PREF_NAME, PRIVATE_MODE);
        editor = pref.edit();
    }
 
    public void addNotification(String notification) {
 
        // get old notifications
        String oldNotifications = getNotifications();
 
        if (oldNotifications != null) {
            oldNotifications += "|" + notification;
        } else {
            oldNotifications = notification;
        }
 
        editor.putString(KEY_NOTIFICATIONS, oldNotifications);
        editor.commit();
    }
 
    public String getNotifications() {
        return pref.getString(KEY_NOTIFICATIONS, null);
    }
 
    public void clear() {
        editor.clear();
        editor.commit();
    }
}
  1. سپس یک کلاس به نام MyApplication.java زیر پکیج app بسازید. این یک کلاس singleton مورد نیاز برای اضافه کردن به فایل AndroidManifest.xml است.
MyApplication.java
package info.tik4.gcm.app;
import android.app.Application;
 
import info.tik4.gcm.helper.MyPreferenceManager;
 
public class MyApplication extends Application {
 
    public static final String TAG = MyApplication.class
            .getSimpleName();
 
    private static MyApplication mInstance;
 
    private MyPreferenceManager pref;
 
    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
    }
 
    public static synchronized MyApplication getInstance() {
        return mInstance;
    }
 
 
    public MyPreferenceManager getPrefManager() {
        if (pref == null) {
            pref = new MyPreferenceManager(this);
        }
 
        return pref;
    }
}
  1. یک پوشه به نام raw زیر res ایجاد کنید. notification.mp3 را دانلود و در پوشه‌ی res => raw قرار دهید.
  2. یک کلاس به نام NotificationUtils.java زیر بسته‌ی gcm ایجاد کنید. این کلاس برای نمایش اعلانات در قسمت اعلانات استفاده می‌شود. این کلاس همچنین شامل توابع اصلی مثل بررسی وضعیت اجرای برنامه(background / foreground)، اعلان دانلود ضمیمه‌ی عکس از url، پخش صدای اعلان و تمیز کردن اعلان پیامها را است.
NotificationUtils.java
package info.tik4.gcm.gcm;
 
import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.support.v4.app.NotificationCompat;
import android.text.Html;
import android.text.TextUtils;
import android.util.Patterns;
 
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
 
import info.tik4.gcm.R;
import info.tik4.gcm.app.Config;
import info.tik4.gcm.app.MyApplication;
 
 
/**
 * Created by Ravi on 01/06/15.
 */
public class NotificationUtils {
 
    private static String TAG = NotificationUtils.class.getSimpleName();
 
    private Context mContext;
 
    public NotificationUtils() {
    }
 
    public NotificationUtils(Context mContext) {
        this.mContext = mContext;
    }
 
    public void showNotificationMessage(String title, String message, String timeStamp, Intent intent) {
        showNotificationMessage(title, message, timeStamp, intent, null);
    }
 
    public void showNotificationMessage(final String title, final String message, final String timeStamp, Intent intent, String imageUrl) {
        // Check for empty push message
        if (TextUtils.isEmpty(message))
            return;
 
 
        // notification icon
        final int icon = R.mipmap.ic_launcher;
 
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        final PendingIntent resultPendingIntent =
                PendingIntent.getActivity(
                        mContext,
                        0,
                        intent,
                        PendingIntent.FLAG_CANCEL_CURRENT
                );
 
        final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
                mContext);
 
        final Uri alarmSound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE
                + "://" + mContext.getPackageName() + "/raw/notification");
 
        if (!TextUtils.isEmpty(imageUrl)) {
 
            if (imageUrl != null && imageUrl.length() > 4 && Patterns.WEB_URL.matcher(imageUrl).matches()) {
 
                Bitmap bitmap = getBitmapFromURL(imageUrl);
 
                if (bitmap != null) {
                    showBigNotification(bitmap, mBuilder, icon, title, message, timeStamp, resultPendingIntent, alarmSound);
                } else {
                    showSmallNotification(mBuilder, icon, title, message, timeStamp, resultPendingIntent, alarmSound);
                }
            }
        } else {
            showSmallNotification(mBuilder, icon, title, message, timeStamp, resultPendingIntent, alarmSound);
            playNotificationSound();
        }
    }
 
 
    private void showSmallNotification(NotificationCompat.Builder mBuilder, int icon, String title, String message, String timeStamp, PendingIntent resultPendingIntent, Uri alarmSound) {
 
        NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
 
        if (Config.appendNotificationMessages) {
            // store the notification in shared pref first
            MyApplication.getInstance().getPrefManager().addNotification(message);
 
            // get the notifications from shared preferences
            String oldNotification = MyApplication.getInstance().getPrefManager().getNotifications();
 
            List<String> messages = Arrays.asList(oldNotification.split("\\|"));
 
            for (int i = messages.size() - 1; i >= 0; i--) {
                inboxStyle.addLine(messages.get(i));
            }
        } else {
            inboxStyle.addLine(message);
        }
 
 
        Notification notification;
        notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0)
                .setAutoCancel(true)
                .setContentTitle(title)
                .setContentIntent(resultPendingIntent)
                .setSound(alarmSound)
                .setStyle(inboxStyle)
                .setWhen(getTimeMilliSec(timeStamp))
                .setSmallIcon(R.mipmap.ic_launcher)
                .setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), icon))
                .setContentText(message)
                .build();
 
        NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(Config.NOTIFICATION_ID, notification);
    }
 
    private void showBigNotification(Bitmap bitmap, NotificationCompat.Builder mBuilder, int icon, String title, String message, String timeStamp, PendingIntent resultPendingIntent, Uri alarmSound) {
        NotificationCompat.BigPictureStyle bigPictureStyle = new NotificationCompat.BigPictureStyle();
        bigPictureStyle.setBigContentTitle(title);
        bigPictureStyle.setSummaryText(Html.fromHtml(message).toString());
        bigPictureStyle.bigPicture(bitmap);
        Notification notification;
        notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0)
                .setAutoCancel(true)
                .setContentTitle(title)
                .setContentIntent(resultPendingIntent)
                .setSound(alarmSound)
                .setStyle(bigPictureStyle)
                .setWhen(getTimeMilliSec(timeStamp))
                .setSmallIcon(R.mipmap.ic_launcher)
                .setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), icon))
                .setContentText(message)
                .build();
 
        NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(Config.NOTIFICATION_ID_BIG_IMAGE, notification);
    }
 
    /**
     * Downloading push notification image before displaying it in
     * the notification tray
     */
    public Bitmap getBitmapFromURL(String strURL) {
        try {
            URL url = new URL(strURL);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            Bitmap myBitmap = BitmapFactory.decodeStream(input);
            return myBitmap;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
 
    // Playing notification sound
    public void playNotificationSound() {
        try {
            Uri alarmSound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE
                    + "://" + MyApplication.getInstance().getApplicationContext().getPackageName() + "/raw/notification");
            Ringtone r = RingtoneManager.getRingtone(MyApplication.getInstance().getApplicationContext(), alarmSound);
            r.play();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    /**
     * Method checks if the app is in background or not
     */
    public static boolean isAppIsInBackground(Context context) {
        boolean isInBackground = true;
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH) {
            List<ActivityManager.RunningAppProcessInfo> runningProcesses = am.getRunningAppProcesses();
            for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) {
                if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                    for (String activeProcess : processInfo.pkgList) {
                        if (activeProcess.equals(context.getPackageName())) {
                            isInBackground = false;
                        }
                    }
                }
            }
        } else {
            List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
            ComponentName componentInfo = taskInfo.get(0).topActivity;
            if (componentInfo.getPackageName().equals(context.getPackageName())) {
                isInBackground = false;
            }
        }
 
        return isInBackground;
    }
 
    // Clears notification tray messages
    public static void clearNotifications() {
        NotificationManager notificationManager = (NotificationManager) MyApplication.getInstance().getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.cancelAll();
    }
 
    public static long getTimeMilliSec(String timeStamp) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date date = format.parse(timeStamp);
            return date.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }
}
  1. یک کلاس به نام GcmIntentService.java زیر پکیج gcm  بسازید. سرویس IntentService را که به عنوان یک خدمت پس‌زمینه عمل می‌کند، توسعه می‌دهد. این سرویس اساساً به سه هدف مورد استفاده قرار میگیرد. با ادامه مقاله ساخت اپلیکیشن فایربیس و PHP باما همراه باشید.
  • برای اتصال با سرور gcm و دریافت توکن ثبت نام. متد registerGCM() استفاده می‌شود.
  • مشترک شدن در یک موضوع. با استفاده از متد subscribeToTopic(“topic”)  .
  • لغو اشتراک از یک موضوع. با استفاده از متد unsubscribeFromTopic(“topic”) .
GcmIntentService.java
package info.tik4.gcm.gcm;
 
import android.app.IntentService;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.widget.Toast;
 
import com.google.android.gms.gcm.GcmPubSub;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import com.google.android.gms.iid.InstanceID;
 
import java.io.IOException;
 
import info.tik4.gcm.R;
import info.tik4.gcm.app.Config;
 
 
public class GcmIntentService extends IntentService {
 
    private static final String TAG = GcmIntentService.class.getSimpleName();
 
    public GcmIntentService() {
        super(TAG);
    }
 
    public static final String KEY = "key";
    public static final String TOPIC = "topic";
    public static final String SUBSCRIBE = "subscribe";
    public static final String UNSUBSCRIBE = "unsubscribe";
 
 
    @Override
    protected void onHandleIntent(Intent intent) {
        String key = intent.getStringExtra(KEY);
        switch (key) {
            case SUBSCRIBE:
                // subscribe to a topic
                String topic = intent.getStringExtra(TOPIC);
                subscribeToTopic(topic);
                break;
            case UNSUBSCRIBE:
                String topic1 = intent.getStringExtra(TOPIC);
                unsubscribeFromTopic(topic1);
                break;
            default:
                // if key is not specified, register with GCM
                registerGCM();
        }
 
    }
 
    /**
     * Registering with GCM and obtaining the gcm registration id
     */
    private void registerGCM() {
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        String token = null;
 
        try {
            InstanceID instanceID = InstanceID.getInstance(this);
            token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
                    GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
 
            Log.e(TAG, "GCM Registration Token: " + token);
 
            // sending the registration id to our server
            sendRegistrationToServer(token);
 
            sharedPreferences.edit().putBoolean(Config.SENT_TOKEN_TO_SERVER, true).apply();
        } catch (Exception e) {
            Log.e(TAG, "Failed to complete token refresh", e);
 
            sharedPreferences.edit().putBoolean(Config.SENT_TOKEN_TO_SERVER, false).apply();
        }
        // Notify UI that registration has completed, so the progress indicator can be hidden.
        Intent registrationComplete = new Intent(Config.REGISTRATION_COMPLETE);
        registrationComplete.putExtra("token", token);
        LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
    }
 
    private void sendRegistrationToServer(final String token) {
        // Send the registration token to our server
        // to keep it in MySQL
 
    }
 
    /**
     * Subscribe to a topic
     */
    public void subscribeToTopic(String topic) {
        GcmPubSub pubSub = GcmPubSub.getInstance(getApplicationContext());
        InstanceID instanceID = InstanceID.getInstance(getApplicationContext());
        String token = null;
        try {
            token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
                    GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
            if (token != null) {
                pubSub.subscribe(token, "/topics/" + topic, null);
                Log.e(TAG, "Subscribed to topic: " + topic);
            } else {
                Log.e(TAG, "error: gcm registration id is null");
            }
        } catch (IOException e) {
            Log.e(TAG, "Topic subscribe error. Topic: " + topic + ", error: " + e.getMessage());
            Toast.makeText(getApplicationContext(), "Topic subscribe error. Topic: " + topic + ", error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }
 
    public void unsubscribeFromTopic(String topic) {
        GcmPubSub pubSub = GcmPubSub.getInstance(getApplicationContext());
        InstanceID instanceID = InstanceID.getInstance(getApplicationContext());
        String token = null;
        try {
            token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
                    GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
            if (token != null) {
                pubSub.unsubscribe(token, "");
                Log.e(TAG, "Unsubscribed from topic: " + topic);
            } else {
                Log.e(TAG, "error: gcm registration id is null");
            }
        } catch (IOException e) {
            Log.e(TAG, "Topic unsubscribe error. Topic: " + topic + ", error: " + e.getMessage());
            Toast.makeText(getApplicationContext(), "Topic subscribe error. Topic: " + topic + ", error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }
}
  1. حال یک کلاس به نام MyInstanceIDListenerService.java زیر پکیج gcm بسازید. این service هر گاه تغییری در توکن ثبت نام ایجاد شود، متد onTokenRefresh() را فراخوانی می‌کند.
MyInstanceIDListenerService.java
package info.tik4.gcm.gcm;
 
import android.content.Intent;
import android.util.Log;
 
import com.google.android.gms.iid.InstanceIDListenerService;
 
public class MyInstanceIDListenerService extends InstanceIDListenerService {
 
    private static final String TAG = MyInstanceIDListenerService.class.getSimpleName();
 
    /**
     * Called if InstanceID token is updated. This may occur if the security of
     * the previous token had been compromised. This call is initiated by the
     * InstanceID provider.
     */
    @Override
    public void onTokenRefresh() {
        Log.e(TAG, "onTokenRefresh");
        // Fetch updated Instance ID token and notify our app's server of any changes (if applicable).
        Intent intent = new Intent(this, GcmIntentService.class);
        startService(intent);
    }
}
  1. یک کلاس به نام MyGcmPushReceiver.java زیر پکیج gcm بسازید. این یک کلاس دریافت کننده است که متد onMessageReceived() هرگاه دستگاه، پوش نوتیفیکیشن جدید دریافت کند، triggered می‌شود.
MyGcmPushReceiver.java
package info.tik4.gcmtest.gcm;
 
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.text.TextUtils;
import android.util.Log;
 
import com.google.android.gms.gcm.GcmListenerService;
 
import info.tik4.gcmtest.activity.MainActivity;
import info.tik4.gcmtest.app.Config;
 
public class MyGcmPushReceiver extends GcmListenerService {
 
    private static final String TAG = MyGcmPushReceiver.class.getSimpleName();
 
    private NotificationUtils notificationUtils;
 
    /**
     * Called when message is received.
     *
     * @param from   SenderID of the sender.
     * @param bundle Data bundle containing message data as key/value pairs.
     *               For Set of keys use data.keySet().
     */
 
    @Override
    public void onMessageReceived(String from, Bundle bundle) {
        String title = bundle.getString("title");
        String message = bundle.getString("message");
        String image = bundle.getString("image");
        String timestamp = bundle.getString("created_at");
        Log.e(TAG, "From: " + from);
        Log.e(TAG, "Title: " + title);
        Log.e(TAG, "message: " + message);
        Log.e(TAG, "image: " + image);
        Log.e(TAG, "timestamp: " + timestamp);
 
        if (!NotificationUtils.isAppIsInBackground(getApplicationContext())) {
 
            // app is in foreground, broadcast the push message
            Intent pushNotification = new Intent(Config.PUSH_NOTIFICATION);
            pushNotification.putExtra("message", message);
            LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification);
 
            // play notification sound
            NotificationUtils notificationUtils = new NotificationUtils();
            notificationUtils.playNotificationSound();
        } else {
 
            Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class);
            resultIntent.putExtra("message", message);
 
            if (TextUtils.isEmpty(image)) {
                showNotificationMessage(getApplicationContext(), title, message, timestamp, resultIntent);
            } else {
                showNotificationMessageWithBigImage(getApplicationContext(), title, message, timestamp, resultIntent, image);
            }
        }
    }
 
    /**
     * Showing notification with text only
     */
    private void showNotificationMessage(Context context, String title, String message, String timeStamp, Intent intent) {
        notificationUtils = new NotificationUtils(context);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        notificationUtils.showNotificationMessage(title, message, timeStamp, intent);
    }
 
    /**
     * Showing notification with text and image
     */
    private void showNotificationMessageWithBigImage(Context context, String title, String message, String timeStamp, Intent intent, String imageUrl) {
        notificationUtils = new NotificationUtils(context);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        notificationUtils.showNotificationMessage(title, message, timeStamp, intent, imageUrl);
    }
}
  1. حال AndroidManifest.xml را باز کنید و تغییرات ضروری زیر را در آن اعمال کنید.
  • با استفاده از صفت (attribute)name،  با مقدار MyApplication  را به تگ  <application> اضافه کنید
  • اجازه‌های INTERNET، WAKE_LOCK، GET_TASKS و C2D_MESSAGE  را اضافه کنید
  • MyGcmPushReceiver & GcmIntentService را به عنوان خدمت و GcmReceiver  را به عنوان دریافت کننده اضافه کنید
  • tik4.gcm  را با نام پکیج پروژه‌ی جاری خود عوض کنید.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="info.tik4.gcm">
 
    <uses-permission android:name="android.permission.INTERNET" />
 
    <!-- needed for older devices -
     used to check app background / foreground status -->
    <uses-permission android:name="android.permission.GET_TASKS" />
 
    <!-- START Added for GCM -->
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <permission
        android:name="info.tik4.gcm.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
 
    <uses-permission android:name="info.tik4.gcm.permission.C2D_MESSAGE" />
    <!-- END Added for GCM -->
 
    <application
        android:allowBackup="true"
        android:name=".app.MyApplication"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".activity.MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
 
 
        <!-- START Added for GCM -->
        <receiver
            android:name="com.google.android.gms.gcm.GcmReceiver"
            android:exported="true"
            android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
 
                <category android:name="info.tik4.gcm" />
            </intent-filter>
        </receiver>
 
        <service
            android:name=".gcm.MyGcmPushReceiver"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            </intent-filter>
        </service>
 
        <service
            android:name=".gcm.GcmIntentService"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.android.gms.iid.InstanceID" />
            </intent-filter>
        </service>
 
        <!-- END Added for GCM -->
 
    </application>
 
</manifest>

 

  1. در نهایت فایل MainActivity.java را باز کنید و تغییرات زیر را روی آن اعمال کنید.
  •  برای دریافت پوش نوتیفیکیشن‌ها، دستگاه باید google play services را پشتیبانی کند.
  • بنابراین متد checkPlayServices()  برای بررسی دردسترس بودن خدمت گوگل پلی استور استفاده می‌شود. اگر سرویس play در دسترس نبود، به سادگی برنامه را می‌بندیم.
  • یک دریافت کننده‌ی broadcast در متد onResume()  برای فیلترهای مرتبط با هر دوی REGISTRATION_COMPLETE  و PUSH_NOTIFICATION.
  • broadcast لغو ثبت‌نام از دریافت کننده‌ی onPause()در متد .
  • یک نمونه از کلاس دریافت کننده‌ی broadcast در متد onCreate()، بسازید که متد onReceive()   هر گاه که فرآیند ثبت نام کامل شد و پیام پوش جدید دریافت شد شلیک می‌شود. با ادامه مقاله ساخت اپلیکیشن چت با فایربیس باما همراه باشید.
MainActivity.java
package info.tik4.gcm.activity;
 
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.widget.Toast;
 
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
 
import info.tik4.gcm.R;
import info.tik4.gcm.app.Config;
import info.tik4.gcm.gcm.GcmIntentService;
 
public class MainActivity extends AppCompatActivity {
 
    private String TAG = MainActivity.class.getSimpleName();
    private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
    private BroadcastReceiver mRegistrationBroadcastReceiver;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
 
        mRegistrationBroadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
 
                // checking for type intent filter
                if (intent.getAction().equals(Config.REGISTRATION_COMPLETE)) {
                    // gcm successfully registered
                    // now subscribe to `global` topic to receive app wide notifications
                    String token = intent.getStringExtra("token");
 
                    Toast.makeText(getApplicationContext(), "GCM registration token: " + token, Toast.LENGTH_LONG).show();
 
                } else if (intent.getAction().equals(Config.SENT_TOKEN_TO_SERVER)) {
                    // gcm registration id is stored in our server's MySQL
 
                    Toast.makeText(getApplicationContext(), "GCM registration token is stored in server!", Toast.LENGTH_LONG).show();
 
                } else if (intent.getAction().equals(Config.PUSH_NOTIFICATION)) {
                    // new push notification is received
 
                    Toast.makeText(getApplicationContext(), "Push notification is received!", Toast.LENGTH_LONG).show();
                }
            }
        };
 
        if (checkPlayServices()) {
            registerGCM();
        }
    }
 
    // starting the service to register with GCM
    private void registerGCM() {
        Intent intent = new Intent(this, GcmIntentService.class);
        intent.putExtra("key", "register");
        startService(intent);
    }
 
    private boolean checkPlayServices() {
        GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
        int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.SUCCESS) {
            if (apiAvailability.isUserResolvableError(resultCode)) {
                apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST)
                        .show();
            } else {
                Log.i(TAG, "This device is not supported. Google Play Services not installed!");
                Toast.makeText(getApplicationContext(), "This device is not supported. Google Play Services not installed!", Toast.LENGTH_LONG).show();
                finish();
            }
            return false;
        }
        return true;
    }
 
    @Override
    protected void onResume() {
        super.onResume();
 
        // register GCM registration complete receiver
        LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
                new IntentFilter(Config.REGISTRATION_COMPLETE));
 
        // register new push message receiver
        // by doing this, the activity will be notified each time a new message arrives
        LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
                new IntentFilter(Config.PUSH_NOTIFICATION));
    }
 
    @Override
    protected void onPause() {
        LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReceiver);
        super.onPause();
    }
}

حالا برنامه را اجرا و برروی دستگاه نصب کنید. مطمئن شوید که دستگاه‌تان اتصال اینترنت دارد و گامهای بالا را به درستی طی کرده‌اید. بعد از اینکه برنامه راه‌اندازی شد، شما باید بتوانید توکن ثبت نام gcm را به عنوان یک پیام toast ببینید.  و همچنین شما می‌توانید توکن ثبت نام را در logCat بیابید.

تست Push Notification

ما یک رابط ساده برای تست پوش نوتیفیکیشن‌ها ایجاد کرده‌ایم جایی که شما یک پیام ساده تایپ می‌کنید و آن را به سوی دستگاه ارسال می‌کنید. توجه داشته باشید که اطلاعات حسّاس (API key & registration token) که شما تولید می‌کنید، به هیچ عنوان برروی سرور ذخیره نشود. همچنین دموی پنل تست فقط وقتی که گامهای توضیح داده شده در این مقاله را دنبال می‌کنید کار می‌کند.

  1. به پنل تست پوش نوتیفیکیشن بروید.
  2. GCM API Key تان را که از کنسول توسعه‌دهنده‌ی گوگل بدست آوردید را وارد کنید.
  3. gcm registration token، آنکه در اندروید استادیو LogCat لاگین میشود، وارد کنید.
  4. یک پیام تایپ کنید و برروی دکمه‌یSend Push Notification کلیک کنید. همچنین یک گزینه برای تست پوش نوتیفیکیشن با ضمیمه‌ی تصویر وجود دارد. این مقادیر برای هر اپلیکیشن متفاوت است و شما نیز باید طبق این آموزش این مقادیر را بدست بیاورید.

ساخت اپلیکیشن فایربیس و PHP

امیدواریم از قسمت دوم مقاله ساخت اپلیکیشن فایربیس و PHP بهره کافی را برده باشید. امیدواریم در ادامه با مطالب ساخت اپلیکیشن چت با فایربیس همراه ما باشید.

دیدگاه‌ خود را بیان کنید

اشتراک در
اطلاع از
guest

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

0 نظرات
بازخورد (Feedback) های اینلاین
مشاهده همه دیدگاه ها
سبد خرید0
There are no products in the cart!