极光推送集成流程

来源:互联网 发布:编写高性能的JS 编辑:程序博客网 时间:2024/05/29 02:30

Android极光推送集成(可接收到服务端推送消息)





最近公司的项目中用到了极光推送,查文档,百度,终于算是基本实现了功能。从来没写过任何博客,所以想着将极光的集成流程大致记录一下,方便日后再次用到的时候,不至于忘记一些重要细节,如果能帮到那些初次集成极光碰到问题的朋友,那自然是更好了。
第一步,注册极光开发者服务,然后进入到后台,创建应用,填写我们自己应用的名称,上传图标(可传可不传)。创建应用完成后,会为我们生成AppKey,这个key我们会在项目的清单文件中填写用到。还有一个Master Secret,这个用于服务器端 API 调用时与 AppKey 配合使用达到鉴权的目的。Android手机端应该是用不到。

第二步,下载Android SDK,
压缩包中的内容
  • AndroidManifest.xml
    • 客户端嵌入SDK参考的配置文件
  • libs/jcore-android.1.x.x.jar
    • 极光开发者服务的核心包。
  • libs/jpush-android-3.x.y.jar
    • JPush SDK 开发包。
  • libs/(cpu-type)/libjcore1xx.so
    • 各种CPU类型的native开发包。
  • res
    • 集成SDK必须添加的资源文件
  • example
    • 是一个完整的 Android 项目,通过这个演示了 JPush SDK 的基本用法,可以用来做参考。
第三步,将下载下来的文件集成到我们的项目中
  • 解压缩 jpush-android--3.x.x-release.zip 集成压缩包。
  • 复制 libs/jcore-android-1.x.x.jar 到工程 libs/ 目录下。
  • 复制 libs/jpush-android-3.x.x.jar 到工程 libs/ 目录下。
  • 复制 libs/(cpu-type)/libjcore1xy.so 到你的工程中存放对应cpu类型的目录下。
  • 复制 res/ 中drawable-hdpi, layout, values文件夹中的资源文件到你的工程中 res/ 对应同名的目录下。
第四步,配置AndroidManifest清单文件

主要步骤为:

  • 复制备注为 "Required" 的部分
  • 将标注为“您应用的包名”的部分,替换为当前应用程序的包名
  • 将标注为“您应用的Appkey”的部分,替换为在Portal上注册该应用的的Key,例如:9fed5bcb7b9b87413678c407
AndroidManifest 示例
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="您应用的包名"    android:versionCode="309"    android:versionName="3.0.9"    >    <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="23" />    <!-- Required -->    <permission        android:name="您应用的包名.permission.JPUSH_MESSAGE"        android:protectionLevel="signature" />    <!-- Required -->    <uses-permission android:name="您应用的包名.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" />    <!-- Optional. Required for location feature -->    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <!-- 用于开启 debug 版本的应用在6.0 系统上 层叠窗口权限 -->    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />    <uses-permission android:name="android.permission.GET_TASKS" />    <application        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:name="Your Application Name">        <!-- 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 3.0.9 Required SDK 核心功能-->        <provider            android:authorities="您应用的包名.DataProvider"            android:name="cn.jpush.android.service.DataProvider"            android:exported="true"        />        <!-- 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="您应用的包名"/>             </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="您应用的包名"/>            </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="您应用的包名" />            </intent-filter>        </activity>        <!-- SDK核心功能-->        <activity            android:name="cn.jpush.android.ui.PopWinActivity"            android:configChanges="orientation|keyboardHidden"            android:exported="false"            android:theme="@style/MyDialogStyle">            <intent-filter>                <category android:name="android.intent.category.DEFAULT" />                <category android:name="您应用的包名" />            </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 since 3.0.7 -->        <!-- 新的tag/alias接口结果返回需要开发者配置一个自定的广播 -->        <!-- 该广播需要继承JPush提供的JPushMessageReceiver类, 并如下新增一个 Intent-Filter -->        <receiver        android:name="自定义 Receiver"        android:enabled="true" >        <intent-filter>        <action android:name="cn.jpush.android.intent.RECEIVE_MESSAGE" />        <category android:name="您应用的包名" />        </intent-filter>        </receiver>        <!-- User defined. 用户自定义的广播接收器-->         <receiver             android:name="您自己定义的Receiver"             android:enabled="true">             <intent-filter>                 <!--Required 用户注册SDK的intent-->                 <action android:name="cn.jpush.android.intent.REGISTRATION" />                 <!--Required 用户接收SDK消息的intent-->                 <action android:name="cn.jpush.android.intent.MESSAGE_RECEIVED" />                 <!--Required 用户接收SDK通知栏信息的intent-->                 <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED" />                 <!--Required 用户打开自定义通知栏的intent-->                 <action android:name="cn.jpush.android.intent.NOTIFICATION_OPENED" />                 <!-- 接收网络变化 连接/断开 since 1.6.3 -->                 <action android:name="cn.jpush.android.intent.CONNECTION" />                 <category android:name="您应用的包名" />             </intent-filter>         </receiver>        <!-- 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>
第五步,将这些准备工作做完之后,开始写代码,首先初始化JPush:(一般初始化操作,我们都放在自己的Application类里)
//初始化极光推送JPushInterface.setDebugMode(true);//设置调试模式,避免出现日志无打印情况        JPushInterface.init(this);
然后测试确认:
  • 确认所需的权限都已经添加。如果必须的权限未添加,日志会提示错误。
  • 确认 AppKey(在Portal上生成的)已经正确的写入 Androidmanifest.xml 。
  • 确认在程序启动时候调用了init(context) 接口
  • 确认测试手机(或者模拟器)已成功连入网络 + 客户端调用 init 后不久,如果一切正常,应有登录成功的日志信息
  • 启动应用程序,在 Portal 上向应用程序发送自定义消息或者通知栏提示。详情请参考管理Portal。
    • 在几秒内,客户端应可收到下发的通知或者正定义消息,如果 SDK 工作正常,则日志信息会如下:
