FCM實現手機推送,推送的方式,真機調試


 

 

 

 

 

 

 

 

 FCM實現手機

        1 下載Androidstudio 3.2 版本,之后新建一個項目

       

       

       2  創建完項目之后查找文件AndroidMainifest.xml

       

 

 3  訪問網站注冊一個自己的firebase的賬戶 https://console.firebase.google.com

 

 

 

 5  進入自己的項目當中,之后添加自己的app,可以是Android的也可以是iOS,在這里我們以Android為例子

6  選擇Android的APP之后會讓你注冊這個APP

 

 7  點擊Register app之后會生成下面的畫面,之后點擊下載.json文件放到指定的目錄下即可

 

8  按照指定的操作即可,把下面的代碼拷貝到指定的文件下,之后點擊同步

 

9  同步是否成功看你是否出錯

 

 

 同步的時候可能會出現下面的錯誤

 

10   在這一步可能會很慢,不用管他,直接點擊Skip this step 即可

 

11  之后會生成一個app:sdf

12  到此firebase的服務器配置完了

 

13  配置前台,找到文件app下的build.gradle下面追加下面的兩行代碼,如下圖所示

implementation 'com.google.firebase:firebase-messaging:17.3.4'
implementation 'com.firebase:firebase-jobdispatcher:0.8.5'

  

14  在下面的路徑下追加三個類,並修改AndroidMainifest.xml文件

MyJobService

package com.example.peiqiang.fcm_test;

import android.util.Log;

import com.firebase.jobdispatcher.JobParameters;
import com.firebase.jobdispatcher.JobService;

public class MyJobService extends JobService {

    private static final String TAG = "MyJobService";

    @Override
    public boolean onStartJob(JobParameters jobParameters) {
        Log.d(TAG, "Performing long running task in scheduled job");
        // TODO(developer): add long running task here.
        return false;
    }

    @Override
    public boolean onStopJob(JobParameters jobParameters) {
        return false;
    }

}

  MyFirebaseMessagingService

/**
 * Copyright 2016 Google Inc. All Rights Reserved.
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.peiqiang.fcm_test;

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.support.v4.app.NotificationCompat;
import android.text.Html;
import android.util.Log;

import com.firebase.jobdispatcher.FirebaseJobDispatcher;
import com.firebase.jobdispatcher.GooglePlayDriver;
import com.firebase.jobdispatcher.Job;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "MyFirebaseMsgService";

    /**
     * Called when message is received.
     *
     * @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
     */
    // [START receive_message]
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        // [START_EXCLUDE]
        // There are two types of messages data messages and notification messages. Data messages
        // are handled
        // here in onMessageReceived whether the app is in the foreground or background. Data
        // messages are the type
        // traditionally used with GCM. Notification messages are only received here in
        // onMessageReceived when the app
        // is in the foreground. When the app is in the background an automatically generated
        // notification is displayed.
        // When the user taps on the notification they are returned to the app. Messages
        // containing both notification
        // and data payloads are treated as notification messages. The Firebase console always
        // sends notification
        // messages. For more see: https://firebase.google.com/docs/cloud-messaging/concept-options
        // [END_EXCLUDE]

        // TODO(developer): Handle FCM messages here.
        // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
        Log.d(TAG, "From: " + remoteMessage.getFrom());

        // Check if message contains a data payload.
        if (remoteMessage.getData().size() > 0) {
            Log.d(TAG, "Message data payload: " + remoteMessage.getData());

            if (/* Check if data needs to be processed by long running job */ true) {
                // For long-running tasks (10 seconds or more) use Firebase Job Dispatcher.
                scheduleJob();
            } else {
                // Handle message within 10 seconds
                handleNow();
            }

        }

        // Check if message contains a notification payload.
        if (remoteMessage.getNotification() != null) {
            Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
        }
//        super.onMessageReceived(remoteMessage);
//        sendNotification(remoteMessage);

        // Also if you intend on generating your own notifications as a result of a received FCM
        // message, here is where that should be initiated. See sendNotification method below.
    }
    // [END receive_message]


