ساختارهای کنترلی در کاتلین : if ، when ، for و while
ساختارهای کنترلی در کاتلین : if ، when ، for و while
1398-06-16
تعریف تابع function در کاتلین
تعریف تابع function در کاتلین – آموزش برنامه نویسی kotlin
1398-06-21

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

نمایش نوتیفیکیشن در اندروید با فایربیس

خب طبیعتا اولین کاری که برای این پروژه باید انجام بدیم اینه که یک اکانت فایربیس بسازیم.پس از ساخت اکانت فایربیس (برای ساخت اکانت فایربیس به این آدرس https://firebase.google.com مراجعه کنید ) از پنل سمت چپ گزینه Cloude Messanging را انتخاب کنید:

فایربیس
نمایش نوتیفیکیشن در اندروید با فایربیس

و در صفحه ای که باز خواهد شد آیکن اندروید را انتخاب کنید

فایربیس
نمایش نوتیفیکیشن در اندروید با فایربیس

حالا در صفحه ای که باز خواهد شد از شما میخواهد که اپلیکیشن اندروید خود را برای ارسال نوتیفیکیشن در فایربیس ثبت کنید

فایربیس
نمایش نوتیفیکیشن در اندروید با فایربیس

نام پکیج و یک نام اختیاری برای اپلیکیشن و مقدار SHA-1 که اختیاری ست را وارد کنید و دکمه Register app را بزنید.

در مرحله دوم یک فایل json با نام google-service.json تولید میکند که برای کانکت شدن اپلیکیشن به فایربیس باید درون پروژه قرار گیرد ، پس آنرا دانلود میکنیم و درون مسیری که خود فایربیس هم نشان داده و درادامه هم خواهیم گفت ایمپورت میکنیم

notification در اندروید
نمایش نوتیفیکیشن در اندروید با فایربیس

مرحله سوم هم وابستگی هایی که لازم است را گفته تا پیاده کنیم

نمایش نوتیفیکیشن در اندروید با فایربیس
نمایش نوتیفیکیشن در اندروید با فایربیس

در مرحله آخر هم فایربیس منتظر میماند تا اپلیکیشنی با نام پکیج مشخص شده و فایل json تولید شده اپلیکیشن را نصب کند و به فایربیس متصل شود تا اولین نصب موفق را ثبت کند.

خب طبق مراحل ثبت پروژه در فایربیس که در بالا توضیح دادیم تنظیمات زیر در پروژه اعمال شد که بدلیل اهمیت زیاد مجددا تکرار خواهیم کرد.پس از دانلود فایل json مورد نیاز باید یک پروژه اندروید ایجاد میکنیم و اولین قدمی که باید برداریم ایمپورت کردن فایل json درون پروژه در project mode در مسیر:

Project name / app

نمایش نوتیفیکیشن در اندروید با فایربیس
نمایش نوتیفیکیشن در اندروید با فایربیس

حالا میتوان وابستگی ها یا dependency های مورد نیاز برای استفاده از FCM یا Firebase Cloud Messanging را اضافه کرد.

در فایل build.gradle(project)

 dependencies {
        classpath 'com.android.tools.build:gradle:3.4.2'
        classpath 'com.google.gms:google-services:4.2.0' 
    }

در فایل build.gradle(app)

dependencies {
 ...

    implementation 'com.google.firebase:firebase-core:17.0.1'
    implementation 'com.google.firebase:firebase-messaging:19.0.1'
}
apply plugin: 'com.google.gms.google-services'

پس از sync کردن یک کلاس برای پیاده کردن رسیور فایربیس نیاز داریم پس یک کلاس کاتلین یا جاوا با نام MyFirebaseMessagingService ایجاد میکنیم و دستورات زیر را پیاده میکنیم

جاوا

package com.tejariapp.firebasenotificationapp.server;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.util.Log;

import androidx.core.app.NotificationCompat;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import com.tejariapp.firebasenotificationapp.MainActivity;
import com.tejariapp.firebasenotificationapp.R;

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "MyFirebaseMsgService";

    @Override
    public void onNewToken(String s) {
        super.onNewToken(s);
        MySharedPref sharedPref = new MySharedPref(this);
        sharedPref.saveToken(s);
    }

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.e(TAG, "From: " + remoteMessage.getFrom() + " Message : " + remoteMessage + " Data : " + remoteMessage.getData());
        if (remoteMessage.getData() != null) {
            String status = remoteMessage.getData().get("status") != null ? remoteMessage.getData().get("status") : "";

            if (status.equals("new_pm"))
                sendNotification();
        }
    }

    private void sendNotification() {
        PendingIntent pendingIntent;
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
        pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);

        NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);

        NotificationCompat.Builder nb = new NotificationCompat.Builder(this, getString(R.string.app_name));

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel mChannel = new NotificationChannel(getString(R.string.app_name),
                    getString(R.string.app_name),
                    NotificationManager.IMPORTANCE_HIGH);

            mChannel.setDescription("this is message");
            mChannel.enableLights(true);
            mChannel.enableVibration(true);

            mNotificationManager.createNotificationChannel(mChannel);

            nb.setChannelId(getString(R.string.app_name) + getString(R.string.app_name));
        }

        nb.setSmallIcon(R.mipmap.ic_launcher_round);
        nb.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher_round));
        nb.setContentTitle("پیام جدید");
        nb.setContentText("شما یک پیام جدید دارید"); 
        nb.setAutoCancel(true);
        nb.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000, 1000, 1000}); 
        nb.setPriority(Notification.PRIORITY_MAX);
        nb.setContentIntent(pendingIntent);
        nb.setChannelId(getString(R.string.app_name) );

        mNotificationManager.notify(0, nb.build());
    }

}

