极光推送在人脸识别终端管理系统中的应用

项目背景

最近开发的一款人脸识别终端管理系统,主要包括运营平台、企业后台管理系统、App端、智能人脸识别终端模块;下图是系统的架构图:

null

其中各个模块之间都需要即时通讯,比如:

  • App端用户注册完成之后,企业管理员在后台管理系统中将用户邀请进入企业,此时需要及时通知用户已加入企业;

  • 当管理员将该用户加入到指定的用户组时,需要将该用户的人脸信息下发到关联了该用户组的智能人脸识别终端中;

  • 管理员更改用户或者设备信息时都需要及时通知到相关的设备同步最新的数据;

  • 用户app远程开门需要发送实时消息给到门禁(或者闸机),门禁(或闸机)收到开门消息后方可开门;

  • 当管理员发布广告或者公告时,需要通知到指定的门禁设备播放最新的消息;

...大概十多项通知都离不开消息的推送,此时最先想到的自然是集成第三方稳定高效的即时推送方案(App端还需要有强大的离线推送功能)。

尊重原创,转载请注明出处,原文地址: http://blog.csdn.net/qq137722697

为什么选择极光推送

集成第三方推送无非出于以下几点考虑:推送稳定高效、方便集成、App离线模式支持更多的机型(通道)、App进程互相拉起、有效的数据统计,最重要的一点要免费;无疑极光推送都满足了这几方面,本人是极光推送几年的老用户,,并且在几年前写过一篇【(快速搞定)2分钟集成极光推送(极光推送Android端集成)https://blog.csdn.net/qq137722697/article/details/52475605】的文章,当时使用极光推送的时候还没有几家推送SDK,可以说极光推送是较早的一批推送方案了,这么多年的积累稳定性方面毋庸置疑。

Android快速集成极光推送

下面一步一步教大家快速集成极光推送(尽量按下面的方式进行,说不定可以少走很多弯路哦):

官方可能要考虑一些额外的情况加了个一个手动集成的教程,现在都2020年了当然得用依赖jcenter项目的方式来集成啦,如需手动集成请移步官方稳定;

开发环境:

  • Android Studio 3.0.1 正式版

  • gradle v3.0.1

  • compileSdkVersion 26

  • targetSdkVersion 22 (减少不必要的动态权限请求)

开发者账号注册、创建应用这些就不说了哈,根据官网提示即可创建完成。

第一步:创建项目名叫smart_face_jpush的项目(有项目的请忽略这一步)

null

第二步:配置app/build.gradle文件


apply plugin: 'com.android.application'  

android {  
    compileSdkVersion 26  
  defaultConfig {  
        applicationId "com.hdl.smartface"//JPush 上注册的包名.  
  minSdkVersion 17  
  targetSdkVersion 22  
  versionCode 1  
  versionName "1.0"  
  testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"  
  //极光推送配置----------开始-----------  
  ndk {  
            //一般armeabi-v7a已能适配绝大部分机型  
  abiFilters 'armeabi-v7a'  
  // 还可以添加 'armeabi', 'arm64-v8a', 'x86', 'x86_64', 'mips', 'mips64'  }  
        manifestPlaceholders = [  
                JPUSH_PKGNAME: applicationId,  
                JPUSH_APPKEY : "307d4e883d70b727687597fb", //JPush 上注册的包名对应的 Appkey.  JPUSH_CHANNEL: "developer-default", //暂时填写默认值即可.  
  ]  
        //极光推送配置----------结束-----------  
  }  

    buildTypes {  
        release {  
            minifyEnabled false  
  proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'  
  }  
    }  
}  

dependencies {  
    implementation fileTree(dir: 'libs', include: ['*.jar'])  
    implementation 'com.android.support:appcompat-v7:26.1.0'  
  testImplementation 'junit:junit:4.12'  
  androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {  
        exclude group: 'com.android.support', module: 'support-annotations'  
  })  
    //极光推送相关库  
  implementation 'cn.jiguang.sdk:jpush:3.5.4'   
  implementation 'cn.jiguang.sdk:jcore:2.2.6' 

//日志库

implementation 'com.hdl:elog:v2.0.2'


}

