添加工程配置
Project 根目录的主 gradle 配置
确认 Android Studio 的 Project 根目录的主 gradle 中配置了 mavenCentral 支持(新建 Project 默认配置就支持),配置华为和 FCM Maven 代码库,可根据华为和 FCM 发布的版本更新选择最新版本:
buildscript {
repositories {
google()
mavenCentral()
// hms, 若不集成华为厂商通道,可直接跳过
maven { url 'http://developer.huawei.com/repo/'}
// fcm, 若不集成 FCM 通道,可直接跳过
maven { url "https://maven.google.com" }
}
dependencies {
// fcm,若不集成 FCM 通道,可直接跳过
classpath 'com.google.gms:google-services:4.3.8'
// hms,若不集成华为厂商通道,可直接跳过
classpath 'com.huawei.agconnect:agcp:1.6.0.300'
}
}
allprojects {
repositories {
google()
mavenCentral()
//hms,若不集成华为厂商通道,可直接跳过
maven {url 'http://developer.huawei.com/repo/'}
//fcm,若不集成 FCM 通道,可直接跳过
maven { url "https://maven.google.com" }
}
}
Module 的 gradle 配置
在 Module 的 gradle 中添加依赖和 AndroidManifest 的替换变量,集成极光推送 SDK 和厂商通道 SDK,其中厂商组合选择所需的通道即可。
android {
......
defaultConfig {
applicationId "com.xxx.xxx" //JPush 上注册的包名.
......
ndk {
//选择要添加的对应 cpu 类型的 .so 库。
abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a'
// 还可以添加 'x86', 'x86_64', 'mips', 'mips64'
}
manifestPlaceholders = [
JPUSH_PKGNAME : applicationId,
//JPush 上注册的包名对应的 Appkey.
JPUSH_APPKEY : "你的 Appkey ",
//暂时填写默认值即可.
JPUSH_CHANNEL : "developer-default",
//若不集成厂商通道,可直接跳过以下配置
MEIZU_APPKEY : "MZ-魅族的APPKEY",
MEIZU_APPID : "MZ-魅族的APPID",
XIAOMI_APPID : "MI-小米的APPID",
XIAOMI_APPKEY : "MI-小米的APPKEY",
OPPO_APPKEY : "OP-oppo的APPKEY",
OPPO_APPID : "OP-oppo的APPID",
OPPO_APPSECRET : "OP-oppo的APPSECRET",
VIVO_APPKEY : "vivo的APPKEY",
VIVO_APPID : "vivo的APPID"
]
......
}
repositories {
flatDir {
dirs 'libs'
}
}
......
}
dependencies {
......
// 此处以JCore 3.2.2 版本为例。
implementation 'cn.jiguang.sdk:jcore:3.2.2'
// 此处以JPush 4.6.2 版本为例
implementation 'cn.jiguang.sdk:jpush:4.6.2'
//若不集成厂商通道,可直接跳过以下依赖
// 接入华为厂商
implementation 'com.huawei.hms:push:6.1.0.300'
// 极光厂商插件版本与接入 JPush 版本保持一致,下同
implementation 'cn.jiguang.sdk.plugin:huawei:4.6.2'
// 接入 FCM 厂商
implementation 'com.google.firebase:firebase-messaging:23.0.0'
implementation 'cn.jiguang.sdk.plugin:fcm:4.6.2'
// 接入魅族厂商
implementation 'cn.jiguang.sdk.plugin:meizu:4.6.2'
// 接入 VIVO 厂商
implementation 'cn.jiguang.sdk.plugin:vivo:4.6.2'
// 接入小米厂商
implementation 'cn.jiguang.sdk.plugin:xiaomi:4.6.2'
// 接入 OPPO 厂商
implementation 'cn.jiguang.sdk.plugin:oppo:4.6.2'
// oppo 厂商 aar 需要单独引入,请将 jiguang/libs 下 com.heytap.msp-push-x.x.x.aar 单独拷贝一份到应用 module/libs 下
implementation(name: 'com.heytap.msp-push-3.0.0', ext: 'aar')
//以下为 OPPO 3.0.0 aar需要依赖
implementation 'com.google.code.gson:gson:2.6.2'
implementation 'commons-codec:commons-codec:1.6'
implementation 'androidx.annotation:annotation:1.1.0'
......
}
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.huawei.agconnect'
应用 Module 配置
如果选择的厂商通道包含了 Huawei 厂商通道和 FCM 厂商通道,则需要额外执行以下操作,若未选择可忽略本步骤。
FCM:在 Firebase 上创建和 JPush 上同包名的待发布应用,创建完成后下载该应用的 google-services.json 配置文件并添加到应用的 module 目录下。
Huawei:在 Huawei 上创建和 JPush 上同包名的待发布应用,创建完成后下载该应用的 agconnect-services.json 配置文件并添加到应用的 module 目录下如图项目位置。
配置推送必须组件
在 AndroidManifest 中配置一个 Service,以在更多手机平台上获得更稳定的支持,示例如下:
从 JPush 3.0.7 开始,需要配置继承 JPushMessageReceiver 的广播,原来如果配了 MyReceiver 现在可以弃用,示例如下
初始化推送服务
Push SDK 提供的 API 接口,都主要集中在cn.jpush.android.api.JPushInterface类里。
public class ExampleApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
JPushInterface.setDebugMode(true);
JPushInterface.init(this);
}
}
在你的主页面绑定别名
int type = JPushInterface.isNotificationEnabled(this);
if (type == 0) {
JPushInterface.goToAppNotificationSettings(this);
} else if (type == 1){
String str = SPUtils.getString(getApplicationContext(), "systemFlag", "") + "_" + SPUtils.getString(getApplicationContext(), "userId", "");
JPushInterface.setAlias(getApplicationContext(), 1, str);
JPushInterface.getAlias(this, 1);
// JPushInterface.setLatestNotificationNumber(this, 9999);设计显示最多的角标数量 不设置华为最多就是99+
LogUtils.e("getRegistrationID=" + JPushInterface.getRegistrationID(this));
}else {
ToastUtils.showToast("表示检测失败");
}
退出的时候记得清空你别名
JPushInterface.deleteAlias(baseApplication.instance, EnumPush.DELETE.getDataId());
我在闪屏页面的时候这样做的防止退出了以后没有清除干净
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
JPushInterface.deleteAlias(baseApplication.instance, EnumPush.DELETE.getDataId());
}
},10000);
我当时也不太清楚初始化到底是应该写着哪里经过同事的点播才开悟,在你的AndroidManifest一定配置了这个全局的一个baseApplication 初始化写在哪里就ok了
不会以为这样就完事了吧!我们的推送主要分两部分
(a 第一部分就是极光通道来推送的
(b第二部分就是厂商通道来推送的
厂商集成设置
Android
进入【极光控制台】-【消息推送】-【推送设置】-【集成设置】-【Android】页面,可以查看应用包名、SDK 集成度和厂商通道配置信息。
应用包名:Android 应用程序的包名(Package Name),在 AndroidManifest.xml 里配置使用。该包名推送、认证、分享、IM等业务共同使用,一旦指定,不可更改。
集成度:SDK 集成度可以帮助用户了解整体集成情况。
厂商通道配置:使用厂商通道需要在控制台配置厂商参数,详情参考 厂商通道参数申请指南。
此处啰嗦一句:需要去各大开放平台创建自己的项目然后到到App Id、App Socret极光需要的配置每个厂商都不一样,还有Default Title 我填写的是我项目包名字 开启按钮一开你的厂商通道就通了
推送到这里基本就是处理接收数据了
XService
JPushMessageReceiver类奉上这是极光通道的接收方法
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.kcxd.app.MainActivity;
import com.kcxd.app.global.base.baseApplication;
import com.kcxd.app.global.base.baseResponseBean;
import com.kcxd.app.global.base.MessageEvent;
import com.kcxd.app.global.base.SPUtils;
import com.kcxd.app.global.base.UrlUtils;
import com.kcxd.app.global.base.VeinRouter;
import com.kcxd.app.global.envm.EnumPush;
import com.kcxd.app.global.envm.EnumUtils;
import com.kcxd.app.global.okgo.AppManager;
import com.kcxd.app.global.okgo.LogUtils;
import com.kcxd.app.global.okgo.RequestParams;
import cn.jpush.android.api.CustomMessage;
import cn.jpush.android.api.JPushInterface;
import cn.jpush.android.api.JPushMessage;
import cn.jpush.android.api.NotificationMessage;
import cn.jpush.android.service.JPushMessageReceiver;
public class Receiver extends JPushMessageReceiver {
private static final String TAG = "JIGUANG";
@Override
public void onConnected(Context context, boolean b) {
super.onConnected(context, b);
Log.e(TAG, "onConnected");
}
@Override
public void onRegister(Context context, String s) {
super.onRegister(context, s);
Log.e(TAG, "onRegister" + s);
}
@Override
public void onAliasOperatorResult(Context context, JPushMessage jPushMessage) {
super.onAliasOperatorResult(context, jPushMessage);
int quence = jPushMessage.getSequence();
int errorCode = jPushMessage.getErrorCode();
//极光回调
switch (EnumPush.getByCurId(quence)){
case DELETE:
break;
case ADD:
if (errorCode==6022){
JPushInterface.setAlias(baseApplication.instance, EnumPush.ADD.getDataId(), SPUtils.getString(baseApplication.instance,"alias",""));
}
break;
}
Log.i("bieming", "bieming:" + jPushMessage.getAlias());
}
@Override
public void onNotifyMessageArrived(Context context, NotificationMessage notificationMessage) {
super.onNotifyMessageArrived(context, notificationMessage);
}
@Override
public void onNotifyMessageOpened(Context context, NotificationMessage notificationMessage) {
super.onNotifyMessageOpened(context, notificationMessage);
Log.e(TAG, notificationMessage.notificationExtras + "onNotifyMessageOpened");
String str = notificationMessage.notificationExtras;
// MessageEvent messageEvent = new MessageEvent(str+"");
// EventBus.getDefault().post(messageEvent);
try{
//打开自定义的Activity
Intent i = new Intent(context, MainActivity.class);
Bundle bundle = new Bundle();
bundle.putString(JPushInterface.EXTRA_NOTIFICATION_TITLE,notificationMessage.notificationTitle);
bundle.putString(JPushInterface.EXTRA_alert,notificationMessage.notificationContent);
bundle.putString("data",str);
i.putExtras(bundle);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP );
context.startActivity(i);
}catch (Throwable throwable){
LogUtils.e(throwable.getMessage());
}
}
@Override
public void onMessage(Context context, CustomMessage customMessage) {
super.onMessage(context, customMessage);
Log.e(TAG, "onMessage");
}
@Override
public void onMultiActionClicked(Context context, Intent intent) {
Log.e(TAG, "[onMultiActionClicked] 用户点击了通知栏按钮");
String nActionExtra = intent.getExtras().getString(JPushInterface.EXTRA_NOTIFICATION_ACTION_EXTRA);
//开发者根据不同 Action 携带的 extra 字段来分配不同的动作。
if (nActionExtra == null) {
Log.d(TAG, "ACTION_NOTIFICATION_CLICK_ACTION nActionExtra is null");
return;
}
}
}
还有离线推送的需要后台配合你绑定你项目的的OpenClickActivity
你需要给后台的就是你这个项目的具体位置你别告诉我你不会好吧!我给的是com.kcxd.app.global.push.OpenClickActivity
OpenClickActivity封上
import android.content.Intent;
import android.text.TextUtils;
import android.util.Log;
import com.kcxd.app.MainActivity;
import com.kcxd.app.R;
import com.kcxd.app.global.base.baseActivity;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
import cn.jpush.android.api.JPushInterface;
public class OpenClickActivity extends baseActivity {
private static final String TAG = "OpenClickActivity";
private static final String KEY_MSGID = "msg_id";
private static final String KEY_WHICH_PUSH_SDK = "rom_type";
private static final String KEY_TITLE = "n_title";
private static final String KEY_ConTENT = "n_content";
private static final String KEY_EXTRAS = "n_extras";
Map map = new HashMap();
private void handleOpenClick() {
Log.d(TAG, "用户点击打开了通知");
String data = null;
//获取华为平台附带的jpush信息
if (getIntent().getData() != null) {
data = getIntent().getData().toString();
}
//获取fcm、oppo、vivo、华硕、小米平台附带的jpush信息
if (TextUtils.isEmpty(data) && getIntent().getExtras() != null) {
data = getIntent().getExtras().getString("JMessageExtra");
}
Log.w(TAG, "msg content is " + String.valueOf(data));
if (TextUtils.isEmpty(data)) return;
try {
JSonObject jsonObject = new JSonObject(data);
String msgId = jsonObject.optString(KEY_MSGID);
byte whichPushSDK = (byte) jsonObject.optInt(KEY_WHICH_PUSH_SDK);
String title = jsonObject.optString(KEY_TITLE);
String content = jsonObject.optString(KEY_CONTENT);
String extras = jsonObject.optString(KEY_EXTRAS);
StringBuilder sb = new StringBuilder();
sb.append("msgId:");
sb.append(String.valueOf(msgId));
sb.append("n");
sb.append("title:");
sb.append(String.valueOf(title));
sb.append("n");
sb.append("content:");
sb.append(String.valueOf(content));
sb.append("n");
sb.append("extras:");
sb.append(String.valueOf(extras));
sb.append("n");
sb.append("platform:");
sb.append(getPushSDKName(whichPushSDK));
Log.w(TAG, "msg map is " + String.valueOf(map));
JPushInterface.reportNotificationOpened(this, msgId, whichPushSDK);
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("data",data);
startActivity(intent);
finish();
} catch (JSonException e) {
Log.w(TAG, "parse notification error");
}
}
private String getPushSDKName(byte whichPushSDK) {
String name;
switch (whichPushSDK) {
case 0:
name = "jpush";
break;
case 1:
name = "xiaomi";
break;
case 2:
name = "huawei";
break;
case 3:
name = "meizu";
break;
case 4:
name = "oppo";
break;
case 5:
name = "vivo";
break;
case 6:
name = "asus";
break;
case 8:
name = "fcm";
break;
default:
name = "jpush";
}
return name;
}
@Override
protected int setLayoutId() {
return R.layout.activity_launch;
}
@Override
protected void initView() {
handleOpenClick();
}
@Override
protected void initData() {
}
}
统一处理跳转到处理的精华奉上
String data = null;
//获取fcm、oppo、vivo、华硕、小米平台附带的jpush信息
if (TextUtils.isEmpty(data) && getIntent().getExtras() != null) {
data = getIntent().getExtras().getString("data");
pushBean = JsonUtils.fromJson(data, PushBean.class);
setType();
}
好人做做到底把接收的实体类也给分享出来吧
public class PushBean {
private NExtras n_extras;
private String n_title;
private String n_content;
private long msg_id;
private int show_type;
private int rom_type;
private String _j_data_;
private int farmId ;
private int houseId ;
private String pushTypeSub;
private String farmName;
private int detailsId;
private int type;
private String uuid;
public String getFarmName() {
return farmName;
}
public void setFarmName(String farmName) {
this.farmName = farmName;
}
public int getDetailsId() {
return detailsId;
}
public void setDetailsId(int detailsId) {
this.detailsId = detailsId;
}
public int getHouseId() {
return houseId;
}
public void setHouseId(int houseId) {
this.houseId = houseId;
}
public int getFarmId() {
return farmId;
}
public void setFarmId(int farmId) {
this.farmId = farmId;
}
public String getPushTypeSub() {
return pushTypeSub;
}
public void setPushTypeSub(String pushTypeSub) {
this.pushTypeSub = pushTypeSub;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public NExtras getN_extras() {
return n_extras;
}
public void setN_extras(NExtras n_extras) {
this.n_extras = n_extras;
}
public String getN_title() {
return n_title;
}
public void setN_title(String n_title) {
this.n_title = n_title;
}
public String getN_content() {
return n_content;
}
public void setN_content(String n_content) {
this.n_content = n_content;
}
public long getMsg_id() {
return msg_id;
}
public void setMsg_id(long msg_id) {
this.msg_id = msg_id;
}
public int getShow_type() {
return show_type;
}
public void setShow_type(int show_type) {
this.show_type = show_type;
}
public int getRom_type() {
return rom_type;
}
public void setRom_type(int rom_type) {
this.rom_type = rom_type;
}
public String get_j_data_() {
return _j_data_;
}
public void set_j_data_(String _j_data_) {
this._j_data_ = _j_data_;
}
@NoArgsConstructor
@Data
public static class NExtras {
private int type;
private String uuid;
private int farmId;
private int houseId;
private String pushTypeSub;
private String farmName;
private int detailsId;
public String getFarmName() {
return farmName;
}
public void setFarmName(String farmName) {
this.farmName = farmName;
}
public String getPushTypeSub() {
return pushTypeSub;
}
public void setPushTypeSub(String pushTypeSub) {
this.pushTypeSub = pushTypeSub;
}
public int getDetailsId() {
return detailsId;
}
public void setDetailsId(int detailsId) {
this.detailsId = detailsId;
}
public int getFarmId() {
return farmId;
}
public void setFarmId(int farmId) {
this.farmId = farmId;
}
public int getHouseId() {
return houseId;
}
public void setHouseId(int houseId) {
this.houseId = houseId;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
@Override
public String toString() {
return "NExtras{" +
"type=" + type +
", uuid='" + uuid + ''' +
", farmId=" + farmId +
", houseId=" + houseId +
'}';
}
}
}
问题1
agconnect-services.json 配置文件下载地址
解决方案奉上
这个前提就是要先开通开放平台创建项目
登录华为开放平台->右上角管理中心->上架及推送服务->我的项目->点击创建的项目->点击下载
问题2
这些准备都已经做好了但是杀进程依然某牌手机收不到消息而且非常的顽固、可恶至极
极光官网没人告诉我什么原因,我就主动添加了极光的客服一顿的排查,一顿的猛戳,和 某牌子手机的客服也是奋力周旋啊最后告诉我等着app版本发布成功在试试…
他没骗人:确实app发布成功 api推送可以收到了
杀死进程后不要用极光给的测试平台推送因为收不到,只能通过api
问题3
当时做到这里的时候也是按照代码这么按照文档上写的,但是鸿蒙的手机收到推送收不到而且日志还报错以下这个错误,懵逼的时刻来了刚好那天是周六极光客服也不上班,叫天天不灵了,查阅了古籍也没找到解决的办法之前明明最先搞定华为、鸿蒙的怎么突然这样临近版本发布让我如何自处…此处一万个
问题解决方案
第一如果没有么用到使用极光富媒体功能就不要配置cn.jpush.android.ui.PushActivity
经过和技术客服的猛戳得到了解决,如果你遇到此类问题我希望能在周六日的时候帮上你
当然当然辅助性的工具不能少
推送收不到时,可以进入【极光控制台】-【消息推送】-【配置管理】-【排查工具】-【消息查询】页面进行生命周期排查,输入 Message ID 和 Registration ID,点击查询即可查看消息的生命周期,查询结果如下图:
消息生命周期:如果发送失败,会在相应的失败环节展示错误码+错误提示信息。
特殊消息生命周期:如果消息类型为通知消息+自定义消息,则消息生命周期会产生两条分叉路径。
消息基本信息:展示消息类型、发送策略和消息体,点击消息体可以查看消息体 json。
设备基本信息:展示通知权限开关状态、厂商注册情况、最近在线时间等设备基本信息
杀死进程/极光推送的测试
Oppo手机会持续收到消息 但是展开消息列表后只能看到最新的8条 提示数量比较准确 提示声会持续
华为手机会持续收到消息 提示数量只是24 ,但是只能看到最新8条 提示声会持续
小米手机会持续收到消息 不提示具体未读数量,但是只能看到最新8条 提示声会持续
Vivo手机收到24条后在不接收消息 清除后消息通知列表后会继续收到满24条后停止接收
删一条就会在接一条如果全部删除就会接收24条就停止了
Vivo手机下载了其他app接极光推送的美柚、丁香园、探探、微博 除了探探以为其他杀死进程都接收不到 探探收到24条也会停止接收 只能查看8条数据
经过和客服的沟通得到答案厂商设置有上限每个手机上限不同
角标测试
小米的角标到最多显示9个 内部代码设置角标不起效果
华为的多了来条添加一条 和内部消息记录能统一
Vivo 新消息推送手机角标不自动增加 内部代码设置角标有效
查阅极光文档发现角标设置只支持华为手机
oppo和魅族手机系统上不支持数字角标的功能,只能设置角标圆点。