//    private void sendNotification(RemoteMessage message) {
//        Intent intent;
//        intent = new Intent(this, MainActivity.class);
//        Log.d(TAG, message.getData().toString());
//
//        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
//        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
//                PendingIntent.FLAG_ONE_SHOT);
//        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
//
//        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
//                .setSmallIcon(R.mipmap.ic_launcher)
//                .setContentTitle(message.getData().get("title"))
//                .setContentText(Html.fromHtml(message.getData().get("body")))
//                .setAutoCancel(true)
//                .setSound(defaultSoundUri)
//                .setContentIntent(pendingIntent);
//
//        NotificationManager notificationManager =
//                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//        notificationManager.notify(0, notificationBuilder.build());
//        saveMessage(message);
//    }



    // [START on_new_token]

    /**
     * Called if InstanceID token is updated. This may occur if the security of
     * the previous token had been compromised. Note that this is called when the InstanceID token
     * is initially generated so this is where you would retrieve the token.
     */
    @Override
    public void onNewToken(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
        // Instance ID token to your app server.
        sendRegistrationToServer(token);
    }
    // [END on_new_token]

    /**
     * Schedule a job using FirebaseJobDispatcher.
     */
    private void scheduleJob() {
        // [START dispatch_job]
        FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(this));
        Job myJob = dispatcher.newJobBuilder()
                .setService(MyJobService.class)
                .setTag("my-job-tag")
                .build();
        dispatcher.schedule(myJob);
        // [END dispatch_job]
    }

    /**
     * Handle time allotted to BroadcastReceivers.
     */
    private void handleNow() {
        Log.d(TAG, "Short lived task is done.");
    }

    /**
     * Persist token to third-party servers.
     *
     * Modify this method to associate the user's FCM InstanceID token with any server-side account
     * maintained by your application.
     *
     * @param token The new token.
     */
    private void sendRegistrationToServer(String token) {
        // TODO: Implement this method to send token to your app server.
    }

    /**
     * Create and show a simple notification containing the received FCM message.
     *
     * @param messageBody FCM message body received.
     */
    private void sendNotification(String messageBody) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);

        String channelId = getString(R.string.default_notification_channel_id);
        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder =
                new NotificationCompat.Builder(this, channelId)
                        .setSmallIcon(R.drawable.ic_stat_ic_notification)
                        .setContentTitle(getString(R.string.fcm_message))
                        .setContentText(messageBody)
                        .setAutoCancel(true)
                        .setSound(defaultSoundUri)
                        .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        // Since android Oreo notification channel is needed.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(channelId,
                    "Channel human readable title",
                    NotificationManager.IMPORTANCE_DEFAULT);
            notificationManager.createNotificationChannel(channel);
        }

        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }
}

  MyFirebaseInstanceIDService

 

/**
 * Copyright 2016 Google Inc. All Rights Reserved.
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.peiqiang.fcm_test;

import android.util.Log;

import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;


public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {

    private static final String TAG = "MyFirebaseIIDService";

    /**
     * Called if InstanceID token is updated. This may occur if the security of
     * the previous token had been compromised. Note that this is called when the InstanceID token
     * is initially generated so this is where you would retrieve the token.
     */
    // [START refresh_token]
    @Override
    public void onTokenRefresh() {
        // Get updated InstanceID token.
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        Log.d(TAG, "Refreshed token: " + refreshedToken);

        // If you want to send messages to this application instance or
        // manage this apps subscriptions on the server side, send the
        // Instance ID token to your app server.
        sendRegistrationToServer(refreshedToken);
    }
    // [END refresh_token]

    /**
     * Persist token to third-party servers.
     *
     * Modify this method to associate the user's FCM InstanceID token with any server-side account
     * maintained by your application.
     *
     * @param token The new token.
     */
    private void sendRegistrationToServer(String token) {
        // TODO: Implement this method to send token to your app server.
//        SendBird.registerPushTokenForCurrentUser(token, new SendBird.RegisterPushTokenWithStatusHandler() {
//            @Override
//            public void onRegistered(SendBird.PushTokenRegistrationStatus pushTokenRegistrationStatus, SendBirdException e) {
//                if (e != null) {
//                    Toast.makeText(MyFirebaseInstanceIDService.this, "" + e.getCode() + ":" + e.getMessage(), Toast.LENGTH_SHORT).show();
//                    return;
//                }
//
//                if (pushTokenRegistrationStatus == SendBird.PushTokenRegistrationStatus.PENDING) {
//                    Toast.makeText(MyFirebaseInstanceIDService.this, "Connection required to register push token.", Toast.LENGTH_SHORT).show();
//                }
//            }
//        });
    }
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.peiqiang.fcm_test">
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <meta-data android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

        <meta-data
            android:name="com.google.firebase.messaging.default_notification_icon"
            android:resource="@drawable/ic_stat_ic_notification" />
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_channel_id"
            android:value="@string/default_notification_channel_id" />


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

        <service  android:name=".MyFirebaseInstanceIDService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
            </intent-filter>
        </service>
        <service android:name=".MyJobService" android:exported="false">
            <intent-filter>
                <action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE"/>
            </intent-filter>
        </service>
    </application>
</manifest>

  15  在此期間可能會報錯,報錯的原因是沒有找到XXX,這個時候就要去定義一些常量文件。

string.xml

<resources>
    <string name="app_name">FCM_Test</string>
    <string name="quickstart_message">Click the SUBSCRIBE TO WEATHER button below to subscribe to the
        weather topic. Messages sent to the weather topic will be received. The LOG TOKEN button logs the
        InstanceID token to logcat.</string>
    <string name="subscribe_to_weather">Subscribe To Weather</string>
    <string name="log_token">Log Token</string>

    <string name="msg_subscribed">Subscribed to weather topic</string>
    <string name="msg_token_fmt" translatable="false">InstanceID Token: %s</string>

    <string name="default_notification_channel_id" translatable="false">fcm_default_channel</string>
    <!--
        This is the name that users will see when interacting with this channel.
        It should describe the category of notifications that will be sent through this channel
     -->
    <string name="default_notification_channel_name" translatable="true">Weather</string>
    <string name="msg_subscribe_failed">Failed to subscribe to weather topic</string>
    <string name="fcm_message">FCM Message</string>
</resources>

  activity_main.xml文件是設計你的app在手機上的具體顯示

配置完之后可能會出現一些圖片找不到的情況,這樣你就要去下面的網址找到對應的圖片,放到你自己的工程下面,路徑參照網址
https://github.com/firebase/quickstart-android/tree/master/messaging/app/src/main/res

 

16  編譯如果沒有錯誤的話,到目前為止就算是OK了

17  啟動你的虛擬機

在這遇到的坑有,haxm安裝不上
Android studio的虛擬手機啟動不起來,window10系統需要安裝haxm的文件,如果你沒有安裝的話再window10系統啟動不起來的,window7系統好像可以直接啟動,可以嘗試着看一下,如果不好用的話在尋找haxm文件
haxm文件自己去C盤下搜索所有的文件就可以找到。當你安裝的時候報下圖錯誤的時候,可以上網自己找一下,有相關的解答。解決的辦法就是取你的BIOS里面設置一下。Window10設置完之后還是啟動不了的話,就去找你的系統是否安裝
過window10 自帶的虛擬機,如果安裝過,OK問題就在這了。去查找你的控制面板里面,找到下圖的地方,把Hyper-V給去掉之后再重新安裝haxm文件,應該就不會出現這種問題了

 

 

18   啟動你的虛擬機之后會讓你選擇你的手機虛擬機的版本問題

19 運行起來之后你的虛擬手機上會出現你自己創建的app

20  到此為止,你的前台和后台配置完成了接下來就是發送消息
發送消息有兩種模式,一種是用postman來發送,一種是用firebase的服務器來發送

 

postman來發送
上網自己下載一個postman的一個軟件打開之后如下圖

 

 

 

解釋說明
1. 網址URL是固定的,調用你的firebase服務器 【https://fcm.googleapis.com/fcm/send】
2. 傳送方式是POST形式
3. 選擇你傳送出去的參數形式
4.具體的數據。
{
"to" : "token",
"notification" : {
"body" : "push body test aadfadfadsfasdfa!",
"title" : "pusqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"
}
}
5.點擊send之后就會把消息發送到你手機設備上面

在運行的時候遇到的一些盲點,有經驗的人知道,對於像我這樣的菜鳥來說,就是一個非常大的坑,坑了我三天,還是在有經驗的人那里學到的測試的方法
在目前我們的代碼程度上,如果你的畫面是下面的畫面的話,之后你在點擊send進行發信的話,恭喜你,你也與我一樣。在下面的畫面上進行推送是不成功的,你手機不會收到消息的
只有把我們的app隱藏,或者是在后台執行,這種情況下是可以推送到我們的手機上的,如果想要在app在畫面上顯示之后進行推送的話,就要再寫代碼,代碼怎么可以自己上網查,我還沒做到這一步
再有一點就是postman他有的時候會延遲,不會及時的送到消息,一般的情況下會及時的推送到你手機上,但是有的情況下是不會即使的推送到你手機上面的,要多等一會,這個需要注意

測試時候的小竅門,就是把你的app給卸載之后在啟動Androidstudio,來回往復

 

token取得方法,在你運行的時候會把你安裝的在虛擬手機上面的token號直接打在Logcat里面,
請注意,只有每次app安裝的時候token才會打到logcat里面,如果第一次安裝了,沒有卸載的情況下,執行這個重啟app或者重啟虛擬機都打不出來token的

 

 用firebase服務器來發送消息,具體參照下圖

 

 

 21  虛擬機弄好之后就要用真機器來試驗你做的app有沒有問題了,這里講一下用真機器來調試你的APP

Android studio工具里面點擊下圖的標識之后會出現增加Android APP的界面

手機打開你的開發者選項,如果不知道在哪的話可以在網上搜一下,打開USB調試即可,有的手機即使打開了USB調試了但是在運行你的Android studio的時候是會報錯的,這樣的話你就要換一台手機了
用數據線鏈接你的手機和電腦之后就可以按照下圖的方式點擊運行APP就會安裝在你的手機上面,如果是debug的話,是可以打斷點的

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM