一般App都會有消息推送的功能,如果是原生安卓或者IOS集成消息推送很容易,各大推送平台都有相關的Sample,但是關於Xamarin.Forms的消息推送集成的資料非常少,下面就說下Xamarin.Forms(Android)怎么集成極光推送
准備工作:
1、了解極光推送原理:https://docs.jiguang.cn/jpush/client/Android/android_sdk/
2、下載極光官方Android SDK :https://docs.jiguang.cn/jpush/resources//
3、注冊極光賬號,拿到AppKey和Master Secret
4、學習xamarin綁定jar包 :https://developer.xamarin.com/guides/android/advanced_topics/binding-a-java-library/binding-a-jar/
以上是准備工作,熟悉以上的內容之后,我們正式進入極光推送集成
一、把極光官方的jar包轉換成Dll
1、建立一個android Bindings Libary項目
2、解壓極光官方Android SDK,我下載的版本是3.1.7
3、把jar包和so文件拷入對應文件夾下面,並設置Build Action,jar文件的Build Action設置為EmbeddedJar,so文件的Build Action設置為EmbeddedNativeLibrary,然后編譯就OK了,我們可以在\bin\Debug目錄看到dll了,可以用反編譯工具檢查下dll是否有效
二、修改AndroidManifest配置
我的配置並不是和極光官方Android SDK的AndroidManifest配置一樣,我參考了網上的別人的代碼,配置如下:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.LayoutDemo"> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!--JPush Required--> <permission android:name="com.companyname.LayoutDemo.permission.JPUSH_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="com.companyname.LayoutDemo.permission.JPUSH_MESSAGE" /> <uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <application android:label="LayoutDemo" android:icon="@drawable/xamarin_logo"> <!-- since 3.0.9 Required SDK--> <provider android:authorities="com.companyname.LayoutDemo.DataProvider" android:name="cn.jpush.android.service.DataProvider" android:exported="true" /> <!-- Required SDK 核心功能--> <!-- 可配置android:process參數將PushService放在其他進程中 --> <service android:name="cn.jpush.android.service.PushService" android:enabled="true" android:exported="false" > <intent-filter> <action android:name="cn.jpush.android.intent.REGISTER" /> <action android:name="cn.jpush.android.intent.REPORT" /> <action android:name="cn.jpush.android.intent.PushService" /> <action android:name="cn.jpush.android.intent.PUSH_TIME" /> </intent-filter> </service> <!-- since 1.8.0 option 可選項。用於同一設備中不同應用的JPush服務相互拉起的功能。 --> <!-- 若不啟用該功能可刪除該組件,將不拉起其他應用也不能被其他應用拉起 --> <service android:name="cn.jpush.android.service.DaemonService" android:enabled="true" android:exported="true"> <intent-filter > <action android:name="cn.jpush.android.intent.DaemonService" /> <category android:name="com.companyname.LayoutDemo"/> </intent-filter> </service> <!-- Required SDK核心功能--> <receiver android:name="cn.jpush.android.service.PushReceiver" android:enabled="true" > <intent-filter android:priority="1000"> <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED_PROXY" /> <category android:name="com.companyname.LayoutDemo"/> </intent-filter> <intent-filter> <action android:name="android.intent.action.USER_PRESENT" /> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> <!-- Optional--> <intent-filter> <action android:name="android.intent.action.PACKAGE_ADDED" /> <action android:name="android.intent.action.PACKAGE_REMOVED" /> <data android:scheme="package" /> </intent-filter> </receiver> <!-- Required SDK核心功能--> <activity android:name="cn.jpush.android.ui.PushActivity" android:configChanges="orientation|keyboardHidden" android:theme="@android:style/Theme.NoTitleBar" android:exported="false" > <intent-filter> <action android:name="cn.jpush.android.ui.PushActivity" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="com.companyname.LayoutDemo" /> </intent-filter> </activity> <!-- SDK核心功能--> <activity android:name="cn.jpush.android.ui.PopWinActivity" android:configChanges="orientation|keyboardHidden" android:exported="false" android:theme="@android:style/Theme.NoTitleBar"> <intent-filter> <category android:name="android.intent.category.DEFAULT" /> <category android:name="com.companyname.LayoutDemo" /> </intent-filter> </activity> <!-- Required SDK核心功能--> <service android:name="cn.jpush.android.service.DownloadService" android:enabled="true" android:exported="false" > </service> <!-- Required SDK核心功能--> <receiver android:name="cn.jpush.android.service.AlarmReceiver" /> <!-- Required. For publish channel feature --> <!-- JPUSH_CHANNEL 是為了方便開發者統計APK分發渠道。--> <!-- 例如: --> <!-- 發到 Google Play 的APK可以設置為 google-play; --> <!-- 發到其他市場的 APK 可以設置為 xxx-market。 --> <!-- 目前這個渠道統計功能的報表還未開放。--> <meta-data android:name="JPUSH_CHANNEL" android:value="developer-default"/> <!-- Required. AppKey copied from Portal --> <meta-data android:name="JPUSH_APPKEY" android:value="替換成你的APPKEY"/> </application> </manifest>
把配置中所有com.companyname.LayoutDemo替換成你自己的app包名,然后替換Appkey,就ok了
三、在Android 項目的MainActivity中初始化PushNotification
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity { protected override void OnCreate(Bundle savedInstanceState) { TabLayoutResource = Resource.Layout.Tabbar; ToolbarResource = Resource.Layout.Toolbar; base.OnCreate(savedInstanceState); initPushNotification(); global::Xamarin.Forms.Forms.Init(this, savedInstanceState); LoadApplication(new App()); } private void initPushNotification() { IntentFilter filter = new IntentFilter(); filter.AddAction(JPushInterface.ActionNotificationOpened); filter.AddAction(JPushInterface.ActionNotificationReceived); filter.AddAction(JPushInterface.ActionMessageReceived); filter.AddAction(JPushInterface.ActionRegistrationId); filter.AddAction(JPushInterface.ActionConnectionChange); NotificationReceiver receiver = new NotificationReceiver(); RegisterReceiver(receiver, filter); JPushInterface.SetDebugMode(true); JPushInterface.Init(this.ApplicationContext); } }
添加NotificationReceiver類,把配置中的IntentFilter放在了代碼中,這里和官方sample有點不一樣,這里也需要替換包名com.companyname.LayoutDemo
[BroadcastReceiver] [IntentFilter(new string[] { "cn.jpush.android.intent.REGISTRATION" }, Categories = new string[] { "com.companyname.LayoutDemo" })] [IntentFilter(new string[] { "cn.jpush.android.intent.MESSAGE_RECEIVED" }, Categories = new string[] { "com.companyname.LayoutDemo" })] [IntentFilter(new string[] { "cn.jpush.android.intent.NOTIFICATION_RECEIVED" }, Categories = new string[] { "com.companyname.LayoutDemo" })] [IntentFilter(new string[] { "cn.jpush.android.intent.NOTIFICATION_OPENED" }, Categories = new string[] { "com.companyname.LayoutDemo" })] [IntentFilter(new string[] { "cn.jpush.android.intent.CONNECTION" }, Categories = new string[] { "com.companyname.LayoutDemo" })] class NotificationReceiver : PushReceiver { public override void OnReceive(Context context, Intent intent) { base.OnReceive(context, intent); //當點擊消息時進入,進入對應的頁面 if (intent.Action == JPushInterface.ActionNotificationOpened) { //When user tap the notification on notification center Bundle bundle = intent.Extras; string jsonData = bundle.GetString(JPushInterface.ExtraExtra); } //第一次安裝app時進入,會拿到registrationID,保存registrationID,當用戶登錄之后把用戶id和registrationID關聯,方便之后一對一發送消息 if (intent.Action == JPushInterface.ActionRegistrationId) { //Only call when first launch, get the registrationID string regID = JPushInterface.GetRegistrationID(context); } //當接收到信息時進入,彈出消息框 if (JPushInterface.ActionMessageReceived.Equals(intent.Action)) { } //當接收到信息時進入,彈出消息框 if (JPushInterface.ActionNotificationReceived.Equals(intent.Action)) { } if (JPushInterface.ActionNotificationReceived.Equals(intent.Action)) { } } }
四、在極光推送網站注冊,並測試發送
注意把所有的com.companyname.LayoutDemo替換成你自己的應用包名,應用包名必須和配置文件保持一致,極光推送根據應用包名和AppKey進行識別,這兩個參數必須正確。
如果是真機測試,必須開啟軟件的通知權限。
坑:
項目在調試模式時,可以調用Jpush推送,但是打包APK之后發現消息推送接收不到,錯誤日志顯示缺少libjcore126.so文件。
解決辦法:在Android項目Assets文件夾下面加入libjcore126.so文件,並設置為AndroidNativeLibrary。 奇怪的是我新建一個項目,按照上述操作進行,無論調試模式還是打包APK都是OK的,不知道什么原因引起的。
參考文章:
https://www.jianshu.com/p/5abe3924acab
https://github.com/JimmyPun610/XamarinAndroidJiGuangPushNotification