配置完成之后需要同步仓库,如图Try Again

null

第三步:配置清单文件

在AndroidManifest.xml的application中加入极光推送必要的配置


<?xml version="1.0" encoding="utf-8"?>  
<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  xmlns:tools="http://schemas.android.com/tools"  
  package="com.hdl.smartface">  

 <application  android:name=".base.MyApp"  
  android:allowBackup="true"  
  android:icon="@mipmap/ic_launcher"  
  android:label="@string/app_name"  
  android:roundIcon="@mipmap/ic_launcher_round"  
  android:supportsRtl="true"  
  android:theme="@style/AppTheme">  
 <activity android:name=".MainActivity">  
 <intent-filter> <action android:name="android.intent.action.MAIN" />  

 <category android:name="android.intent.category.LAUNCHER" />  
 </intent-filter> </activity>  <!--极光推送*********************************开始************************************-->  
 <!-- 若您的业务中有使用极光富媒体功能,或者极光早上好功能,需要把此 Activity 的 exported 修改成 true 覆盖 jcenter 上的组件。 -->  
  <activity  
  android:name="cn.jpush.android.ui.PopWinActivity"  
  android:exported="true"  
  android:theme="@style/MyDialogStyle"  
  tools:node="replace">  
 <intent-filter> <category android:name="android.intent.category.DEFAULT" />  
 <action android:name="cn.jpush.android.ui.PopWinActivity" />  
 <category android:name="${applicationId}" />  
 </intent-filter> </activity>  
  <!-- 若您的业务中有使用极光富媒体功能,或者极光早上好功能,需要把此 Activity 的 exported 修改成 true 覆盖 jcenter 上的组件。 -->  
  <activity  
  android:name="cn.jpush.android.ui.PushActivity"  
  android:configChanges="orientation|keyboardHidden"  
  android:exported="true"  
  android:theme="@android:style/Theme.NoTitleBar"  
  tools:node="replace">  
 <intent-filter> <action android:name="cn.jpush.android.ui.PushActivity" />  

 <category android:name="android.intent.category.DEFAULT" />  
 <category android:name="${applicationId}" />  
 </intent-filter> </activity>  <!--用于接收推送消息的广播接收器-->  
  <receiver  
  android:name=".receiver.JpushReceiver"  
  android:enabled="true"  
  android:exported="false">  
 <intent-filter> <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 用户接收SDK通知栏信息的intent-->  
  <action android:name="cn.jpush.android.intent.NOTIFICATION_OPENED" /> <!--Required 用户打开自定义通知栏的intent-->  
  <action android:name="cn.jpush.android.intent.CONNECTION" /><!-- 接收网络变化 连接/断开 since 1.6.3 -->  <category android:name="com.hdl.smartface" />  
 </intent-filter> </receiver>  <!--用于接收tag标签和alias别名相关消息-->  
  <receiver android:name=".receiver.MyJpushMessageReceiver">  
 <intent-filter> <action android:name="cn.jpush.android.intent.RECEIVE_MESSAGE" />  
 <category android:name="com.hdl.smartface"></category>  
 </intent-filter> </receiver>  <!-- Required SDK核心功能-->  
  <receiver  
  android:name="cn.jpush.android.service.PushReceiver"  
  android:enabled="true"  
  android:exported="false">  
 <intent-filter android:priority="1000">  
 <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED_PROXY" /> <!--Required 显示通知栏 -->  
  <category android:name="com.hdl.smartface" />  
 </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核心功能-->  
  <receiver  
  android:name="cn.jpush.android.service.AlarmReceiver"  
  android:exported="false" />  
  <!-- 可配置android:process参数将PushService放在其他进程中 -->  
  <service  
  android:name="cn.jpush.android.service.PushService"  
  android:exported="false"  
  android:process=":pushcore">  
 <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>  <!-- 这个Service要继承JCommonService -->  
  <service  
  android:name=".services.PushService"  
  android:process=":pushcore">  
 <intent-filter> <action android:name="cn.jiguang.user.service.action" />  
 </intent-filter> </service>  <!--极光推送*********************************结束************************************-->  

  </application>  

