跨平臺應用開發進階 (八) :uni-app 實現 Android 原生 APP- 雲打包整合極光推送 (JG-JPUSH) 詳細教程

語言: CN / TW / HK

一、前言

因專案需求,需要 uni-app 原生 APP-雲打包整合極光推送,現將整合過程梳理得出此文。

二、資源

首先,我們需要用到的一些外掛以及極光平臺官網連結:

  1. 極光推送官方SDK

  2. 極光JCore官方SDK

  3. 極光官網平臺

  4. 極光官方demo

三、整合

3.1 SDK 引入

極光推送官方SDK極光JCore官方SDK 是極光推送的官方外掛,需要下載下來用作本地外掛使用(或者直接在 Dcloud 繫結雲外掛,和其他外掛的引入方式沒有大致的區別,就不在累述。)

如果用作本地外掛的話,需要在專案下建立一個 nativeplugins 資料夾,然後將剛才下載的 JG-JPush , JG-JCore 資料夾匯入 nativeplugins 資料夾中,然後在 manifest.json 檔案中點選 App 原生外掛配置:匯入本地外掛即可。

將外掛成功匯入本地之後,點選原始碼檢視,會看到多出了一項 " nativePlugins "的配置。

3.2 程式碼整合

在專案中具體實現極光訊息推送的監聽,可以參考官方 demo,(只需要看 demo 下面的 JPush_Hbuilder_Demo 資料夾即可),具體的 api 回撥處理可以根據業務需求進行調整:

App.vue 頁面中通過以下語句將 JG-JPush 引入: var jpushModule = uni.requireNativePlugin(“JG-JPush”)

<script>  var jpushModule = uni.requireNativePlugin("JG-JPush")  export default {    onLaunch: function() {      console.log('App Launch')      if(uni.getSystemInfoSync().platform == "ios"){        // 請求定位許可權        let locationServicesEnabled = jpushModule.locationServicesEnabled()        let locationAuthorizationStatus = jpushModule.getLocationAuthorizationStatus()        console.log('locationAuthorizationStatus',locationAuthorizationStatus)          if (locationServicesEnabled == true && locationAuthorizationStatus < 3) {          jpushModule.requestLocationAuthorization((result)=>{            console.log('定位許可權',result.status)          })        }                        jpushModule.requestNotificationAuthorization((result)=>{          let status = result.status          if (status < 2) {            uni.showToast({              icon: 'none',              title: '您還沒有開啟通知許可權',              duration: 3000            })          }        })
jpushModule.addGeofenceListener(result=>{ let code = result.code let type = result.type let geofenceId = result.geofenceId let userInfo = result.userInfo uni.showToast({ icon: 'none', title: '觸發地理圍欄', duration: 3000 }) }) } jpushModule.initJPushService(); jpushModule.setLoggerEnable(true); jpushModule.addConnectEventListener(result=>{ let connectEnable = result.connectEnable uni.$emit('connectStatusChange',connectEnable) }); jpushModule.addNotificationListener(result=>{ let notificationEventType = result.notificationEventType let messageID = result.messageID let title = result.title let content = result.content let extras = result.extras uni.showToast({ icon: 'none', title: JSON.stringify(result), duration: 3000 }) }); jpushModule.addCustomMessageListener(result=>{ let type = result.type let messageType = result.messageType let content = result.content uni.showToast({ icon: 'none', title: JSON.stringify(result), duration: 3000 }) }) jpushModule.addLocalNotificationListener(result=>{ let messageID = result.messageID let title = result.title let content = result.content let extras = result.extras uni.showToast({ icon: 'none', title: JSON.stringify(result), duration: 3000 }) }) }, onShow: function() { console.log('App Show') }, onHide: function() { console.log('App Hide') } }</script>
<style> /*每個頁面公共css */</style>

複製程式碼

根據業務邏輯,在需要監聽的頁面實現極光推送的一個監聽動作。

