Java & Android | JPush集成

此篇文章主要记录一下极光推送的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****" /> 
1.png

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();
    }
}

下面可以运行看下效果了

  • 由极光开发者后台推送一个消息


    2.png
  • 手机接收到的消息


    3.png
  • 控制台打印的log


    4.png

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}
  • 手机收到的推送


    5.png

结束语

简单的集成就到此结束了.今天下载了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的形式推送的

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,568评论 25 707
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 12,473评论 2 59
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • 我是日记星球212号星宝宝万儿,我在参加日记星球第七期21天蜕变之旅的复训,这是我在日记星球写的第108篇原创日记...
    万儿阅读 182评论 0 3
  • 以前家里养过一只狗,因为乖顺通人性所以取名叫布丁。 后来狗狗离家出走了,可能是因为外面的世界太精彩,也有可能被某流...
    灵动美食阅读 158评论 0 0