美文网首页
极光推送接入

极光推送接入

作者: 晨畿茨 | 来源:发表于2018-12-06 11:35 被阅读0次

    极光推送调研

    • 极光接入
    • 主要功能使用
    • 总结

    极光接入

    • 申请极光AppKey
    • 极光接入步骤/引入jar包

    申请极光AppKey

    进入极光官网,==申请开发者账号==,创建应用。并保存 ==AppKey==

    AppKey:89326387481e57aa2cd576cb
    

    极光接入步骤/引入jar包

    添加项目配置依赖

    在project中添加 ==jcenter== 库(Android Studio创建项目时候已经自动生成)

    allprojects {
        repositories {
            jcenter()
        }
    }
    repositories {
        jcenter()
    }
    

    在app的build.gradle中添加相关配置

     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 : "你的 Appkey ", //JPush 上注册的包名对应的 Appkey.
                JPUSH_CHANNEL : "developer-default", //暂时填写默认值即可.
            ]
    

    添加极光推送SDK依赖,

    implementation 'cn.jiguang.sdk:jpush:3.1.6'  // 此处以JPush 3.1.6 版本为例。
    implementation 'cn.jiguang.sdk:jcore:1.2.5'  // 此处以JCore 1.2.5 版本为例。
    

    Manifests.xml中添加权限

     <!-- Required -->
        <permission
            android:name="com.jpushtest.click.jpushtest.permission.JPUSH_MESSAGE"
            android:protectionLevel="signature" />
      
        <!-- Required  一些系统要求的权限,如访问网络等-->
        <uses-permission android:name="com.jpushtest.click.jpushtest.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.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.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.VIBRATE" />
        <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" />
        
    

    ==注:== 使用极光推送还需要在Manifests.xml配置文件中添加相关的service、receiver等.此处先不配置,后续使用到再进行配置

    目前极光的相关接入已经完成,下边进行使用.

    主要功能的使用

    • 初始化
    • 自定义的通知栏
    • 通知
    • 自定义消息

    初始化

    ==Application==中添加JPush的初始化

    JPushInterface.setDebugMode(true)
    JPushInterface.init(application)
    

    <font color = red>注:setDebugMode方法要在init之前

    还需要在manifests.xml 配置文件配置相关的service、reciver.根据官方demo中要求的如下:

     <!-- 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.jpushtest.click.jpushtest" />
                </intent-filter>
            </activity>
    
            <!-- Required SDK 核心功能-->
            <!-- 可配置android:process参数将PushService放在其他进程中 -->
            <service
                android:name="cn.jpush.android.service.PushService"
                android:process=":pushcore"
                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.jpushtest.click.jpushtest.DataProvider"
                android:name="cn.jpush.android.service.DataProvider"
                android:process=":pushcore"
                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.jpushtest.click.jpushtest" />
                </intent-filter>
    
            </service>
            <!-- since 3.1.0 Required SDK 核心功能-->
            <provider
                android:authorities="com.jpushtest.click.jpushtest.DownloadProvider"
                android:name="cn.jpush.android.service.DownloadProvider"
                android:exported="true"
            />
            <!-- Required SDK核心功能-->
            <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.jpushtest.click.jpushtest" />
                </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"/>
            
              <!-- Required  . Enable it you can get statistics data with channel -->
            <meta-data android:name="JPUSH_CHANNEL" android:value="developer-default"/>
            <meta-data android:name="JPUSH_APPKEY" android:value="89326387481e57aa2cd576cb" /> <!--  </>值来自开发者平台取得的AppKey-->
    
    

    我们在接受通知、自定义的消息时候也要添加自定义的receiver,通过拦截不同的 ==action== 实现消息的接收

    
            <!-- User defined.  For test only  用户自定义的广播接收器-->
            <receiver
                android:name="com.example.jpushdemo.MyReceiver"
                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 -->
                    <category android:name="com.jpushtest.click.jpushtest" />
                </intent-filter>
            </receiver>
    
            <!-- User defined.  For test only  用户自定义接收消息器,3.0.7开始支持,目前新tag/alias接口设置结果会在该广播接收器对应的方法中回调-->
            <receiver android:name="com.example.jpushdemo.MyJPushMessageReceiver">
                <intent-filter>
                    <action android:name="cn.jpush.android.intent.RECEIVE_MESSAGE" />
                    <category android:name="com.jpushtest.click.jpushtest"></category>
                </intent-filter>
            </receiver>
    

    MyReceiver.java

    接收JPush发送的广播,并做逻辑处理

    public class MyReceiver extends BroadcastReceiver {
        private static final String TAG = "JIGUANG-Example";
    
        @Override
        public void onReceive(Context context, Intent intent) {
            try {
                Bundle bundle = intent.getExtras();
                Logger.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);
                    Logger.d(TAG, "[MyReceiver] 接收Registration Id : " + regId);
                    //send the Registration Id to your server...
    
                } else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {
                    Logger.d(TAG, "[MyReceiver] 接收到推送下来的自定义消息: " + bundle.getString(JPushInterface.EXTRA_MESSAGE));
                    processCustomMessage(context, bundle);
    
                } else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {
                    Logger.d(TAG, "[MyReceiver] 接收到推送下来的通知");
                    int notifactionId = bundle.getInt(JPushInterface.EXTRA_NOTIFICATION_ID);
                    Logger.d(TAG, "[MyReceiver] 接收到推送下来的通知的ID: " + notifactionId);
    
                } else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {
                    Logger.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())) {
                    Logger.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);
                    Logger.w(TAG, "[MyReceiver]" + intent.getAction() +" connected state change to "+connected);
                } else {
                    Logger.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))) {
                        Logger.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) {
                        Logger.e(TAG, "Get message extra JSON error!");
                    }
    
                } else {
                    sb.append("\nkey:" + key + ", value:" + bundle.get(key));
                }
            }
            return sb.toString();
        }
        
        //send msg to MainActivity
        private void processCustomMessage(Context context, Bundle bundle) {
            if (MainActivity.isForeground) {
                String message = bundle.getString(JPushInterface.EXTRA_MESSAGE);
                String extras = bundle.getString(JPushInterface.EXTRA_EXTRA);
                Intent msgIntent = new Intent(MainActivity.MESSAGE_RECEIVED_ACTION);
                msgIntent.putExtra(MainActivity.KEY_MESSAGE, message);
                if (!ExampleUtil.isEmpty(extras)) {
                    try {
                        JSONObject extraJson = new JSONObject(extras);
                        if (extraJson.length() > 0) {
                            msgIntent.putExtra(MainActivity.KEY_EXTRAS, extras);
                        }
                    } catch (JSONException e) {
    
                    }
    
                }
                LocalBroadcastManager.getInstance(context).sendBroadcast(msgIntent);
            }
        }
    }
    

    MyJPushMessageReceiver.java

    自定义JPush message 接收器,包括操作tag/alias的结果返回(仅仅包含tag/alias新接口部分)

    
    /**
     * 自定义JPush message 接收器,包括操作tag/alias的结果返回(仅仅包含tag/alias新接口部分)
     * */
    public class MyJPushMessageReceiver extends JPushMessageReceiver {
    
        @Override
        public void onTagOperatorResult(Context context,JPushMessage jPushMessage) {
            TagAliasOperatorHelper.getInstance().onTagOperatorResult(context,jPushMessage);
            super.onTagOperatorResult(context, jPushMessage);
        }
        @Override
        public void onCheckTagOperatorResult(Context context,JPushMessage jPushMessage){
            TagAliasOperatorHelper.getInstance().onCheckTagOperatorResult(context,jPushMessage);
            super.onCheckTagOperatorResult(context, jPushMessage);
        }
        @Override
        public void onAliasOperatorResult(Context context, JPushMessage jPushMessage) {
            TagAliasOperatorHelper.getInstance().onAliasOperatorResult(context,jPushMessage);
            super.onAliasOperatorResult(context, jPushMessage);
        }
    
        @Override
        public void onMobileNumberOperatorResult(Context context, JPushMessage jPushMessage) {
            TagAliasOperatorHelper.getInstance().onMobileNumberOperatorResult(context,jPushMessage);
            super.onMobileNumberOperatorResult(context, jPushMessage);
        }
    }
    
    

    完成初始化之后,运行项目,根据log判断JPush是否启动

    [MyReceiver] onReceive - cn.jpush.android.intent.CONNECTION, extras: 
        key:cn.jpush.android.APPKEY, value:89326387481e57aa2cd576cb
        key:cn.jpush.android.CONNECTION_CHANGE, value:true
    

    自定义的通知栏

    JPush允许用户自定义通知栏的样式,并给样式进行编号(不同的场景使用不同的编号)

    在完成JPush的init之后,使用 ==JPushInterface.setPushNotificationBuilder(2, builder1);== 初始化不同编号的通知栏样式 自定义不同的样式。

     BasicPushNotificationBuilder builder = new BasicPushNotificationBuilder(this);
            builder.statusBarDrawable = R.drawable.ic_launcher;
            builder.notificationFlags = Notification.FLAG_AUTO_CANCEL
                    | Notification.FLAG_SHOW_LIGHTS;  //设置为自动消失和呼吸灯闪烁
            builder.notificationDefaults = Notification.DEFAULT_SOUND
                    | Notification.DEFAULT_VIBRATE
                    | Notification.DEFAULT_LIGHTS;  // 设置为铃声、震动、呼吸灯闪烁都要
            JPushInterface.setPushNotificationBuilder(1, builder);
            MultiActionsNotificationBuilder builder1 = new MultiActionsNotificationBuilder(this);
    //添加按钮,参数(按钮图片、按钮文字、扩展数据)
            builder1.addJPushAction(R.drawable.jpush_ic_richpush_actionbar_back, "first", "my_extra1");
            builder1.addJPushAction(R.drawable.jpush_ic_richpush_actionbar_back, "second", "my_extra2");
            builder1.addJPushAction(R.drawable.jpush_ic_richpush_actionbar_back, "third", "my_extra3");
            JPushInterface.setPushNotificationBuilder(2, builder1);
    
    
            CustomPushNotificationBuilder builder3 = new
                    CustomPushNotificationBuilder(this,
                    R.layout.customer_notitfication_layout,
                    R.id.icon,
                    R.id.title,
                    R.id.text);
            // 指定定制的 Notification Layout
            builder3.statusBarDrawable = R.drawable.jpush_notification_icon;
            // 指定最顶层状态栏小图标
            builder3.layoutIconDrawable = R.drawable.ic_launcher;
            // 指定下拉状态栏时显示的通知图标
            JPushInterface.setPushNotificationBuilder(3, builder3);
    

    JPush 控制台根据场景输入不同的数据

    QQ截图20181015180120.png

    通知

    在控制台中点击通知->编辑通知->选择平台->点击发送


    QQ截图20181015174842.png

    发送成功之后即可看到在手机上已经接收到相关的推送通知.

    也可在控制台中看到相关信息的输出。

    [MyReceiver] onReceive - cn.jpush.android.intent.NOTIFICATION_RECEIVED, extras: 
        key:cn.jpush.android.ALERT, value:请问
        key:cn.jpush.android.NOTIFICATION_ID, value:1621204763
        key:cn.jpush.android.ALERT_TYPE, value:7
        key:cn.jpush.android.NOTIFICATION_CONTENT_TITLE, value:JPush SDK Demo
        key:cn.jpush.android.MSG_ID, value:1621204763
    

    为了满足更多场景的客户需求,极光退出 ==标签== 、==别名== 功能,使用该功能需要在JPush初始化init之后的任意位置为当前用户增删改查标签、别名

    switch (tagAliasBean.action) {
                    case ACTION_ADD:
                        JPushInterface.addTags(context, sequence, tagAliasBean.tags);
                        break;
                    case ACTION_SET:
                        JPushInterface.setTags(context, sequence, tagAliasBean.tags);
                        break;
                    case ACTION_DELETE:
                        JPushInterface.deleteTags(context, sequence, tagAliasBean.tags);
                        break;
                    case ACTION_CHECK:
                        //一次只能check一个tag
                        String tag = (String)tagAliasBean.tags.toArray()[0];
                        JPushInterface.checkTagBindState(context,sequence,tag);
                        break;
                    case ACTION_GET:
                        JPushInterface.getAllTags(context, sequence);
                        break;
                    case ACTION_CLEAN:
                        JPushInterface.cleanTags(context, sequence);
                        break;
                    default:
                        Logger.w(TAG,"unsupport tag action type");
                        return;
                }
                
                // 别名
                  switch (tagAliasBean.action){
                    case ACTION_GET:
                        JPushInterface.getAlias(context,sequence);
                        break;
                    case ACTION_DELETE:
                        JPushInterface.deleteAlias(context,sequence);
                        break;
                    case ACTION_SET:
                        JPushInterface.setAlias(context,sequence,tagAliasBean.alias);
                        break;
                    default:
                        Logger.w(TAG,"unsupport alias action type");
                        return;
                }
    

    添加完相关的别名、标签之后就可以在后台自定义批量的发送通知。

    自定义的消息

    自定义消息与通知的区别:

    <font color = green>自定义消息用户是无感的。</font>
    JPush只负责接收到消息并将消息广播出去。不会在通知栏显示notification。开发者可以在控制台看到App接收到的相关消息。

    发送自定义通知的步骤:


    QQ截图20181015174306.png

    接收自定义消息时候在 ==MyMyReceiver.java== 的 ==onReceive== 方法中拦截 ==JPushInterface.ACTION_MESSAGE_RECEIVED== 的action从Intent中接收到相关数据。根据需求自定义通知栏的显示,以及后续的逻辑操作。

    总结

    JPush采用长连接发送数据,内部SDK完成数据接收到以后的数据协议解析,并在APP中创建Notification。

    邮件连接xpg@alphathink.org

    相关文章

      网友评论

          本文标题:极光推送接入

          本文链接:https://www.haomeiwen.com/subject/vmwncqtx.html