کاتلین

package com.tejariapp.firebasenotificationapp.server

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory
import android.os.Build
import android.util.Log

import androidx.core.app.NotificationCompat

import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import com.tejariapp.firebasenotificationapp.MainActivity
import com.tejariapp.firebasenotificationapp.R

class MyFirebaseMessagingService : FirebaseMessagingService() {

    override fun onNewToken(s: String?) {
        super.onNewToken(s)
        val sharedPref = MySharedPref(this)
        sharedPref.saveToken(s)
    }

    override fun onMessageReceived(remoteMessage: RemoteMessage?) {
        Log.e(TAG, "From: " + remoteMessage!!.from + " Message : " + remoteMessage + " Data : " + remoteMessage.data)
        if (remoteMessage.data != null) {
            val status = if (remoteMessage.data["status"] != null) remoteMessage.data["status"] else ""

            if (status == "new_pm")
                sendNotification()
        }
    }

    private fun sendNotification() {
        val pendingIntent: PendingIntent
        val intent = Intent(this, MainActivity::class.java)
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
        pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT)

        val mNotificationManager = this.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        val nb = NotificationCompat.Builder(this, getString(R.string.app_name))

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val mChannel = NotificationChannel(getString(R.string.app_name),
                    getString(R.string.app_name),
                    NotificationManager.IMPORTANCE_HIGH)

            mChannel.description = "this is message"
            mChannel.enableLights(true)
            mChannel.enableVibration(true)

            mNotificationManager.createNotificationChannel(mChannel)

            nb.setChannelId(getString(R.string.app_name) + getString(R.string.app_name))
        }

        nb.setSmallIcon(R.mipmap.ic_launcher_round)
        nb.setLargeIcon(BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher_round))
        nb.setContentTitle("پیام جدید")
        nb.setContentText("شما یک پیام جدید دارید")
        nb.setAutoCancel(true)
        nb.setVibrate(longArrayOf(1000, 1000, 1000, 1000, 1000, 1000, 1000))
        nb.priority = Notification.PRIORITY_MAX
        nb.setContentIntent(pendingIntent)
        nb.setChannelId(getString(R.string.app_name))

        mNotificationManager.notify(0, nb.build())
    }

    companion object {
        private val TAG = "MyFirebaseMsgService"
    }
}

در کلاس فوق ما از کلاس FirebaseMessagingService ارث بری کردیم که دو متد مهم برای override شدن دارد.
یک متد onNewToken داریم که در صورتی که توکن جدیدی به دستگاه داده شود آن را درون دیتابیس داخلی خود ذخیره میکند.این توکن برای ما خیلی اهمیت دارد چون در واقع آدرس دستگاه ما است و برای ارسال یک نوتفیکیشن به یک دیوایس خاص باید توکن آنرا داشته باشیم به همین دلیل باید توکن را علاوه بر دیتابیس داخلی درون دیتابیس سرور هم برای ارسال نوتیفیکیشن به یک دیوایس خاص ذخیره کرد.

 @Override
    public void onNewToken(String s) {
        super.onNewToken(s);
        MySharedPref sharedPref = new MySharedPref(this);
        sharedPref.saveToken(s);
    }

همچنین درون متد دیگری که override شده با عنوان onMessageReceived درواقع پیامی که در قالب جیسون برای ما ارسال شده رو مدیریت میکنیم.با استفاده از متد زیر میتوان دریافت پیام از کجا ارسال شده

 remoteMessage.getFrom() 

