因为之前没有集成过百度云推送,接手新项目之后项目需求是接入百度云推送,没办法因为项目是海外项目所以只能硬着头皮来接入了,话不多说开始你的表演:
首先就是去百度云推送的官网去创建应用并启用:
.在配置详情页中,扫描二维码或者点击下载SDK,可以下载对应包名的demo,个人建议直接点击右上角的下载SDK来下载demo,因为我刚开始使用二维码下载下来的demo并不是最新的版本,也没有百度云产品的简介。
.运行demo没问题也可以推送,感觉百度云推送还是很nice的,so那就去集成到咱们自己的项目中吧
.将自己需要的文件提取出来,尽可能的去掉无用的东西。**demo中包好了许多功能是你用不到的,因此需要将自己需要功能的相关文件摘出来。结果测试没问题。需要的东西如下:
pushservice-5.2.0.12.jar包,所有的.so文件,notification_custom_builder.xml(这是通知栏的布局),
注意:如果您的 Android 工程使用的是 Android API level 21 及以上的版本,您的通知图标背景 必须是透明的,否则在 Android5.0 及以上的机器上通知图标可能会变成白色的方块。
在该工程下创建一个 libs 文件夹
将 pushservice-VERSION.jar 拷贝到 libs 文件夹中,把 SDK 压缩包中的 libs/armeabi 目录下的
libbdpush_V2_9.so 拷贝到工程对应的 libs/armeabi 文件夹下。
a) 如果你的工程中没有使用其他的.so,建议只复制 armeabi 文件夹。
b) 如果你的工程中还使用了其他的.so 文件,只需要拷贝云推送对应目录下的.so 文件。
c) 如果你使用的 Android 开发环境是 Android Stutio,在工程中“src/main”目录中新建名为
jniLibs 的目录,将 libs 文件夹中文件拷贝到“jniLibs”目录内。
.AndroidManifest.xm中的权限:
.AndroidManifest.xml 注册消息接收 Receiver
客户端需实现自己的 MyPushMessageReceiver,接收 Push 服务的消息,并实现对消息的处理。以
下是 AndroidManifest.xml 中的配置代码。
7. AndroidManifest.xml 增加 pushservice 配置
8. 富媒体功能(可选)
富媒体是相对于一般消息而言,一种高级的通知,提供文本、视频、音乐等形式的消息。您需要 把富媒体相关的资源文件(包括 layout 文件、图片和字符资源分别添加到相应的资源目录),同时在 AndroidManifest.xml 文件里声明富媒体 Activity。如果应用不支持富媒体推送功能,可以不添加相关的 资源和声明。在 targetSdkVersion>=23 时,需要应用具有 sd 卡读写权限,否则富媒体不能正常展示。
◆ 资源
- Layout:
◼ bpush_download_progress.xml ◼ bpush_media_list_item.xml
◼ bpush_media_list.xml
- drawable:
◼ bpush_list_item_bg.9.png ◼ bpush_return_btn.png
◼ bpush_top_bg.9.png
.AndroidManifest.xml声明权限
9. 请确保 AndroidManifest.xml 中声明了必须的组件以及组件的属性,否则 Push 服务部分功能 可能无法正常工作。
.客户端程序需要自己实现一个 Receiver 来接收 Push 消息、接口调用回调以及通知点击事件,也 就是上文提到的 AndrodManifest.xml 中注册的 receiver ,该 Receiver 需要继承 PushMessageReceiver,示例如下:
/*
* 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) {
// 绑定成功
}
// 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;
Log.d(TAG, messageString);
// 自定义内容获取方式,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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// Demo更新界面展示代码,应用请在这里加入自己的处理逻辑
updateContent(context, messageString);
}
/**
* 接收通知点击的函数。
*
* @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);
// 自定义内容获取方式,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) {
// TODO Auto-generated catch block
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) {
// TODO Auto-generated catch block
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 sucessTags, List 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 sucessTags, List 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 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) {
// 解绑定成功
}
// Demo更新界面展示代码,应用请在这里加入自己的处理逻辑
updateContent(context, responseString);
}
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;
Intent intent = new Intent();
intent.setClass(context.getApplicationContext(), MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.getApplicationContext().startActivity(intent);
}
}
.到这里就已经差不多了,其实百度云推送的集成并没有和其他推送有什么区别很难
.然后就是百度云推送的初始化,官方文档建议初始化放在主Activity不要放在Application里面进行初始化
PushManager.startWork(this, PushConstants.LOGIN_TYPE_API_KEY,"你的api_key");
.ok运行走一波,so easy,当你以为已经结束的时候其实只是刚开始,经过测试,不行!!!!!,接收不到消息。
有的测试机可以收到有的测试机收不到,想啊想,不知道错在哪,然后开始怀疑是不是包冲突了?然后各种方法排除测试等等,没得到任何结论!!
.然后各种百度,但是关于百度云推送的文章实在太少了,偶然间看到大神们的文章:
https://blog.csdn.net/kinglong68/article/details/53507086
https://blog.csdn.net/cdkd123/article/details/50521924
.在build.gradle里要配置下,位置在build.gradle -> android下和compileSdkVersion平级目录:
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
.而不是
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
我试了试,去掉这句话也可以。
注意,项目中本来配置着
在官网,建议使用Android Studio工具开发者,将.so文件放入jniLibs目录下,奶奶的,为啥不说清楚,gradle中也需要配置!!!
就这样,问题解决了。
.如果想设置响应铃声的问题,这个我没有试,具体可以参考大佬的文章(文末):
https://blog.csdn.net/kinglong68/article/details/53507086
.至此测试,不仅仅是OK,简直nice,都可以推送,内心还有一点小开心外带一点小兴奋
如果这样的话你就等着吃苦瓜吧,因为问题并没有完全解决,你再试试Android 8.0简直是灾难,因为Android在Android O之后取消了设置channelid你发的推送在Android 8.0上根本就没有任何消息可以收到,没办法问度娘吧,然后陷入了死循环,日后的两天在百度 + 百度中度过,找了无数种方法还是不行,看看官方的公众号和QQ群看下吧,发现竟然被注销了,没错你找不到百度云推送的官方客服人员了,没办法,再去官网看看吧,抱着试一试的心态,选择右上角的SDK下载试试吧(因为之前是二维码下载的)
.我去发现压缩包里多出了好多东西,什么文档了,最新的百度云更新状态说明了等等,这官网也是够无聊的,没办法谁让人牛呢,忍了
.在文档里终于找到了Android 8.0的推送解决办法,这里记给大家
.从 SDK 5.8.0 版本开始,提供关于 Android O(8.x)新特性---通知渠道的设置接口。 若您的应用需要适配 Android O(8.x)系统,且将目标版本 targetSdkVersion 设置为 26 及以上
时,可自定义系统所必需的 channelId 和 channelName 字段,若不指定,SDK 将使用渠道名默 认值"Push"。对于 BasicPushNotificationBuilder,所有的通知消息均使用同一个 channel;对 于 CustomPushNotificationBuilder,可根据自定义的 notification_builder_id 编号,来指定 不同 channel。调用方法示例如下:
设置过的 channel 都会显示在系统的应用通知列表中,您可以根据需要调用 Android O 系统 API 删除 SDK 默认的 channelId(“com.baidu.android.pushservice.push”)或自定义的 channelId。 调用方法示例如下:
这里就不说没用的了,直接把解决问题的所有代码贴出来(我是写在了初始化的后面):
//初始化百度云推送,第三个参数为自己百度推送申请的appkey
PushManager.startWork(this,PushConstants.LOGIN_TYPE_API_KEY,"你的api_key");
//与下方代码中 PushManager.setNotificationBuilder(this, 1, cBuilder)中的第二个参数对应
CustomPushNotificationBuilder cBuilder = new CustomPushNotificationBuilder( R.layout.notification_custom_builder, R.id.notification_icon, R.id.notification_title, R.id.notification_text);
cBuilder.setNotificationFlags(Notification.FLAG_AUTO_CANCEL);
cBuilder.setNotificationDefaults(Notification.DEFAULT_VIBRATE);
cBuilder.setStatusbarIcon(this.getApplicationInfo().icon);
cBuilder.setLayoutDrawable(this.getApplicationInfo().icon);
cBuilder.setNotificationSound(Uri.withAppendedPath( MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "6").toString());
// 若您的应用需要适配Android O(8.x)系统,且将目标版本targetSdkVersion设置为26及以上时:
// 可自定义channelId/channelName, 若不设置则使用默认值"Push";
// 注:非targetSdkVersion 26的应用无需以下2行调用且不会生效
cBuilder.setChannelId("Push");
cBuilder.setChannelName("Push");
// 推送高级设置,通知栏样式设置为下面的ID,ID应与server下发字段notification_builder_id值保持一致
PushManager.setNotificationBuilder(this, 1, cBuilder);
.如果你直接将notification_custom_builder.xml这个布局拷贝进去了,应该就没有多少需要修改的地方了,
.混淆打包说明
如果开发者需要混淆自己的 APK,请在混淆文件(一般默认为 Android 工程下 proguard-project.txt 或者 proguard.cfg)中添加如下说明(VERSION 为版本名称,pushservice-VERSION.jar 为集成的 jar 包 名字):
-libraryjars libs/pushservice-VERSION.jar
-dontwarn com.baidu.**
-keep class com.baidu.**{*; }
.API 说明
本 SDK 中有四个重要的开放类,分别为:PushManager、PushSettings、BasicPushNotificationBuilder 和 CustomPushNotificationBuilder,还有常量类 PushConstants。
到这里算是已经解决了Android 8.0的推送问题了,希望大家可以快快乐乐的工作,本来不想发文章的,但是网上却是没有解决百度云推送Android 8.0问题的文章所以就啰嗦了一下,新手勿喷谢谢,希望解决您的问题,告辞!!!