- 注册
- 创建应用
- 生成AppKey 、Master Secret
文章只介绍Android Studio Jcenter 自动集成
支持jcenter
buildscript {
repositories {
jcenter()
}
......
}
allprojets {
repositories {
jcenter()
}
}
配置gradle
因为项目本身自定义config.gradle ,所以都用rootProject.exty引用,和实际一样
android {
...
defaultConfig {
applicationId rootProject.ext.android["applicationId"]
ndk {
abiFilters 'armeabi'
}
}
...
buildTypes {
debug {
manifestPlaceholders = [
JPUSH_PKGNAME: rootProject.ext.android["applicationId"],
JPUSH_APPKEY : rootProject.ext.jpush["debugAppKey"],
JPUSH_CHANNEL: rootProject.ext.jpush["channel"]]
}
release {
manifestPlaceholders = [
JPUSH_PKGNAME: rootProject.ext.android["applicationId"],
JPUSH_APPKEY : rootProject.ext.jpush["releaseAppKey"],
JPUSH_CHANNEL: rootProject.ext.jpush["channel"]]
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
config.gradle代码
jpush = [
//JPush上注册的包名对应的appkey
debugAppKey : "",
releaseAppKey: "",
//暂时填写默认值即可
channel : "developer-default"
]
配置AndroidManifest
注意:在AndroidManifest中使用 ${applicationId} 引用gradle中定义的包名
这里分三块展示给大家
- 权限相关 @Required必填
<!-- Required -->
<permission
android:name="${applicationId}.permission.JPUSH_MESSAGE"
android:protectionLevel="signature" />
<!-- Required -->
<uses-permission android:name="${applicationId}.permission.JPUSH_MESSAGE" />
<!-- Required -->
<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 -->
<!-- 用于开启 debug 版本的应用在6.0 系统上 层叠窗口权限 -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<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" />
- 核心功能 @Required必填
<application
...
<!-- 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:name="cn.jpush.android.service.DataProvider"
android:authorities="${applicationId}.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="${applicationId}" />
</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="${applicationId}" />
</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:exported="false"
android:theme="@android:style/Theme.NoTitleBar">
<intent-filter>
<action android:name="cn.jpush.android.ui.PushActivity" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="${applicationId}" />
</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="${applicationId}" />
</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" />
</application>
- 自定义广播接收器 @必填
<!-- User defined. For test only 用户自定义的广播接收器-->
<receiver
android:name=".jpush.JPushReceiver"
android:enabled="true"
android:exported="false">
<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="${applicationId}" />
</intent-filter>
</receiver>
/**
* 自定义接收器
* 如果不定义这个 Receiver,则:
* 1) 默认用户会打开主界面
* 2) 接收不到自定义消息
*/
public class JPushReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
if (intent == null) {
return;
}
String extraData = intent.getExtras().getString(JPushInterface.EXTRA_EXTRA);
if (StringUtil.isEmpty(extraData)) {
return;
}
PushEntity pushEntity = new Gson().fromJson(extraData, PushEntity.class);
//推送消息 收到
if(false && JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())){
}
//推送消息 点击
if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {
}
}
}
一行代码
/**
* 极光推送
*/
private void initPush() {
// 设置开启日志,发布时请关闭日志
JPushInterface.setDebugMode(BuildConfig.LOG_DEBUG);
// 初始化 JPush
JPushInterface.init(this);
}
jianshu_0032.png好了,到这里,我们就集成完了,去官网发送一条通知,测试一波
调试指南
- SDK启动过程
- 检查AndroidManifest.xml中是否有配置AppKey,如果没有,则启动失败
- 检查 Androidmanifest.xml文件配置的正确性,必须要保证“Android SDK 集成指南”中所有标注“
- Required的部分都正确配置,否则启动失败
- 检查 JPush SDK库文件的有效性,如果库文件无效,则启动失败
- 检查网络是否可用,如果网络可用则连接服务器登录,否则启动失败
- 登陆成功后可以从log中看到如下log
- 网络问题
- 关闭代理
- 网络不稳定
- 部分系统的特殊处理
详情请查看极光推送官方文档
测试指南
之前我们有定义两个AppKey,为什么要有两个AppKey呢?
最开始我们只有一个AppKey,然后App上线后,需要测试推送,这时,发送的话,线上的用户都会收到推送消息,如果只针对用户推的话,难免测试服与线上服ID一致,还是会有少部分用户收到推送,然后与极光团队邮件沟通,解决方案就是重新注册账号,新建应用,得到测试AppKey,用来只做测试。这样线上和测试就分两条通道走了。
buildTypes {
debug {
manifestPlaceholders = [
JPUSH_APPKEY : rootProject.ext.jpush["debugAppKey"],
}
release {
manifestPlaceholders = [
JPUSH_APPKEY : rootProject.ext.jpush["releaseAppKey"],
}
}
gradle小技巧
jianshu_0033.png jianshu_0034.png这里需要gradle设置一下签名即可,使用简单
感叹gradle的强大,如果想深入了解的同学,请移步
Gradle入门(一)
高级API
应项目需求,采用设置别名的方式,这里也只介绍setAlias
- 注册 & 登录 成功后,设置uid为别名,下次进来不用重复设置别名,所以最好记录一个状态值
@Override
public void initPush() {
if (UserCache.getInstance().getJPushStatus()) {
return;
}
mHandler.sendMessage(mHandler.obtainMessage(MSG_SET_ALIAS, localUid));
}
- 接收消息,设置别名
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case MSG_SET_ALIAS:
JPushInterface.setAlias(MainActivity.this, (String) msg.obj, mAliasCallback);
break;
}
}
};
- 设置别名的回调
private final TagAliasCallback mAliasCallback = new TagAliasCallback() {
@Override
public void gotResult(int code, String alias, Set<String> tags) {
switch (code) {
case 0:
//设置成功,存储状态值
UserCache.getInstance().saveJPushSuccess();
break;
case 6002:
//失败,重复设置
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SET_ALIAS, alias), 1000 * 60);
break;
default:
break;
}
}
};
- 退出登录,删除别名
@Override
public void loginOut() {
// JPushInterface.deleteAlias(,); 也可以
JPushInterface.setAlias(AppSettingActivity.this, "", null);
exitActivity();
}
其它
关于拉起
- 不是所有使用了极光服务的App都愿意开启拉起功能 来拉起别的应用或者被别的应用拉起
- 拉起同样会受到系统的限制,该功能只是尽量提高点重启的几率,相当于有比没有好
- 测试拉起的具体步骤方法
- 成功设置了拉起也不是说马上你杀死,推送测试他就能收到的,你要等他拉起成功
注意
互相拉起服务,使用的后果一定要考虑清楚
使用了互相拉起服务,确实,你们APP推送的及时到达率都提升了很多,但是,APP开启的一段时间里,手机会卡顿,因为会唤醒,同样注册了极光推送互相拉起服务的应用,手机里面有2-3个还好,用户还发现不了什么,如果手机里面有100,200,300个应用,那最少唤醒10- 30个,开启的一段时间,手机绝对会卡顿,所以为什么会有垃圾联盟了,为什么手机越用越卡。
当然也看你们产品定位,毕竟手机里面装100,200,300个应用的用户占少数,牺牲少部分用户,博得大部分群体也可以,看实际需求。
最后呢,我们的产品最开始开启互相拉起服务,一段时间我又删除了,就是关闭互相拉起服务,正常情况,APP不该唤醒其它应用,也不会被其它应用唤醒,结果,删除了,还是没法解决互相唤醒,现在就是想关关不掉!!!和极光服务沟通过,让我们多测试一下,现在也没时间测试,暂时记一个Bug,也有可能不是极光服务的问题。总之,慎重!
后记
上线后怎么测试推送和广播?
事情起因,测试人员不小心推送、广播全部人,结果,线上的用户都收到了 test 这样的信息,无法点击查看。其实,我也经常会收到新浪推送的test信息,真的非常影响用户体验。
iOS为什么不会出现这样的问题呢?
他们在设置时,已经有生产环境和开发环境,配置不同的签名,结合后端的业务,来推生产环境,还是开发环境,这样线上的用户就不会收到测试人员的推送
android怎么解决呢?
- 重新注册极光账号
- 设置包名,生成AppKey 、Master Secret
- 告诉后台,这个属于开发测试的通道
网友评论