با استفاده از متد زیر میتوان دیتا (داده های جیسونی که همراه نونیتفای ارسال شده) را واکشی کرد

remoteMessage.getData()

ما میخواهیم که یک جیسون ارسال کنیم و براساس آن یک نوتیفیکیشن با اندروید ایجاد کنیم ، پس در دستورات چک کردیم که در جیسون های دریافتی مقداری که با کلید status ارسال شده را بررسی کن و اگر value آن new_pm بود سپس نوتیفیکیشن را ایجاد میکنیم.

 String status = remoteMessage.getData().get("status") != null ? remoteMessage.getData().get("status") : "";

            if (status.equals("new_pm"))
                sendNotification();

در ادامه در دستورات php این جیسون را ارسال خواهیم کرد که قالبی مانند قالب زیر خواهد داشت

{
"status":"new_pm"
} 

و در متد sendNotification هم یک نوتیفیکیشن ایجاد شده که با کلیک برروی آن به صفحه MainActivity هدایت شود و همچنین در بلاک زیر نوتیفیکیشن برای ورژن اندروید های بالای ۸ را تنظیم کردیم تا بتوان هر ویژگی که بخواهیم به آن بدهیم برای مثال ویبره ، صدا و…

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel mChannel = new NotificationChannel(getString(R.string.app_name),
                    getString(R.string.app_name),
                    NotificationManager.IMPORTANCE_HIGH);

            mChannel.setDescription("this is message");
            mChannel.enableLights(true);
            mChannel.enableVibration(true);

            mNotificationManager.createNotificationChannel(mChannel);

            nb.setChannelId(getString(R.string.app_name) + getString(R.string.app_name));
        }

طبق تنظیمات اندروید از ورژن اندروید ۸ به بالا نمیتوان بصورت ساده نوتیفیکیشن ساخت و سفارشی سازی یا کاستومایز کرد بلکه باید برای نوتیفیکیشن کانال بسازیم و تنظیمات را به کانال اعمال کنیم و کانال را به نوتیفیشن اختصاص دهیم.

خب ما رسیور فایربیس را پیاده کردیم تا زمان دریافت نوتیفیکشن از سرویس فایربیس اپلیکیشن ران شود و دستوراتی که نوشتیم انجام شود پس آن را به عنوان رسیور دائم در مانیفست پروژه مشخص میکنیم.

 <service
            android:name=".MyFirebaseMessagingService"
            android:stopWithTask="false">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT"/>
            </intent-filter>
        </service>
        <service
            android:name=".server.MyFirebaseMessagingService"
            android:stopWithTask="false">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT"/>
            </intent-filter>
        </service>

خب همانطور که گفتیم ما توکن رو درون دیتابیس داخلی نوتیفیکیشن ذخیره میکنیم پس باید از کلاس sharedprefrence استفاده کنیم.بنابراین یک کلاس ایجاد میکنیم و درون آن دستورات مورد نیاز را مینویسیم

جاوا

package com.tejariapp.firebasenotificationapp.server;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;

import static android.content.Context.MODE_PRIVATE;

public class MySharedPref {
    private Context context;
    private SharedPreferences.Editor editor;
    private SharedPreferences prefs;

    public MySharedPref(Context context) {
        this.context = context;

        prefs = context.getSharedPreferences("PUSH_DB", MODE_PRIVATE);
        editor = context.getSharedPreferences("PUSH_DB", MODE_PRIVATE).edit();
    }

    public void saveToken(String token) {
        editor.putString("TOKEN", token);
        editor.apply();
    }

    public String getToken() {
        return prefs.getString("TOKEN", "-");
    }

}

کاتلین

package com.tejariapp.firebasenotificationapp.server
 

import android.content.Context 
import android.content.SharedPreferences

import android.content.Context.MODE_PRIVATE

class MySharedPref(private val context: Context) {
    private val editor: SharedPreferences.Editor
    private val prefs: SharedPreferences

    val token: String?
        get() = prefs.getString("TOKEN", "-")

    init {

        prefs = context.getSharedPreferences("PUSH_DB", MODE_PRIVATE)
        editor = context.getSharedPreferences("PUSH_DB", MODE_PRIVATE).edit()
    }

    fun saveToken(token: String) {
        editor.putString("TOKEN", token)
        editor.apply()
    }
}

فراموش نکنید که در مانیفست پروژه مجوز دسترسی به اینترنت هم قرار دهید

 <uses-permission android:name="android.permission.INTERNET"/>

کلاس MainActivity هم که بدون هیچ عملیات خاصی به عنوان کلاس لانچر پیاده شده

جاوا

package com.tejariapp.firebasenotificationapp;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

کاتلین