</manifest>

第四步:混淆配置

在proguard-rules.pro文件中加入一下配置


#极光推送混淆配置-------------开始------------  
-dontoptimize  
-dontpreverify  

-dontwarn cn.jpush.**  
-keep class cn.jpush.** { *; }  
-keep class * extends cn.jpush.android.helpers.JPushMessageReceiver { *; }  

-dontwarn cn.jiguang.**  
-keep class cn.jiguang.** { *; }  
#极光推送混淆配置-------------结束------------

第五步:创建接收消息的广播接收器JpushReceiver


package com.hdl.smartface.receiver;  

import android.content.BroadcastReceiver;  
import android.content.Context;  
import android.content.Intent;  
import android.os.Bundle;  
import android.text.TextUtils;  

import com.hdl.elog.ELog;  

import org.json.JSONException;  
import org.json.JSONObject;  

import java.util.Iterator;  

import cn.jpush.android.api.JPushInterface;  
import cn.jpush.android.helper.Logger;  

/**  
 * 自定义接收器  
  * <p>  
  * 如果不定义这个 Receiver,则:  
  * 1) 默认用户会打开主界面  
  * 2) 接收不到自定义消息  
  *  
 * @author Admin  
 */public class JpushReceiver extends BroadcastReceiver {  
    private static final String TAG = "JpushReceiver";  

  @Override  
  public void onReceive(Context context, Intent intent) {  
        try {  
            Bundle bundle = intent.getExtras();  
  ELog.e(TAG, "[JpushReceiver] onReceive - " + intent.getAction() + ", extras: " + printBundle(bundle));  

 if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {  
                String regId = bundle.getString(JPushInterface.EXTRA_REGISTRATION_ID);  
  ELog.e(TAG, "[JpushReceiver] 接收Registration Id : " + regId);  
  //send the Registration Id to your server...  

  } else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {  
                ELog.e(TAG, "[JpushReceiver] 接收到推送下来的自定义消息: " + bundle.getString(JPushInterface.EXTRA_MESSAGE));  
//          processCustomMessage(context, bundle);  

  } else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {  
                ELog.e(TAG, "[JpushReceiver] 接收到推送下来的通知");  
 int notifactionId = bundle.getInt(JPushInterface.EXTRA_NOTIFICATION_ID);  
  ELog.e(TAG, "[JpushReceiver] 接收到推送下来的通知的ID: " + notifactionId);  

  } else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {  
                ELog.e(TAG, "[JpushReceiver] 用户点击打开了通知");  

  //打开自定义的Activity  
//          Intent i = new Intent(context, TestActivity.class);  
//          i.putExtras(bundle);  
 //i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//          i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP );  
//          context.startActivity(i);  

  } else if (JPushInterface.ACTION_RICHPUSH_CALLBACK.equals(intent.getAction())) {  
                ELog.e(TAG, "[JpushReceiver] 用户收到到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);  
  Logger.w(TAG, "[JpushReceiver]" + intent.getAction() + " connected state change to " + connected);  
  } else {  
                ELog.e(TAG, "[JpushReceiver] Unhandled intent - " + intent.getAction());  
  }  
        } catch (Exception e) {  

        }  

    }  

    /**  
 * 打印所有的 intent extra 数据  
  *  
 * @param bundle  
  * @return  
  */  
  private static String printBundle(Bundle bundle) {  
        StringBuilder sb = new StringBuilder();  
 for (String key : bundle.keySet()) {  
            if (key.equals(JPushInterface.EXTRA_NOTIFICATION_ID)) {  
                sb.append("\nkey:" + key + ", value:" + bundle.getInt(key));  
  } else if (key.equals(JPushInterface.EXTRA_CONNECTION_CHANGE)) {  
                sb.append("\nkey:" + key + ", value:" + bundle.getBoolean(key));  
  } else if (key.equals(JPushInterface.EXTRA_EXTRA)) {  
                if (TextUtils.isEmpty(bundle.getString(JPushInterface.EXTRA_EXTRA))) {  
                    Logger.i(TAG, "This message has no Extra data");  
 continue;  }  

                try {  
                    JSONObject json = new JSONObject(bundle.getString(JPushInterface.EXTRA_EXTRA));  
  Iterator<String> it = json.keys();  

 while (it.hasNext()) {  
                        String myKey = it.next();  
  sb.append("\nkey:" + key + ", value: [" +  
                                myKey + " - " + json.optString(myKey) + "]");  
  }  
                } catch (JSONException e) {  
                    Logger.e(TAG, "Get message extra JSON error!");  
  }  

            } else {  
                sb.append("\nkey:" + key + ", value:" + bundle.get(key));  
  }  
        }  
        return sb.toString();  
  }  
}  


第六步:创建继承至JPushMessageReceiver的广播接收器MyJpushMessageReceiver


package com.hdl.smartface.receiver;  

import android.content.Context;  
import android.util.Log;  

import cn.jpush.android.api.JPushMessage;  
import cn.jpush.android.service.JPushMessageReceiver;  

/**  
 * 自定义JPush message 接收器,包括操作tag/alias的结果返回(仅仅包含tag/alias新接口部分)  
 * * @author Admin  
 */public class MyJpushMessageReceiver extends JPushMessageReceiver {  
    private static final String TAG = "MyJpushMessageReceiver";  

  @Override  
  public void onTagOperatorResult(Context context, JPushMessage jPushMessage) {  
        super.onTagOperatorResult(context, jPushMessage);  
  Log.e(TAG, "onTagOperatorResult: code = " + jPushMessage.getErrorCode());  
  }  

    @Override  
  public void onCheckTagOperatorResult(Context context, JPushMessage jPushMessage) {  
        super.onCheckTagOperatorResult(context, jPushMessage);  
  Log.e(TAG, "onCheckTagOperatorResult: code = " + jPushMessage.getErrorCode());  
  }  

    @Override  
  public void onAliasOperatorResult(Context context, JPushMessage jPushMessage) {  
        super.onAliasOperatorResult(context, jPushMessage);  
  Log.e(TAG, "onAliasOperatorResult: code = " + jPushMessage.getErrorCode());  
  }  

    @Override  
  public void onMobileNumberOperatorResult(Context context, JPushMessage jPushMessage) {  
        super.onMobileNumberOperatorResult(context, jPushMessage);  
  Log.e(TAG, "onMobileNumberOperatorResult: code = " + jPushMessage.getErrorCode());  
  }  
}

第七步:初始化sdk

新建应用启动类MyApp(继承至Application的类--如已有此类请忽略新建过程)并在onCreate中初始化极光推送


package com.hdl.smartface.base;  

import android.app.Application;  

import cn.jpush.android.api.JPushInterface;  

/**  
 * 应用启动类  
  * Created by Admin on 2020/1/11.  
 * * @author Admin  
 */  
public class MyApp extends Application {  
    @Override  
  public void onCreate() {  
        super.onCreate();  
  initJpush();  
  }  

    /**  
 * 初始化极光推送  
  */  
  private void initJpush() {  
        //调试模式开关,正式版需设置未false  
  JPushInterface.setDebugMode(true);  
  //初始化极光推送  
  JPushInterface.init(this);  
  }  
}  

同时AndroidMenifest.xml中的application标签加入


...

<application  
 ...  
  android:name=".base.MyApp"  
  ...>

....

测试

本项目中智能人脸识别终端都是使用的自定义消息(不用弹出通知),通知主要是针对用户App端(会在手机通知栏弹出通知信息)

测试Android端接收通知

打开极光推送后台,“发送通知”页面,输入标题和内容,点击发送预览即可

null

此时App端能收到以下信息说明集成成功:

null

测试Android端接收自定义消息

打开极光推送后台,“自定义消息”页面,输入通知内容,点击发送预览即可

null

此时App端能收到以下信息说明接收自定义消息成功:

null

消息接收正常,只需要根据消息内容来处理相应的逻辑即可,所以只需要前后端商量好消息的协议即可,倒数第二章会给出一些消息协议的定制建议以便于前端解析协议。

服务端快速集成极光推送

你可能已经发现,发送消息是通过极光推送的后台管理页面发送的,实际业务中总不能跑他们官网一条消息一条消息的发吧!

是的,极光推送是提供得有服务端推送SDK的,我们只需要集成他们的SDK来发送消息,app端负责接收消息即可。

本项目的服务端是基于java开发的,所以使用极光推送服务端SDK for Java版来做示例。

创建一个maven项目,加入极光推送相关推送


<?xml version="1.0" encoding="UTF-8"?>  
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">  
 <modelVersion>4.0.0</modelVersion>  
 <parent> <groupId>org.springframework.boot</groupId>  
 <artifactId>spring-boot-starter-parent</artifactId>  
 <version>2.2.2.RELEASE</version>  
 <relativePath/> <!-- lookup parent from repository -->  
  </parent>  
 <groupId>com.hdl</groupId>  
 <artifactId>smartface</artifactId>  
 <version>0.0.1-SNAPSHOT</version>  
 <name>smartface</name>  
 <description>Demo project for Spring Boot</description>  

 <properties> <java.version>1.8</java.version>  
 </properties>  
 <dependencies> <dependency> <groupId>org.springframework.boot</groupId>  
 <artifactId>spring-boot-starter</artifactId>  
 </dependency>  
 <dependency> <groupId>org.springframework.boot</groupId>  
 <artifactId>spring-boot-starter-test</artifactId>  
 <scope>test</scope>  
 <exclusions> <exclusion> <groupId>org.junit.vintage</groupId>  
 <artifactId>junit-vintage-engine</artifactId>  
 </exclusion> </exclusions> </dependency>  <!--极光推送相关依赖*************开始************-->  
  <dependency>  
 <groupId>cn.jpush.api</groupId>  
 <artifactId>jpush-client</artifactId>  
 <version>3.4.3</version>  
 </dependency> <dependency> <groupId>cn.jpush.api</groupId>  
 <artifactId>jiguang-common</artifactId>  
 <version>1.1.4</version>  
 </dependency> <dependency> <groupId>io.netty</groupId>  
 <artifactId>netty-all</artifactId>  
 <version>4.1.6.Final</version>  
 <scope>compile</scope>  
 </dependency> <dependency> <groupId>com.google.code.gson</groupId>  
 <artifactId>gson</artifactId>  
 <version>2.3</version>  
 </dependency> <dependency> <groupId>org.slf4j</groupId>  
 <artifactId>slf4j-api</artifactId>  
 <version>1.7.7</version>  
 </dependency>  
  <!-- For log4j -->  
  <dependency>  
 <groupId>org.slf4j</groupId>  
 <artifactId>slf4j-log4j12</artifactId>  
 <version>1.7.7</version>  
 </dependency> <dependency> <groupId>log4j</groupId>  
 <artifactId>log4j</artifactId>  
 <version>1.2.17</version>  
 </dependency>  <!--极光推送相关依赖*************结束************-->  
  </dependencies>  

 <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId>  
 <artifactId>spring-boot-maven-plugin</artifactId>  
 </plugin> </plugins> </build>  
</project>

测试服务端下发通知

同步完成,记下来开始测试消息发送


package com.hdl.smartface;  

import cn.jiguang.common.ClientConfig;  
import cn.jiguang.common.resp.APIConnectionException;  
import cn.jiguang.common.resp.APIRequestException;  
import cn.jpush.api.JPushClient;  
import cn.jpush.api.push.PushResult;  
import cn.jpush.api.push.model.PushPayload;  
import org.junit.jupiter.api.Test;  
import org.slf4j.Logger;  
import org.slf4j.LoggerFactory;  

import static cn.jpush.api.push.model.notification.PlatformNotification.ALERT;  

public class JPushTest {  
    protected static final Logger LOG = LoggerFactory.getLogger(SmartfaceApplicationTests.class);  
  /**  
 * 极光推送应用管理中获取  
  */  
  private static final String MASTER_SECRET = "6031870790216966f74410d1";  
  /**  
 * 极光推送应用管理中获取  
  */  
  private static final String APP_KEY = "307d4e883d70b727687597fb";  

 public static PushPayload buildPushObject_all_all_alert() {  
        return PushPayload.alertAll(ALERT);  
  }  

    @Test  
  public void testPushMsg() {  
        JPushClient jpushClient = new JPushClient(MASTER_SECRET, APP_KEY, null, ClientConfig.getInstance());  

  // For push, all you need do is to build PushPayload object.  
  PushPayload payload = buildPushObject_all_all_alert();  

 try {  
            PushResult result = jpushClient.sendPush(payload);  
  LOG.info("Got result - " + result);  

  } catch (APIConnectionException e) {  
            // Connection error, should retry later  
  LOG.error("Connection error, should retry later", e);  
  } catch (APIRequestException e) {  
            // Should review the error, and fix the request  
  LOG.error("Should review the error, and fix the request", e);  
  LOG.info("HTTP Status: " + e.getStatus());  
  LOG.info("Error Code: " + e.getErrorCode());  
  LOG.info("Error Message: " + e.getErrorMessage());  
  }  
    }  
}

此时服务端控制台输入以下消息说明推送成功

null

Android控制台输入以下信息说明接收消息成功:

null

发送自定义消息

发送自定义消息,只需调用方法PushPayload.Builder.setMessage(Message.content("要发送的自定义消息"))即可


/**  
 * 测试推送自定义消息  
  */  
@Test  
public void testPushCustomMsg() {  
    JPushClient jpushClient = new JPushClient(MASTER_SECRET, APP_KEY, null, ClientConfig.getInstance());  

  PushPayload pushPayload = PushPayload.newBuilder()  
            .setPlatform(Platform.all())  
            .setAudience(Audience.all())  
            .setMessage(Message.content("This is a custom msg"))  
            .build();  
 try {  
        PushResult result = jpushClient.sendPush(pushPayload);  
  LOG.info("Got result - " + result);  

  } catch (APIConnectionException e) {  
        // Connection error, should retry later  
  LOG.error("Connection error, should retry later", e);  
  } catch (APIRequestException e) {  
        // Should review the error, and fix the request  
  LOG.error("Should review the error, and fix the request", e);  
  LOG.info("HTTP Status: " + e.getStatus());  
  LOG.info("Error Code: " + e.getErrorCode());  
  LOG.info("Error Message: " + e.getErrorMessage());  
  }  
}

App端接收到以下消息说明发送自定义消息成功

null

模拟新增人员信息消息

先来看看人员信息实体类:


package com.hdl.smartface.model;  

/**  
 * 人脸用户信息  
  */  
public class FaceUser {  
    /**  
 * 姓名  
  */  
  private String name;  
  /**  
 * 手机号  
  */  
  private String phone;  
  /**  
 * 人脸特征值  
  */  
  private String featrue;  
  /**  
 * 人脸图片  
  */  
  private String pic;  

 ...省略getter setter  toString  
}

公共自定义消息实体类(定义说明请看下一节介绍)


package com.hdl.smartface.base;  

/**  
 * 公共自定义消息返回体  
  */  
public class BaseCustomMessage<T> {  
    /**  
 * 消息类型  
  */  
  private String type;  
  /**  
 * 消息简介  
  */  
  private String msg;  
  /**  
 * 可变参数【扩展参数】  
  */  
  private T data;  

 public String getType() {  
        return type;  
  }  

    public void setType(String type) {  
        this.type = type;  
  }  

    public String getMsg() {  
        return msg;  
  }  

    public void setMsg(String msg) {  
        this.msg = msg;  
  }  

    public T getData() {  
        return data;  
  }  

    public void setData(T data) {  
        this.data = data;  
  }  

    @Override  
  public String toString() {  
        return "BaseCustomMessage{" +  
                "type='" + type + '\'' +  
                ", msg='" + msg + '\'' +  
                ", data=" + data +  
                '}';  
  }  
}

服务端发送测试消息:


/**  
 * 测试发送新增人脸信息消息  
  */  
@Test  
public void testSendAddFaceUserMessage() {  
    JPushClient jpushClient = new JPushClient(MASTER_SECRET, APP_KEY, null, ClientConfig.getInstance());  
  //模拟构建需要下发的人员信息  
  FaceUser faceUser = new FaceUser();  
  faceUser.setName("大力哥");  
  faceUser.setPhone("155959595959");  
  faceUser.setFeatrue("http://face.hdl.com/featrue/155959595959.data");  
  faceUser.setPic("http://face.hdl.com/pic/155959595959.png");  
  //模拟构建自定义消息体  
  BaseCustomMessage<FaceUser> faceUserMessage = new BaseCustomMessage<>();  
  faceUserMessage.setType("1001001");//方便测试,这里写死,type和msg建议按下一章的建议来制定  
  faceUserMessage.setMsg("新人脸更新");  
  faceUserMessage.setData(faceUser);  
  PushPayload pushPayload = PushPayload.newBuilder()  
            .setPlatform(Platform.all())  
            .setAudience(Audience.all())  
            .setMessage(Message.content(new Gson().toJson(faceUserMessage)))//使用gson将对象转成json  
  .build();  
 try {  
        PushResult result = jpushClient.sendPush(pushPayload);  
  LOG.info("Got result - " + result);  

  } catch (APIConnectionException e) {  
        // Connection error, should retry later  
  LOG.error("Connection error, should retry later", e);  
  } catch (APIRequestException e) {  
        // Should review the error, and fix the request  
  LOG.error("Should review the error, and fix the request", e);  
  LOG.info("HTTP Status: " + e.getStatus());  
  LOG.info("Error Code: " + e.getErrorCode());  
  LOG.info("Error Message: " + e.getErrorMessage());  
  }  
}

此时app端会收到以下消息:

null

自定义消息推送协议的制定

此处只作为参考,最终还是得根据你们的实际情况来制定。

协议使用json来制定,分为公共参数和可变参数部分(或者叫扩展参数)


{  
    "type":"消息类型编号",  
    "msg":"消息说明",  
    "data":根据消息的类型传递不同的json对象  
}  

此处的type定义,建议后端使用字典来管理或者使用枚举也行,类型的编号建议有一定的编码信息,便于业务的统计与分析,如下图:

null

当服务端新增人脸消息时,需要及时下发消息给相应的人脸识别终端下载最新的人脸信息,此时消息协议可以这么定


{

    "type":"1001001",

    "msg":"新人脸更新",

    "data":{

        "name":"大力哥",

        "phone":"155959595959",

        "featrue":"http://face.hdl.com/featrue/155959595959.data",

        "pic":"http://face.hdl.com/pic/155959595959.png"

    }

}

data是可变参数字段(或者叫扩展参数字段),根据不同的type放回不同的实体即可,再来一个下发人脸识别终端广告的协议:


{

    "type":"20010658",

    "msg":"广告更新通知",

    "data":[

        {

            "url":"http://face.hdl.com/adv/qhkhk3g523424aqat.png",

            "sourceType":"img",

            "duration":5,

            "title":"恭祝大家新春快乐"

        },

        {

            "url":"http://face.hdl.com/adv/ioweybzgkshywet12b34.mp4",

            "sourceType":"vedio",

            "duration":-1,

            "title":"给大家拜年啦"

        },

        {

            "url":"http://face.hdl.com/adv/shdgwsgsd124sgs.png",

            "sourceType":"img",

            "duration":5,

            "title":"年货节火热进行中"

        }

    ]

}

此时的data可以是一个集合,表示下发三条广告信息。

null

写在最后的话

阅读完本文相信您已经基本了解到如何将极光推送应用到实际项目中,并且能够快速集成Android端SDK和Java服务端SDK,限于篇幅很多功能未能一一介绍,如看完本文还有疑问可评论留言或者移步官方网站;

下面给出本文的demo地址:

尊重原创,转载请注明出处,原文地址: http://blog.csdn.net/qq137722697