[JPushInterface] action:init.......[PushService] Login succeed!
第六步,如果测试登陆成功后,我们可以尝试让服务端给我们发送信息,或者用极光的网站进行发送自定义消息。

如果我们在之前的步骤成功集成了jPush,那么就会将服务端或者极光网站发送的消息通过广播发送到之前下载的极光Demo里面的MyReceiver类。
private static final String TAG = "JPush";@Overridepublic void onReceive(Context context, Intent intent) {Bundle bundle = intent.getExtras();// Log.d(TAG, "[MyReceiver] onReceive - " + intent.getAction() + ",// extras: " + printBundle(bundle));if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {String regId = bundle.getString(JPushInterface.EXTRA_REGISTRATION_ID);Log.d(TAG, "[MyReceiver] 接收Registration Id : " + regId);// send the Registration Id to your server...} else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {Log.d(TAG, "[MyReceiver] 接收到推送下来的自定义消息: " + bundle.getString(JPushInterface.EXTRA_MESSAGE));processCustomMessage(context, bundle);//调用这个方法可以对接受到的内容进行下一步操作} else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {Log.d(TAG, "[MyReceiver] 接收到推送下来的通知");int notifactionId = bundle.getInt(JPushInterface.EXTRA_NOTIFICATION_ID);Log.d(TAG, "[MyReceiver] 接收到推送下来的通知的ID: " + notifactionId);} else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {Log.d(TAG, "[MyReceiver] 用户点击打开了通知");} else if (JPushInterface.ACTION_RICHPUSH_CALLBACK.equals(intent.getAction())) {Log.d(TAG, "[MyReceiver] 用户收到到RICH PUSH CALLBACK: " + bundle.getString(JPushInterface.EXTRA_EXTRA));// 在这里根据 JPushInterface.EXTRA_EXTRA 的内容处理代码,比如打开新的Activity,// 打开一个网页等..} else if (JPushInterface.ACTION_CONNECTION_CHANGE.equals(intent.getAction())) {boolean connected = intent.getBooleanExtra(JPushInterface.EXTRA_CONNECTION_CHANGE, false);Log.w(TAG, "[MyReceiver]" + intent.getAction() + " connected state change to " + connected);} else {Log.d(TAG, "[MyReceiver] Unhandled intent - " + intent.getAction());}}/** * 实现自定义消息内容 *  * @param context * @param bundle */private void processCustomMessage(Context context, Bundle bundle) {NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);NotificationCompat.Builder notification = new NotificationCompat.Builder(context);//这里我们可以获取到我们需要用到的东西String message = bundle.getString(JPushInterface.EXTRA_MESSAGE);//获得服务端发送过来的消息内容String title = bundle.getString(JPushInterface.EXTRA_TITLE);//获得服务端发送过来的标题//为notification设置文本内容为message,标题为title,小图标为系统启动路标notification.setAutoCancel(true).setContentText(message).setContentTitle(title).setSmallIcon(R.drawable.ic_launcher);//点击notification跳转到想打开的ActivityIntent mIntent = new Intent(context, GrMessageListActivity.class);mIntent.putExtras(bundle);PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, mIntent, 0);notification.setContentIntent(pendingIntent);//为notification设置一个自定义铃声notification.setSound(Uri.parse("android.resource://" + context.getPackageName() + "/" + R.raw.test));notificationManager.notify(2, notification.build());
最后一步,我们android客户端在与服务端进行交互时,需要给服务端设置一个别名,代码如下,一般用在项目登录之后
JPushInterface.setAlias(GrLoginActivity.this, 1, elementId);

第三个参数即为别名,这里我用到的是用户id。

至此,一个JPush的基本功能实现的集成流程就完毕了。