跨平台应用开发进阶(八) :uni-app 实现Android原生APP-云打包集成极光推送(JG-JPUSH)详细教程

一、前言

因项目需求,需要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")

java 复制代码
<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>

根据业务逻辑,在需要监听的页面实现极光推送的一个监听动作。

java 复制代码
<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来进行判断。

java 复制代码
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触发全局的自定义事件后,

java 复制代码
uni.$emit('connectStatusChange',connectEnable);

在另一文件中,无法通过uni.$on监听到全局的自定义事件。很是诡异,后考虑到该操作目的只是通过传送页面参数,自己就考虑应用uni.setStorage代替传参,

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

应用uni.getStorage代替收参,

java 复制代码
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)
	}
});

注意⚠️: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 查看基座版本号

java 复制代码
onReady:function(){
    // #ifdef APP-PLUS
    console.log("运行环境版本号(客户端uni-app的基座版本号):" + plus.runtime.uniVersion);
    console.log("应用基座版本号(客户端5+运行环境的版本号):" + plus.runtime.innerVersion);//格式为:[主版本号].[次版本号].[修订版本号].[编译代号]
    // #endif   
},

注意⚠️:打正式包取消勾选"自定义基座"!使用自定义基座各种SDK配置才能生效, 但是使用自定义基座进行云端打包后,HX提示【自定义基座不可用于正式发布,其脱离HBuilderX无法更新应用资源】,手机安装打出来的包提示【当前应用运行在测试环境,发布正式版请打正式包】

原因是自定义基座和HBuilder自带基座都是用于开发调试。使用自定义基座开发调试uni-app原生插件后,不可直接将自定义基座apk作为正式版发布。云打包时若勾选了"自定义基座",打出来的是测试包;应该重新提交云端打包(不能勾选"自定义基座")生成正式版本,正式包的SDK配置会自动生效。

3.5 延伸阅读:厂商通道集成

利用极光控制台发送广播时,不支持应用离线状态推送。若要实现APP离线可推送广播信息,可集成厂商通道,离线状态下应用厂商通道实现广播信息接收。

详参《厂商通道集成手册》。

四、拓展阅读

相关推荐
y先森2 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy2 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189112 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿3 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡4 小时前
commitlint校验git提交信息
前端
虾球xz4 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇4 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒4 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员5 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐5 小时前
前端图像处理(一)
前端