这是我第一个使用的推送服务,百度云推送
废话不多说,开始上内容
功能实现过程:
1. 到百度云推送官网下载最新版本的SDK
http://push.baidu.com/sdk/push_client_sdk_for_android
2. 将SDK下的jar包和so文件拉到项目中libs目录下
3. 添加AndroidManifest.XML配置权限
<!-- Push service 运行需要的权限 --><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.READ_PHONE_STATE" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /><uses-permission android:name="android.permission.WRITE_SETTINGS" /><uses-permission android:name="android.permission.VIBRATE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER"/><uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" /><uses-permission android:name="android.permission.DISABLE_KEYGUARD" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
<!-- 4.6版本新增的Activity声明,提升Push后台存活率 --><activity
android:name="com.baidu.android.pushservice.PushKeepAlive"
android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
<!-- push service start --><!-- 用于接收系统消息以保证PushService正常运行 --><receiver android:name="com.baidu.android.pushservice.PushServiceReceiver"
android:process=":bdservice_v1" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="com.baidu.android.pushservice.action.notification.SHOW" />
<action android:name="com.baidu.android.pushservice.action.media.CLICK" />
<!-- 以下四项为可选的action声明,可大大提高service存活率和消息到达速度 -->
<action android:name="android.intent.action.MEDIA_MOUNTED" />
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter></receiver><!-- Push服务接收客户端发送的各种请求--><receiver android:name="com.baidu.android.pushservice.RegistrationReceiver"
android:process=":bdservice_v1" >
<intent-filter>
<action android:name="com.baidu.android.pushservice.action.METHOD" />
<action android:name="com.baidu.android.pushservice.action.BIND_SYNC" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<data android:scheme="package" />
</intent-filter> </receiver><service android:name="com.baidu.android.pushservice.PushService" android:exported="true"
android:process=":bdservice_v1" >
<intent-filter >
<action android:name="com.baidu.android.pushservice.action.PUSH_SERVICE" />
</intent-filter></service><!-- 4.4版本新增的CommandService声明,提升小米和魅族手机上的实际推送到达率 --><service android:name="com.baidu.android.pushservice.CommandService"
android:exported="true" /><!-- push结束 -->
4. 在主activity中的onCreate函数中初始化代码
// 代码
PushManager.startWork(getApplicationContext(),PushConstants.LOGIN_TYPE_API_KEY,"api_key");
其中的api_key字段替换成百度云推送中申请应用的AppKey
5. 自定义回调方法
创建一个类,继承PushMessageReceiver类(底下附完整代码)
重载所有的回调方法
其中onBind(Context context, int errorCode, String appid,String userId, String channelId, String requestId)方法,返回的参数channelId用于标识手机端id,它表示一个手机终端的id,每个手机终端都有自己的id,他是固定的、无法改变的,可用于指定设备推送。
同时,还要在项目中添加新的权限:
<!-- 此处Receiver名字修改为当前包名路径 --><receiver android:name="com.*.*.PushTestReceiver">
<intent-filter>
<!-- 接收push消息 -->
<action android:name="com.baidu.android.pushservice.action.MESSAGE" />
<!-- 接收bind、setTags等method的返回结果-->
<action android:name="com.baidu.android.pushservice.action.RECEIVE" />
<!-- 接收通知点击事件,和通知自定义内容 -->
<action android:name="com.baidu.android.pushservice.action.notification.CLICK" />
</intent-filter></receiver>
其中红色字段com.*.*.PushTestReceiver替换成当前项目的包名和类名,例如:
6. 运行App
如果运行之后打印出来的errorCode = 0,说明绑定成功了,从而可以根据channelid进行推送。channelId从onBind() 中返回获取。
方式:
1. 推送方式有三种:通知、透传、富媒体通知。
通知:创建一条通知,通知推送会直接显示在通知栏上
透传:创建一条透传信息,MyPushMessageReceiver中的onMessage()方法,可以接受到透传信息,并且不会显示在通知栏上
富媒体通知:也是一种通知,区别在于配置展示的模板,通知栏展示更加美观和多样化
2. 推送的范围有四种:所有设备、指定设备、标签设备、精准推送
所有设备:使用同一个key下的Android设备都能接收到推送
指定设备:根据channelID进行推送,最多可同时推送10个不同的id
标签设备:根据channelID创建标签,同一标签下的channelid能同时收到推送,最多同一标签下可达10000个channelId用户。
精准推送:可根据标签组合、地理区域、兴趣精准推送(在我看来这个就是个鸡肋。。。)
3. 由于第一种推送方式的通知过于简单,项目中我使用的是透传方式,服务端发送透传信息,前端MyPushMessageReceiver中的onMessage()方法接受到信息,再自定义一个通知。
4. 此次使用推送,目的是商户端能及时接受到客户端的订单信息以及客户端接受到商户端的处理信息,所以采用的是指定设备,登录和注册时把channelID存储下来,同时传递到服务端,服务端根据channelID以及用户账号进行绑定,获取到新订单时,根据用户账号匹配推送消息。
MypushMessageReceiver类代码:
package com.idiancaiba;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import org.json.JSONException;
import org.json.JSONObject;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import com.baidu.android.pushservice.PushMessageReceiver;
import com.idiancaiba.ui.HomeActivity;
import com.idiancaiba.ui.OrderActivity;
import com.idiancaiba.util.SharedPreferencesUtils;
import com.idiancaiba.util.Utils;
/*
* Push消息处理receiver。请编写您需要的回调函数, 一般来说: onBind是必须的,用来处理startWork返回值;
*onMessage用来接收透传消息; onSetTags、onDelTags、onListTags是tag相关操作的回调;
*onNotificationClicked在通知被点击时回调; onUnbind是stopWork接口的返回值回调
* 返回值中的errorCode,解释如下:
*0 - Success
*10001 - Network Problem
*10101 Integrate Check Error
*30600 - Internal Server Error
*30601 - Method Not Allowed
*30602 - Request Params Not Valid
*30603 - Authentication Failed
*30604 - Quota Use Up Payment Required
*30605 -Data Required Not Found
*30606 - Request Time Expires Timeout
*30607 - Channel Token Timeout
*30608 - Bind Relation Not Found
*30609 - Bind Number Too Many
* 当您遇到以上返回错误时,如果解释不了您的问题,请用同一请求的返回值requestId和errorCode联系我们追查问题。
*
*/
public class MyPushMessageReceiver extends PushMessageReceiver {
/** TAG to Log */
public static final String TAG = MyPushMessageReceiver.class
.getSimpleName();
/**
* 调用PushManager.startWork后,sdk将对push
* server发起绑定请求,这个过程是异步的。绑定请求的结果通过onBind返回。 如果您需要用单播推送,需要把这里获取的channel
* id和user id上传到应用server中,再调用server接口用channel id和user id给单个手机或者用户推送。
*
* @param context
* BroadcastReceiver的执行Context
* @param errorCode
* 绑定接口返回值,0 - 成功
* @param appid
* 应用id。errorCode非0时为null
* @param userId
* 应用user id。errorCode非0时为null
* @param channelId
* 应用channel id。errorCode非0时为null
* @param requestId
* 向服务端发起的请求id。在追查问题时有用;
* @return none
*/
@Override
public void onBind(Context context, int errorCode, String appid,
String userId, String channelId, String requestId) {
String responseString = "onBind errorCode=" + errorCode + " appid="
+ appid + " userId=" + userId + " channelId=" + channelId
+ " requestId=" + requestId;
Log.d(TAG, responseString);
if (errorCode == 0) {
// 绑定成功
SharedPreferencesUtils.setParam(context, "channelId", channelId);
System.out.println("绑定成功! channelId="+channelId);
}
// Demo更新界面展示代码,应用请在这里加入自己的处理逻辑
updateContent(context, responseString);
}
/**
* 接收透传消息的函数。
*
* @param context
* 上下文
* @param message
* 推送的消息
* @param customContentString
* 自定义内容,为空或者json字符串
*/
@Override
public void onMessage(Context context, String message,
String customContentString) {
String messageString = "透传消息 message=\"" + message+ "\" customContentString=" + customContentString;
System.out.println(messageString);
if (!TextUtils.isEmpty(message)) {
JSONObject customJson = null;
try {
customJson = new JSONObject(message);
String title= customJson.getString("title");
String description= customJson.getString("description");
init(context,title,description);
} catch (JSONException e) {
e.printStackTrace();
}
}
// Demo更新界面展示代码,应用请在这里加入自己的处理逻辑
updateContent(context, messageString);
}
/**
* 初始化通知信息
* @param context
* @param description
* @param title
*/
private void init(Context context, String title, String description){
NotificationManager manager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder mBuiler = new Notification.Builder(context);
mBuiler.setContentTitle(title)//标题
.setAutoCancel(true)//点击通知消失
.setContentText(description)//文本
.setContentIntent(getDefalutIntent(context))//点击事件,传到activity
.setTicker(description)//一闪而过标题
.setWhen(System.currentTimeMillis())//通知时间
.setSmallIcon(R.drawable.notification)//图标
.setVibrate(new long[] {0,300,500,700})//震动
.setLights(0xff0000ff, 300, 0)//三色灯,没有
.setSound(Uri.parse("android.resource://com.idiancaiba/"+R.raw.sound));//自定义声音文件
manager.notify((int)System.currentTimeMillis(), mBuiler.build());
}
/**
* 设置点击通知跳转,按back键返回主页面
* @return
*/
public PendingIntent getDefalutIntent(Context context){
Intent[] intents = new Intent[2];
intents[0] = Intent.makeRestartActivityTask(new ComponentName(context, HomeActivity.class));
intents[1] = new Intent(context,OrderActivity.class);
PendingIntent pendingIntent= PendingIntent.getActivities(context, 0, intents, Notification.FLAG_AUTO_CANCEL);
return pendingIntent;
}
/**
* 接收通知点击的函数。
*
* @param context
* 上下文
* @param title
* 推送的通知的标题
* @param description
* 推送的通知的描述
* @param customContentString
* 自定义内容,为空或者json字符串
*/
@Override
public void onNotificationClicked(Context context, String title,
String description, String customContentString) {
String notifyString = "通知点击 title=\"" + title + "\" description=\""
+ description + "\" customContent=" + customContentString;
Log.d(TAG, notifyString);
//百度云推送默认点击后跳转到指定页面 需加上下面代码才能跳转到指定位置
Intent intent = new Intent();
intent.setClass(context.getApplicationContext(), OrderActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.getApplicationContext().startActivity(intent);
// 自定义内容获取方式,mykey和myvalue对应通知推送时自定义内容中设置的键和值
if (!TextUtils.isEmpty(customContentString)) {
JSONObject customJson = null;
try {
customJson = new JSONObject(customContentString);
String myvalue = null;
if (!customJson.isNull("mykey")) {
myvalue = customJson.getString("mykey");
}
} catch (JSONException e) {
e.printStackTrace();
}
}
// Demo更新界面展示代码,应用请在这里加入自己的处理逻辑
updateContent(context, notifyString);
}
/**
* 接收通知到达的函数。
*
* @param context
* 上下文
* @param title
* 推送的通知的标题
* @param description
* 推送的通知的描述
* @param customContentString
* 自定义内容,为空或者json字符串
*/
@Override
public void onNotificationArrived(Context context, String title,
String description, String customContentString) {
String notifyString = "onNotificationArrived title=\"" + title
+ "\" description=\"" + description + "\" customContent="
+ customContentString;
Log.d(TAG, notifyString);
// 自定义内容获取方式,mykey和myvalue对应通知推送时自定义内容中设置的键和值
if (!TextUtils.isEmpty(customContentString)) {
JSONObject customJson = null;
try {
customJson = new JSONObject(customContentString);
String myvalue = null;
if (!customJson.isNull("mykey")) {
myvalue = customJson.getString("mykey");
}
} catch (JSONException e) {
e.printStackTrace();
}
}
// Demo更新界面展示代码,应用请在这里加入自己的处理逻辑
// 你可以參考 onNotificationClicked中的提示从自定义内容获取具体值
updateContent(context, notifyString);
}
/**
* setTags() 的回调函数。
*
* @param context
* 上下文
* @param errorCode
* 错误码。0表示某些tag已经设置成功;非0表示所有tag的设置均失败。
* @param successTags
* 设置成功的tag
* @param failTags
* 设置失败的tag
* @param requestId
* 分配给对云推送的请求的id
*/
@Override
public void onSetTags(Context context, int errorCode,
List<String> sucessTags, List<String> failTags, String requestId) {
String responseString = "onSetTags errorCode=" + errorCode
+ " sucessTags=" + sucessTags + " failTags=" + failTags
+ " requestId=" + requestId;
Log.d(TAG, responseString);
// Demo更新界面展示代码,应用请在这里加入自己的处理逻辑
updateContent(context, responseString);
}
/**
* delTags() 的回调函数。
*
* @param context
* 上下文
* @param errorCode
* 错误码。0表示某些tag已经删除成功;非0表示所有tag均删除失败。
* @param successTags
* 成功删除的tag
* @param failTags
* 删除失败的tag
* @param requestId
* 分配给对云推送的请求的id
*/
@Override
public void onDelTags(Context context, int errorCode,
List<String> sucessTags, List<String> failTags, String requestId) {
String responseString = "onDelTags errorCode=" + errorCode
+ " sucessTags=" + sucessTags + " failTags=" + failTags
+ " requestId=" + requestId;
Log.d(TAG, responseString);
// Demo更新界面展示代码,应用请在这里加入自己的处理逻辑
updateContent(context, responseString);
}
/**
* listTags() 的回调函数。
*
* @param context
* 上下文
* @param errorCode
* 错误码。0表示列举tag成功;非0表示失败。
* @param tags
* 当前应用设置的所有tag。
* @param requestId
* 分配给对云推送的请求的id
*/
@Override
public void onListTags(Context context, int errorCode, List<String> tags,
String requestId) {
String responseString = "onListTags errorCode=" + errorCode + " tags="
+ tags;
Log.d(TAG, responseString);
// Demo更新界面展示代码,应用请在这里加入自己的处理逻辑
updateContent(context, responseString);
}
/**
* PushManager.stopWork() 的回调函数。
*
* @param context
* 上下文
* @param errorCode
* 错误码。0表示从云推送解绑定成功;非0表示失败。
* @param requestId
* 分配给对云推送的请求的id
*/
@Override
public void onUnbind(Context context, int errorCode, String requestId) {
String responseString = "onUnbind errorCode=" + errorCode
+ " requestId = " + requestId;
Log.d(TAG, responseString);
if (errorCode == 0) {
// 解绑定成功
Log.d(TAG, "解绑成功");
SharedPreferencesUtils.cleanChannelId(context);
}
// Demo更新界面展示代码,应用请在这里加入自己的处理逻辑
updateContent(context, responseString);
}
@SuppressLint("SimpleDateFormat")
private void updateContent(Context context, String content) {
Log.d(TAG, "updateContent");
String logText = "" + Utils.logStringCache;
if (!logText.equals("")) {
logText += "\n";
}
SimpleDateFormat sDateFormat = new SimpleDateFormat("HH-mm-ss");
logText += sDateFormat.format(new Date()) + ": ";
logText += content;
Utils.logStringCache = logText;
}
}
以上为个人的总结,疑问或者有不妥当之处,请指出