<template>    <div>    </br>    </br>    <label style="margin-right: 50rpx;">網路狀態:</label>    <label>{{connectStatus}}</label>    </br>    <label style="margin-right: 50rpx;">DeviceToken:</label>    <label v-model="deviceToken">未獲得</label>    </br>    <label style="margin-right: 50rpx;">UDID:</label>    <label v-model="udid">未獲得</label>    </br>    <label style="margin-right: 50rpx;">RegistrationID:</label>    <label>{{registrationID}}</label>    </br>    <label style="margin-right: 50rpx;">appkey:</label>    <label v-model="appkey">未獲得</label>    </br>        <label>---------------------------------</label>    <button type="primary" @click="openSettingsForNotification">開啟通知設定介面</button>    </br>    <button type="primary" @click="setLoggerEnable">開啟日誌</button>    </br>    <button type="primary" @click="setLoggerUnEnable">關閉日誌</button>    </br>    <button type="primary" @click="getRegistrationID">獲取註冊id</button>        </div></template>
<script> // 首先需要通過 uni.requireNativePlugin("ModuleName") 獲取 module var jpushModule = uni.requireNativePlugin("JG-JPush") export default { data() { return { connectStatus: '未連結', deviceToken: '', udid: '', registrationID: '未獲得', appkey: '', } }, onLoad() { console.log('開始監聽連線狀態') uni.$on('connectStatusChange',(connectStatus)=>{ var connectStr = '' if (connectStatus == true) { connectStr = '已連線' this.getRegistrationID() }else { connectStr = '未連線' } console.log('監聽到了連線狀態變化 --- ', connectStr) this.connectStatus = connectStr }) }, onUnload() { // 移除監聽事件 uni.$off('connectStatusChange') }, methods: { openSettingsForNotification() { jpushModule.openSettingsForNotification((result)=>{ this.showToast(result) }) }, setLoggerEnable() { jpushModule.setLoggerEnable(true) }, setLoggerUnEnable() { jpushModule.setLoggerEnable(false) }, getRegistrationID() { jpushModule.getRegistrationID(result=>{ let registerID = result.registerID console.log(registerID) this.registrationID = registerID }) }, showToast(result){ uni.showToast({ icon:'none', title: JSON.stringify(result), duration: 3000 }) }
} }</script>

複製程式碼

重點在 JS 建立監聽通道。

實現上面步驟之後,程式的程式碼部分基本完成,但是此時還是無法成功除錯和連結的。

在極光官網後臺新建一個應用

應用的名稱,圖示,類目根據實際專案填寫即可:

填寫完成之後直接點選右下角下一步:

這裡的包名需要填寫你實際專案的包名,在 hbuilder 進行自定義基座打包時填寫的也是這個對用的包名,填寫之後直接回到應用管理,點選你剛才建立的專案會看到這個介面

這裡的 AppKey 是應用在極光平臺的唯一標識。

由於極光推送的接入無法使用 hbuilder 官方的基座進行除錯,所以需要我們進行自定義基座的製作與除錯:

第一步:將上面提到的 appkey 複製,然後開啟專案 manifest.json 的原始碼檢視,將剛才的包名以及 AppKey 填寫到外掛配置中:

上述配置全部完成之後,就可以進行我們自定義基座的打包了:hbuilder 工具點選: 執行---->執行到手機或模擬器---->製作自定義基座 。包名一定要和極光註冊應用時填寫的包名保持一致。

自定義基座製作成功之後,點選: 執行---->執行到手機或模擬器---->執行基座選擇----->選擇自定義基座 進行除錯。

自定義基座選好之後,點選: 執行---->執行到手機或模擬器---->執行裝置 就好了。

如果想測試是否成功連結極光伺服器,我們可以通過是否可成功獲取 registerID 來進行判斷。

jpushModule.getRegistrationID(result => {  console.log(result.registerID,"註冊ID.....")  uni.showToast({    title:result.registerID,    icon:"success",    duration:3000  })})

複製程式碼

在極光後臺選擇我們的應用,然後自建一條推送訊息。

點選頁面最下方的傳送預覽,然後即時傳送就好了,成功之後在我們的測試裝置上會出現一條通知。至此, uni-app 原生 APP-雲打包 app 接入極光推送就完全走通了。

3.3 遇到的問題及解決方案

3.3.1 包大小限制

HBuilderx 打包是對包的大小有限制的,一般不能超過 40M,超過 40M 則需要繳費打包,十元一次,雖然不貴,但是長此以往也是一筆不小的費用,且不是解決根源問題的處理方式。

此時,沒錢途的前端只好想法設法地壓縮包的大小。

仔細地觀察專案檔案中比較大、比較佔資源的就是圖片和字型檔案所佔的比重較大,程式碼基本都很小,所以應當將優化靜態資源作為優化方向。

3.3.2 [JS Framework] 當前執行的基座不包含原生外掛[JG-JPush],請在 manifest 中配置該外掛,重新制作包括該原生外掛的自定義執行基座

出現以上問題的原因是未安裝自定義基座,建議先把裝置中已有包移出,然後安裝自定義基座,在此基礎上再進行聯調。

3.3.3 uni.$emit 觸發全域性的自定義事件後, uni.$on 監聽不到全域性的自定義事件

App.vue 檔案通過 uni.$emit 觸發全域性的自定義事件後,

uni.$emit('connectStatusChange',connectEnable);

複製程式碼

在另一檔案中,無法通過 uni.$on 監聽到全域性的自定義事件。很是詭異,後考慮到該操作目的只是通過傳送頁面引數,自己就考慮應用 uni.setStorage 代替傳參,

uni.setStorage({  key: 'connectStatusChange',  data: connectEnable,  success: function () {    console.log('------------connectStatusChange-----success--------');  }});

複製程式碼

應用 uni.getStorage 代替收參,

uni.getStorage({    key: 'connectStatusChange',    success: function (res) {    var connectStr = '';        console.log('connectStatusChange:', res);    if (res.data === true) {      connectStr = '已連線';      _that.getRegistrationID();    } else {      connectStr = '未連線';    }    console.log('監聽到了連線狀態變化 --- ', connectStr)     },  fail: function(err) {    console.log('---------err----------', err)  }});

複製程式碼

注意:warning::Storage 需要在合適時機清除,否則會造成業務錯亂,例如,在使用者登出時執行 uni.removeStorage('connectStatusChange') 操作,將其從本地快取中非同步移除指定 key。

3.4 延伸閱讀:HBuilder 基座和自定義基座

3.4.1 HBuilder 基座

(1)點選選單欄 “執行”->“執行到手機或模擬器” ,會在手機/模擬器上安裝“HBuilder”應用(或者叫 HBuilder基座 ),在應用開發過程中 HBuilder/HBuilderX 會將應用資源實時同步到基座並重新整理,從而實時檢視修改效果。

(2)這裡的“HBuilder”應用(或者叫 HBuilder基座 )使用的是 DCloud 申請的第三方 SDK 配置,開發者設定的第三方 SDK 配置資訊不會生效。如微信分享,分享後顯示的來源一定是“HBuilder”。如果開發者希望自己申請的第三方 SDK 配置生效,則需在應用中呼叫 uni-app 原生外掛也必須使用自定義基座。

3.4.2 自定義基座

(1)自定義基座是使用開發者申請的第三方 SDK 配置生成的基座應用,用於 HBuilder/HBuilderX 開發應用時實時在手機/模擬器上檢視執行效果。

(2)在 HBuilder/HBuilderX 中點選選單欄 “執行->執行到手機或模擬器->製作自定義基座” 生成自定義基座安裝包。

[HBuilder] 19:37:36.837 專案 SOURCE [__UNI__1E9A5AA]打自定義基座包成功:路徑為: G:/liy/projects/uniapp/SOURCE/unpackage/debug/android_debug.apk

選擇選單 “執行->執行到手機或模擬器->執行基座選擇->自定義基座” 後再次執行專案,即可通過自定義基座檢視日誌。

注:自定義基座不可用於正式釋出,其脫離 HBuilderX 無法更新應用資源!

(3)打包成功後需要點選選單欄 “執行->執行到手機或模擬器->執行基座選擇->自定義基座” 來開啟自定義基座功能。

(4)點選選單欄 “執行”->“執行到手機或模擬器” ,可實時在手機上檢視執行效果。

3.4.2.1 共享自定義基座

如果在專案開發團隊中你選擇花米制作自定義基座,其他團隊成員本地聯調時是否還需要重新制作自定義基座?畢竟這是花錢的買賣,能省就省,誰讓咱是沒錢途的前端開發攻城獅呢。以下方式可實現一人制作花米自定義基座,全員共享。

  1. 複製自定義基座 android_debug.apk 檔案到 HBuilderX 中。

  2. HBuilderX 專案中建立 unpackage 目錄,在 unpackage 目錄下建立 debug 目錄,將上述生成的 android_debug.apk 檔案拷貝到 debug 目錄中。目錄結構參考下圖:

  3. 將執行基座選為自定義基座。

  4. 點選執行,直接執行到手機即可。

接下來,你就可以愉快的應用自定義基座了。

3.4.3 檢視基座版本號

onReady:function(){    // #ifdef APP-PLUS    console.log("執行環境版本號(客戶端uni-app的基座版本號):" + plus.runtime.uniVersion);    console.log("應用基座版本號(客戶端5+執行環境的版本號):" + plus.runtime.innerVersion);//格式為:[主版本號].[次版本號].[修訂版本號].[編譯代號]    // #endif   },

複製程式碼

注意:warning::打正式包取消勾選“自定義基座”!使用自定義基座各種 SDK 配置才能生效, 但是使用自定義基座進行雲端打包後,HX 提示 【自定義基座不可用於正式釋出,其脫離HBuilderX無法更新應用資源】 ,手機安裝打出來的包提示 【當前應用執行在測試環境,釋出正式版請打正式包】

原因是 自定義基座和HBuilder自帶基座都是用於開發除錯 。使用自定義基座開發除錯 uni-app 原生外掛後,不可直接將自定義基座 apk 作為正式版釋出。雲打包時若勾選了“自定義基座”,打出來的是測試包;應該重新提交雲端打包(不能勾選“自定義基座”)生成正式版本,正式包的 SDK 配置會自動生效。

四、拓展閱讀