package com.tejariapp.firebasenotificationapp
 

import androidx.appcompat.app.AppCompatActivity

import android.os.Bundle

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

در نهایت فایل های php برای ارسال نوتیفیکیشن هم بصورت زیر خواهد بود

کلاس notif.php

<?php
class SendNotification {
    private static $API_SERVER_KEY = 'AAAACzTpr1A:APA91bEujUifrFrdLaYtXYckfEXj3r-56RGorat_T2duFcR7TULvurBT4_0nieI8kxToSk3N2bHlpRi_hWScV90Gdj9FXwx-lerRmevL5..........';

    private static $is_background = "TRUE";
    public function __construct() {

    }
    public function sendPushNotificationToFCMSever($token) {
        $path_to_firebase_cm = 'https://fcm.googleapis.com/fcm/send';

        $fields = array(
            'to' => $token,
            'priority' => 10,
            'data'=>array(
                "status"=>"new_pm"
            )
        );
        $headers = array(
            'Authorization:key=' . self::$API_SERVER_KEY,
            'Content-Type:application/json'
        );

        // Open connection
        $ch = curl_init();
        // Set the url, number of POST vars, POST data
        curl_setopt($ch, CURLOPT_URL, $path_to_firebase_cm);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
        // Execute post
        $result = curl_exec($ch);
        // Close connection
        curl_close($ch);
        return $result;
    }
}
?>

مقدار API_SERVER_KEY را باید از پنل فایربس در مسیر زیر بیاوریم ، از پنل سمت راست برروی چرخ دنده کنار Project Overview کلیک کرده و Project settings رو انتخاب میکنیم

نمایش نوتیفیکیشن در اندروید با فایربیس
آموزش نمایش نوتیفیکیشن در اندروید با فایربیس

سپس تب cloud messaging را انتخاب میکنیم و مقدار server key رو کپی و در کلاس php که برای ارسال نوتیفیکیشن نوشتیم برای فیلد API_SERVER_KEY قرار میدهیم.

نمایش نوتیفیکیشن در اندروید با فایربیس
نمایش نوتیفیکیشن در اندروید با فایربیس

همچنین دستور زیر نیز درواقع همان مقدار جیسونی که ما در رسیور اندروید نوشتیم را تنظیم و ارسال میکنیم

   $fields = array(
            'to' => $token,
            'priority' => 10,
            'data'=>array(
                "status"=>"new_pm"
            )
        );

حالا یک کلاس php دیگر ایجاد میکنیم برای ارسال نوتیفیکیشن با استفاده از کلاس notif.php با نام sendNotif.php ایجاد میکنیم و دستورات زیر را پیاده میکنیم:

<?php
include("connection.php");
include "SendNotification.php";

$id = $_POST['id'];

$con = connection::getConnection();

//send push code
        $user_token = "";
        $sql2 = "SELECT user_token FROM `tbl_user` WHERE `user_id`= $id";
        $result2 = $con->query($sql2);
        if ($result2->num_rows > 0){
            while ($row = $result2->fetch_assoc()){
                $user_token = $row['user_token'];
            }
        }

        $serverObject = new SendNotification();
        $jsonString = $serverObject->sendPushNotificationToFCMSever( $user_token );
?>

توجه کنید که دستورات فوق درصورتی ست که شما توکن های کاربران را ذخیره میکنید و میخواهید براساس آی دی کاربر توکن موبایل آنرا واکشی و نوتیفیکیشن برای او ارسال کنید ، اما درصورتی که میخواهید نوتیفیکیشن را به یک توکن استاتیک ارسال کنید میتوان دستورات را چنین تغییر داد.

<?php
include("connection.php");
include "SendNotification.php"; 

$con = connection::getConnection(); 
        $serverObject = new SendNotification();
        $jsonString = $serverObject->sendPushNotificationToFCMSever( 'user token' );
?>

بجای عبارت user token باید توکن موبایل مقصد را وارد کنید.

از طریق پنل فایربیس نیز میتوان با کلیک برروی گزینه Cloud Messaging از پنل سمت راست و سپس کلیک کردن دکمه New Notification در پنجره باز شده

نحوه نمایش notification در اندروید
نحوه نمایش notification در اندروید

میتوان یک نوتیفیکیشن جدید ایجاد و ارسال کرد.مطابق تصویر زیر مقادیر Notificaiton Title و Notification Text را وارد کنید سپس برروی دکمه Send test Message کلیک کنید

نمایش نوتیفکیشن در اندروید با فایربیس
نحوه نمایش notification در اندروید

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

امیدواریم که این آموزش برای شما مفید بوده باشد 🙂

پاسخی بگذارید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *