UltraLCC
Thu, Sep 20, 2018 8:08 PM
選擇Start a new Android Studio project
Learn More →
輸入專案的名稱,並勾選Include Kotlin support 來使用Kotlin進行開發
Learn More →
建立一個Empty Activity 的專案
Learn More →
完成!ps.如果遇到問題可以看看這裡
Learn More →
點擊 Tools->Firebase 呼叫Firebase功能欄
Learn More →
選擇 Cloud Messaging 並點擊 Set up Firebase Cloud Messaging
Learn More →
點擊Connect to Firebase
Learn More →
登入 Google 帳戶
Learn More →
這個網頁不用管他 直接回到Android Studio
Learn More →
如果還沒創建Firebase的專案就選擇上面的創建一個新專案,如果已經有專案就選擇下面的專案加入 點選Connect to Firebase
Learn More →
可能會出現連接失敗,這是他的Bug 再按一次 Connect to Firebase 接著點選 Sync 就會直接連接了
Learn More →
點擊Add FCM to your app 之後點擊 Accept changes 即可
Learn More →
Learn More →
我們需要創建"MyFirebaseInstanceIdService"和"MyFirebaseMessagingService"兩個Class
並分別繼承"FirebaseInstanceIdService"與"FirebaseMessagingService"
我們創立一個service的package 並創建這兩個class
Learn More →
在這兩個文件中輸入以下程式碼
import android.util.Log
import com.google.firebase.iid.FirebaseInstanceId
import com.google.firebase.iid.FirebaseInstanceIdService
class MyFirebaseInstanceIdService: FirebaseInstanceIdService() {
override fun onTokenRefresh() {
// Get updated InstanceID token
val refreshedToken = FirebaseInstanceId.getInstance().token //用這個函數取得已經生成的Token
Log.d("FCMTOKEN", "Refreshed token: " + refreshedToken);
}
}
import android.util.Log
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
class MyFirebaseMessagingService: FirebaseMessagingService() {
override fun onMessageReceived(remoteMessage: RemoteMessage) {
////// Do when received push notification
Log.d("GETMESSAGE", "Message data payload: " + remoteMessage.data)
}
}
在AndroidManifest.xml裏置入下面的程式碼,激活上面的class
<service
android:name=".service.MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<service
android:name=".service.MyFirebaseInstanceIdService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
Learn More →
若連接Firebase時選的是新建專案,不需要設定Firebase
當選擇的是加入專案時需要至專案裡點擊剛剛加入的Application
Learn More →
Learn More →
接著直接跳到第四步
Learn More →
稍等一下網頁上出現成功就代表設定成功了
到Firebase網頁 從左邊欄位選擇 拓展 -> Cloud Messaging
點擊傳送第一則訊息
輸入訊息文字並選擇目標為Android,接著按下傳送訊息就可以了
(重要!! 在按下傳送前必須確保App是在背景運行,若App在前景運行,則不會顯示通知,並且請在實體手機上測試)
MyFirebaseInstanceIdService 內的 onTokenRefresh() 函數會在Token生成時被呼叫
在這個函數底下我們先新增兩行程式碼
override fun onTokenRefresh() {
// Get updated InstanceID token
...
...
FirebaseMessaging.getInstance().subscribeToTopic("all");
FirebaseMessaging.getInstance().subscribeToTopic("android");
}
這兩行程式碼在onTokenRefresh()時會向Firebase註冊兩個Topic用來對群體發送推播
若想要對單一裝置做推播則需要取得裝置的Token
override fun onTokenRefresh() {
// Get updated InstanceID token
...
...
...
OKHttpService().sendRegistrationToServer(refreshedToken);///這個函數要自己實現
}
我們可以建立一個http連線將我們的Token回傳給我們的server
我們可以利用OKHttp套件來進行http請求
這邊會教你使用OKHttp對server進行post請求
在build.gradle(Project) 裡加入版本訊息
buildscript {
...
ext.anko_version='0.10.6'
...
...
}
在buile.gradle(Module) 裡加入這兩個套件的訊息
dependencies {
...
...
////3rd part packages----------
implementation "org.jetbrains.anko:anko:$anko_version"
implementation 'com.squareup.okhttp3:okhttp:3.11.0'
}
在service資料夾下創建名為OKHttpService的Class,鍵入下面的程式碼
import okhttp3.MediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import java.io.IOException
class OkHttpService {
val JSON = MediaType.parse("application/json; charset=utf-8")
var client = OkHttpClient()
@Throws(IOException::class)
public fun post(url: String, json: String): String {
val body = RequestBody.create(JSON, json)
val request = Request.Builder()
.url(url)
.post(body)
.build()
val response = client.newCall(request).execute()
return response.body()!!.string()
}
}
在param裏組成json,並將url改成自己的server即可~
class OKHttpService {
...
...
...
fun sendRegistrationToServer(refreshedToken : String?){
val param = "{\"token\":\"$refreshedToken\"}"
doAsync {
Log.d("ResponseOK",post("http://10.88.0.216:8888", param))
}
}
}
<uses-permission android:name="android.permission.INTERNET"/>
這樣就完成http的發送步驟了!,Token將會在產生時一併進行發送
大家還記得上面我們在測試推播時,App必須是背景執行才會有通知顯示,這是因為當時App顯示的通知是Firebase預設的通知形式,必須在App關閉時才會收到,並且不會跳出通知。
Firebase 有兩種通知的形式
為了使我們的應用程式在任何時候都會收到,並彈出通知,我們必須使用data形式的通知來實作MyFirebaseMessagingService裏的onMessageReceived() ,產生自定義的通知
在onMessageReceived() 裏加入下面的程式碼,使得remoteMessage收到資料時去呼叫sendNotification() 發送通知
if (remoteMessage.data.isNotEmpty()) {
Log.d("GETMESSAGE", "Message data payload: " + remoteMessage.data)
sendNotification(remoteMessage)
}
接著我們必須要實作sendNotification()
Android 8 以上的手機需要建立Channel才能成功發送通知
class MyFirebaseMessagingService: FirebaseMessagingService() {
...
...
...
private fun sendNotification(remoteMessage: RemoteMessage){
//////// Create notification channel
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = "HighChannel"
val description = "HighPriorityChannel"
val importance = NotificationManager.IMPORTANCE_HIGH
val channel = NotificationChannel("HighChannel", name, importance)
channel.description = description
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager!!.createNotificationChannel(channel)
}
}
}
class MyFirebaseMessagingService: FirebaseMessagingService() {
...
...
...
private fun sendNotification(remoteMessage: RemoteMessage){
...
...
//////// Set up notification
val notification = remoteMessage.data
val clickIntent = intentFor<MainActivity>()
val piClick = PendingIntent.getActivity(this, R.string.app_name,clickIntent,PendingIntent.FLAG_UPDATE_CURRENT)
val builder = NotificationCompat.Builder(this,"HighChannel")
val myNotifyBuilder = builder.setContentIntent(piClick)
.setDefaults(Notification.DEFAULT_ALL)
.setPriority(NotificationManager.IMPORTANCE_HIGH)
.setAutoCancel(true)
.setSmallIcon(R.mipmap.ic_launcher)
.setWhen(System.currentTimeMillis())
.setContentTitle(notification["title"]!!)
.setContentText(notification["message"]!!)
.setVisibility(Notification.VISIBILITY_PUBLIC)
if (!notification["subText"].isNullOrEmpty())
myNotifyBuilder.setSubText(notification["subText"])
if(!notification["icon"].isNullOrEmpty())
myNotifyBuilder.setLargeIcon(getBitmapFromURL(notification["icon"]!!))
val notify = myNotifyBuilder.build()
val notifyMgr = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notifyMgr.notify(R.string.app_name,notify)
}
}
*記得這個要寫在 sendNotification() 外面
class MyFirebaseMessagingService: FirebaseMessagingService() {
...
...
///// Build Bitmap from url (use for custom icon)
private fun getBitmapFromURL(strURL: String): Bitmap? {
try {
val url = URL(strURL)
val connection = url.openConnection() as HttpURLConnection
connection.doInput = true
connection.connect()
val input = connection.inputStream
return BitmapFactory.decodeStream(input)
} catch (e: IOException) {
e.printStackTrace()
return null
}
}
}
取得電源控制權限
<uses-permission android:name="android.permission.WAKE_LOCK" />
加入控制程式碼
class MyFirebaseMessagingService: FirebaseMessagingService() {
...
...
...
private fun sendNotification(remoteMessage: RemoteMessage){
...
...
...
///// Wake up the screen when receive push notification
val screenOn = (getSystemService(Context.POWER_SERVICE) as PowerManager).newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP, "example")
screenOn.acquire()
screenOn.release()
}
}
Firebase Lagacy HTTP Protocol 使用Post方法觸發
應該設定的地方有
Example:
{
"to" : "/topics/android",
or
"to" : "Token",
"data" : {
"message" : "First Notification",
"title": "My Title"
}
}
完成拉 讚!
點擊右下角的 "Install Build Tools 27.0.3 and sync project"來安裝即可
(有時需要連續安裝多個套件)
Android