此篇文章主要记录一下极光推送的Java后台和Android移动端的相关集成. 因为之前写过android的demo,但是并没有记录.最近新项目中又需要集成java后台的相关开发. 所以记录一下相关内容.
Android平台JPush相关集成
1.manifest文件配置
- 权限
<!-- Required -->
<permission
android:name="com.jpush.test.permission.JPUSH_MESSAGE"
android:protectionLevel="signature" />
<!-- Required 一些系统要求的权限,如访问网络等-->
<uses-permission android:name="com.jpush.test.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.WRITE_SETTINGS" />
<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.ACCESS_WIFI_STATE" />
<!-- Optional for location -->
<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" />
- 自定义推送弹框界面
<!-- Rich push 核心功能 since 2.0.6-->
<activity
android:name="cn.jpush.android.ui.PopWinActivity"
android:theme="@style/MyDialogStyle"
android:exported="false">
</activity>
<!-- 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.jpush.test" />
</intent-filter>
</activity>
- 相关服务
<!-- Required SDK 核心功能-->
<!-- 可配置android:process参数将PushService放在其他进程中 -->
<service
android:name="cn.jpush.android.service.PushService"
android:process=":mult"
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="com.jpush.test.DataProvider"
android:name="cn.jpush.android.service.DataProvider"
android:exported="false" />
<!-- 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.jpush.test" />
</intent-filter>
</service>
<!-- since 3.1.0 Required SDK 核心功能-->
<provider
android:authorities="com.jpush.test.DownloadProvider"
android:name="cn.jpush.android.service.DownloadProvider"
android:exported="true" />
- 广播接收器
<!-- Required SDK核心功能-->
<!-- 新的 tag/alias 接口结果返回需要开发者配置一个自定的广播 -->
<!-- 该广播需要继承 JPush 提供的 JPushMessageReceiver 类, 并如下新增一个 Intent-Filter -->
<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.jpush.test" />
</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"/>
<!-- 用户自定义的广播接收器-->
<receiver
android:name="com.jpush.test.PushTestReceiver"
android:exported="false"
android:enabled="true">
<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 -->
<action android:name="cn.jpush.android.intent.ACTION_RICHPUSH_CALLBACK" />
<action android:name="cn.jpush.android.HTML_PATH" />
<action android:name="cn.jpush.android.HTML_RES" />
<category android:name="com.jpush.test" />
</intent-filter>
</receiver>
- 应用的APP_KEY
这个值是在极光的官网开发者中心自己新建一个android项目后,会提供的.长度为24
<!-- </>值来自开发者平台取得的AppKey-->
<meta-data android:name="JPUSH_APPKEY" android:value="****5ea7e437316fb24d****" />
2.测试代码
/**
* 该Receiver在Manifest中注册过
*/
public class PushTestReceiver extends BroadcastReceiver {
private static final String TAG = "JIGUANG-Receiver";
@Override
public void onReceive(Context context, Intent intent) {
try {
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);
String message = bundle.getString(JPushInterface.EXTRA_MESSAGE);
String title = bundle.getString(JPushInterface.EXTRA_TITLE);
Log.d(TAG, "[MyReceiver] 接收到推送下来的通知的ID: " + notifactionId+", 消息内容为:"+message+ ", 标题为:"+title);
} else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {
Log.d(TAG, "[MyReceiver] 用户点击打开了通知");
// //打开自定义的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())) {
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.d(TAG, "[MyReceiver]" + intent.getAction() +" connected state change to "+connected);
} else if(JPushInterface.EXTRA_RICHPUSH_HTML_PATH.equals(intent.getAction())) {
Log.d(TAG, "[MyReceiver] 下载的HTML的文件路径: "+bundle.getString(JPushInterface.EXTRA_RICHPUSH_HTML_PATH));
}else if(JPushInterface.EXTRA_RICHPUSH_HTML_RES.equals(intent.getAction())) {
String fileStr = bundle.getString(JPushInterface.EXTRA_RICHPUSH_HTML_RES);
String[] fileNames = fileStr.split(",");
Log.d(TAG, "[MyReceiver] 下载的图片资源的文件名: "+fileNames);
}else {
Log.d(TAG, "[MyReceiver] Unhandled intent - " + intent.getAction());
}
} catch (Exception e){
}
}
// 打印所有的 intent extra 数据
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))) {
Log.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) {
Log.e(TAG, "Get message extra JSON error!");
}
} else {
sb.append("\nkey:" + key + ", value:" + bundle.get(key));
}
}
return sb.toString();
}
}
下面可以运行看下效果了
-
由极光开发者后台推送一个消息
-
手机接收到的消息
-
控制台打印的log
Java后台JPush相关集成
1.Maven pom文件配置
这里要说一下, 官方文档提供的配置中并没有jpush-client这个库. 但是我在集成使用时一些包并不能成功导出. (delete后Maven install了很多次还是不成功 ). 随后下载了源码看,根据报错提示信息在pom中添加该库就可以成功导包使用了.
<!-- JPush start -->
<dependency>
<groupId>cn.jpush.api</groupId>
<artifactId>jiguang-common</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>cn.jpush.api</groupId>
<artifactId>jpush-client</artifactId>
<version>3.2.3</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>
<!-- JPush end -->
2.测试代码
public class JPushTest {
protected static final Logger LOG = LoggerFactory.getLogger(JPushTest.class);
//APP_KEY和MASTER_SECRET是极光推送开发者中心创建的应用信息中提供的信息
protected static final String APP_KEY ="*****ea7e437316fb24d****";
protected static final String MASTER_SECRET = "*****ff150b063ebc794****";
public static void main(String[] args) {
testSendPush();
}
public static void testSendPush() {
final JPushClient jpushClient = new JPushClient(MASTER_SECRET, APP_KEY, 0);
final PushPayload payload = buildPushObject_android_and_ios();
try {
PushResult result = jpushClient.sendPush(payload);
LOG.info("Got result - " + result);
System.out.println(result);
// 如果使用 NettyHttpClient,需要手动调用 close 方法退出进程
// If uses NettyHttpClient, call close when finished sending request, otherwise process will not exit.
// jpushClient.close();
} catch (cn.jpush.api.common.resp.APIRequestException e) {
LOG.error("Error response from JPush server. Should review and fix it. ", e);
LOG.info("HTTP Status: " + e.getStatus());
LOG.info("Error Code: " + e.getErrorCode());
LOG.info("Error Message: " + e.getErrorMessage());
LOG.info("Msg ID: " + e.getMsgId());
LOG.error("Sendno: " + payload.getSendno());
} catch (cn.jpush.api.common.resp.APIConnectionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static PushPayload buildPushObject_android_and_ios() {
Map<String, String> extras = new HashMap<String, String>();
extras.put("test", "https://community.jiguang.cn/push");
return PushPayload.newBuilder()
.setPlatform(Platform.android_ios())
.setAudience(Audience.all())
.setNotification(Notification.newBuilder()
.setAlert("我是一个推送消息")
.addPlatformNotification(AndroidNotification.newBuilder()
.setTitle("Good night")
.addExtras(extras).build())
.addPlatformNotification(IosNotification.newBuilder()
.incrBadge(1)
.addExtra("extra_key", "extra_value").build())
.build())
.build();
}
}
- 推送成功后控制台会打印
Got result - {"msg_id":2671605784,"sendno":128182687}
-
手机收到的推送
结束语
简单的集成就到此结束了.今天下载了java端的sdk源码.后续的深度功能挖掘和更灵活实用的功能还需研究一下.再接再厉咯~
Java后台根据别名推送消息
public static PushPayload buildPushObject_all_alias_alert(String alias,String alert) {
return PushPayload.newBuilder()
.setPlatform(Platform.all()) // 推送平台
.setAudience(Audience.alias(alias)) // 推送用户 根据别名区分
.setNotification(Notification.newBuilder()
.addPlatformNotification(AndroidNotification.newBuilder()
.setAlert("这是一个推送")
.build())
.build())//推送内容
.build();
}
Java后台发送json字符串
public static PushPayload buildPushJson_all_alias(PushModel model) {
Gson gson = new Gson();
return PushPayload.newBuilder()
.setPlatform(Platform.android())
.setAudience(Audience.alias(model.alias))
.setNotification(Notification.newBuilder()
.setAlert(model.message)
.addPlatformNotification(AndroidNotification.newBuilder()
.setTitle(model.title)
.addExtra("message", gson.toJson(model)) //将对象转成json后的String
.build())
.build())
.build();
}
发送json的方式有很多种,我这里用了gson的转换,然后以String的形式推送的