美文网首页推送
信鸽推送笔记

信鸽推送笔记

作者: Chenyangqi | 来源:发表于2019-06-27 22:18 被阅读14次

    记录一下这周使用腾讯信鸽推送的吐血过程。总结一下,没事不要用腾讯的产品,按照开发文档一顿操作猛如虎,运行一下各种报错兼容问题,实在是无力吐槽。奈何我司大佬有腾讯血统,使用的都是腾讯系列的产品。

    开发步骤
    • 1:资源导入以及配置
    • 2:账号绑定
    • 3:接收状态栏消息
    • 4:接收应用内消息
    • 5:账号解绑
    • 6:集成华为、小米、魅族厂商通道(周末在写)
    1.资源导入以及配置

    起初我也是按照官方文档,号称10分钟快速集成推送功能,然后各种出错,搞了我一下午一脸懵逼。直接贴出最终正确的配置过程如下:
    先去官网申请一个测试应用如下


    image.png

    把申请的测试应用ACCESS ID和ACCESS KEY填入如下:

    android {
        compileSdkVersion 28
        defaultConfig {
            applicationId "com.***.***"
            minSdkVersion 21
            targetSdkVersion 28
            versionCode 1
            versionName "1.0.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    
            ndk {
                abiFilters 'armeabi', 'armeabi-v7a'
            }
            manifestPlaceholders = [
                    XG_ACCESS_ID : "21*******",
                    XG_ACCESS_KEY: "AX1********",
            ]
        }
    
       
    
    dependencies {
        //信鸽jar
        implementation 'com.tencent.xinge:xinge:3.2.7-Release'
        //jg包
        implementation 'com.tencent.jg:jg:1.1'
        //wup包
        implementation 'com.tencent.wup:wup:1.0.0.E-Release'
        //mid包
        implementation 'com.tencent.mid:mid:4.0.6-release'
    }
    

    manifest配置如下

     <application
            android:name=".MyApplication"
            android:allowBackup="true"
            android:icon="@mipmap/logo"
            android:label="@string/app_name"
            android:networkSecurityConfig="@xml/network_security_config"
            android:roundIcon="@mipmap/logo"
            android:supportsRtl="true"
            android:theme="@style/AppTheme"
            tools:replace="android:name">
    
            ......
    
            <provider
                android:name="android.support.v4.content.FileProvider"
                android:authorities="com.fsxq.createcamp"
                android:exported="false"
                android:grantUriPermissions="true">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/photo_path" />
            </provider>
    
            <activity
                android:name="com.yalantis.ucrop.UCropActivity"
                android:screenOrientation="portrait"
                android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
    
            <receiver
                android:name="com.***.***.xgpush.MessageReceiver"
                android:exported="true">
                <intent-filter>
                    <!-- 接收消息透传 -->
                    <action android:name="com.tencent.android.tpush.action.PUSH_MESSAGE" />
                    <!-- 监听注册、反注册、设置/删除标签、通知被点击等处理结果 -->
                    <action android:name="com.tencent.android.tpush.action.FEEDBACK" />
                </intent-filter>
            </receiver>
        </application>
        <!-- 【必须】 信鸽SDK所需权限   -->
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.READ_PHONE_STATE" />
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.WAKE_LOCK" />
        <uses-permission android:name="android.permission.VIBRATE" />
        <!-- 【常用】 信鸽SDK所需权限 -->
        <uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
        <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.WRITE_SETTINGS" />
        <!-- 【可选】 信鸽SDK所需权限 -->
        <uses-permission android:name="android.permission.RESTART_PACKAGES" />
        <uses-permission android:name="android.permission.BROADCAST_STICKY" />
        <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
        <uses-permission android:name="android.permission.GET_TASKS" />
        <uses-permission android:name="android.permission.READ_LOGS" />
        <uses-permission android:name="android.permission.BLUETOOTH" />
        <uses-permission android:name="android.permission.BATTERY_STATS" />
    

    其中的MessageReceiver是继承自XGPushBaseReceiver的一个消息处理类,后续的状态栏信息和应用内消息通过此类处理,MessageReceiver类如下

    import android.app.NotificationManager;
    import android.content.Context;
    import android.util.Log;
    import android.widget.Toast;
    
    import com.fsxq.createcamp.bean.MessageEvent;
    import com.fsxq.createcamp.bean.XGMessageBean;
    import com.fsxq.createcamp.utils.MyUtils;
    import com.google.gson.Gson;
    import com.tencent.android.tpush.XGPushBaseReceiver;
    import com.tencent.android.tpush.XGPushClickedResult;
    import com.tencent.android.tpush.XGPushRegisterResult;
    import com.tencent.android.tpush.XGPushShowedResult;
    import com.tencent.android.tpush.XGPushTextMessage;
    
    import org.greenrobot.eventbus.EventBus;
    import org.json.JSONException;
    import org.json.JSONObject;
    
    /**
     * Create by 陈扬齐
     * Create on 2019-06-26
     * description:
     */
    public class MessageReceiver extends XGPushBaseReceiver {
    
        // 通知展示
        @Override
        public void onNotifactionShowedResult(Context context, XGPushShowedResult notifiShowedRlt) {
            Log.i("push", "收到状态栏消息:" + notifiShowedRlt.getTitle() + "---" + notifiShowedRlt.getContent());
            MyUtils.showToast(context,
                    "收到消息:" + notifiShowedRlt.getTitle() + "---" + notifiShowedRlt.getContent());
        }
    
        //反注册的回调
        @Override
        public void onUnregisterResult(Context context, int errorCode) {
            Log.i("push", "解绑账号的回调");
        }
    
        //设置tag的回调
        @Override
        public void onSetTagResult(Context context, int errorCode, String tagName) {
            Log.i("push", "设置tag的回调");
        }
    
        //删除tag的回调
        @Override
        public void onDeleteTagResult(Context context, int errorCode, String tagName) {
            Log.i("push", "删除tag的回调");
        }
    
        // 通知点击回调 actionType=1为该消息被清除,actionType=0为该消息被点击。此处不能做点击消息跳转,详细方法请参照官网的Android常见问题文档
        @Override
        public void onNotifactionClickedResult(Context context, XGPushClickedResult message) {
            Log.i("push", "+++++++++++++++ 通知被点击 跳转到指定页面。");
            NotificationManager notificationManager =
                    (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.cancelAll();
            if (context == null || message == null) {
                return;
            }
            String text = "";
            if (message.getActionType() == XGPushClickedResult.NOTIFACTION_CLICKED_TYPE) {
                // 通知在通知栏被点击啦。。。。。
                // APP自己处理点击的相关动作
                // 这个动作可以在activity的onResume也能监听,请看第3点相关内容
                text = "通知被打开 :" + message;
            } else if (message.getActionType() == XGPushClickedResult.NOTIFACTION_DELETED_TYPE) {
                // 通知被清除啦。。。。
                // APP自己处理通知被清除后的相关动作
                text = "通知被清除 :" + message;
            }
            Toast.makeText(context, "广播接收到通知被点击:" + message.toString(), Toast.LENGTH_SHORT).show();
            // 获取自定义key-value
            String customContent = message.getCustomContent();
            if (customContent != null && customContent.length() != 0) {
                try {
                    JSONObject obj = new JSONObject(customContent);
                    // key1为前台配置的key
                    if (!obj.isNull("key")) {
                        String value = obj.getString("key");
                        Log.i("push", "键值对消息:" + value);
                    }
                    // ...
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }
    
        //注册的回调
        @Override
        public void onRegisterResult(Context context, int errorCode,
                                     XGPushRegisterResult message) {
            if (context == null || message == null) {
                return;
            }
            String text = "";
            if (errorCode == XGPushBaseReceiver.SUCCESS) {
                text = "注册成功" + message;
                // 在这里拿token
                String token = message.getToken();
            } else {
                text = message + "注册失败错误码:" + errorCode;
            }
            Log.i("push", text);
        }
    
        // 消息透传的回调
        @Override
        public void onTextMessage(Context context, XGPushTextMessage message) {
            Log.i("push", "应用内消息:" + new Gson().toJson(message));
            String customContent = message.getCustomContent();
            if (customContent != null && customContent.length() != 0) {
                try {
                    XGMessageBean bean = new Gson().fromJson(customContent, XGMessageBean.class);
                    EventBus.getDefault().post(new MessageEvent(bean.getType()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    

    通过如上操作就已经完成信鸽推送的配置了。

    2.绑定账号

    信鸽提供了三种方式绑定推送终端,设备Token,Tag(标签),账号。通过这三种方式可以实现一对一,一对多等推送目的,我使用的是通过绑定用户账号确定推送目标,简单的用一个单例TPushManager封装一下信鸽绑定找那个号和解绑账号的功能如下

    import android.content.Context;
    import android.text.TextUtils;
    import android.util.Log;
    
    import com.fsxq.createcamp.bean.Constant;
    import com.fsxq.createcamp.retrofit.RetrofitFactory;
    import com.fsxq.createcamp.utils.SPUtils;
    import com.tencent.android.tpush.XGIOperateCallback;
    import com.tencent.android.tpush.XGPushConfig;
    import com.tencent.android.tpush.XGPushManager;
    
    /**
     * Create by 陈扬齐
     * Create on 2019-06-26
     * description:
     */
    public class TPushManager {
    
        private TPushManager() {
        }
    
        private static class TPushManagerHolder {
            private static final TPushManager INSTANCE = new TPushManager();
        }
    
        public static TPushManager getInstance() {
            return TPushManager.TPushManagerHolder.INSTANCE;
        }
    
        /**
         * 初始化绑定
         *
         * @param context
         */
        public void config(Context context) {
            //线上环境不开启debug
            if (!RetrofitFactory.IS_ONLINE) {
                XGPushConfig.enableDebug(context, true);
            }
            String userId = SPUtils.getInstance().getString(Constant.SP.USER_ID);
            String pushPrefix = SPUtils.getInstance().getString(Constant.SP.PUSH_PREFIX);
            if (TextUtils.isEmpty(userId) || TextUtils.isEmpty(pushPrefix))
                return;
            String account = pushPrefix + userId;
            Log.i("push", "account:" + account);
            XGPushManager.registerPush(context, account,
                    new XGIOperateCallback() {
                        @Override
                        public void onSuccess(Object data, int i) {
                            Log.i("push", "注册成功:" + data);
                        }
    
                        @Override
                        public void onFail(Object data, int errorCode, String msg) {
                            Log.i("push", "注册失败,错误码:" + errorCode + "错误信息:" + msg);
                        }
                    });
    
    //        // 新建自定义样式
    //        XGBasicPushNotificationBuilder build = new XGBasicPushNotificationBuilder();
    //        // 设置自定义样式属性,该属性对对应的编号生效,指定后不能修改。
    //        build.setIcon(R.mipmap.logo)
    //                .setSound(RingtoneManager.getActualDefaultRingtoneUri(context,
    //                        RingtoneManager.TYPE_ALARM)) // 设置声音
    //                .setDefaults(Notification.DEFAULT_VIBRATE) // 振动
    //                .setFlags(Notification.FLAG_NO_CLEAR); // 是否可清除
    //        // 设置通知样式,样式编号为1,即build_id为1,可通过后台脚本指定
    //        XGPushManager.setPushNotificationBuilder(context, 1, build);
        }
    
        /**
         * 解除账号绑定
         *
         * @param context
         */
        public void unRegister(Context context) {
            String userId = SPUtils.getInstance().getString(Constant.SP.USER_ID);
            String pushPrefix = SPUtils.getInstance().getString(Constant.SP.PUSH_PREFIX);
            if (TextUtils.isEmpty(userId) || TextUtils.isEmpty(pushPrefix))
                return;
            String account = pushPrefix + userId;
            XGPushManager.delAccount(context, account);
            XGPushManager.unregisterPush(context);
        }
    }
    

    然后根据你的需求在Application或者Mainactivity进行账号绑定

     TPushManager.getInstance().config(this);
    
    3:接收状态栏消息

    如信鸽后台发送一条状态栏消息,在MessageReceiver的onNotifactionShowedResult回调中就能接收到状态栏消息了。在这之前先确定一下APP是否有获取通知权限,没有则提示用户齐设置页面开启,获取通知权限实现如下

    /**
         * 通知用户开启推送
         */
        private void initNotificationRight() {
            if (NotificationManagerCompat.from(this).areNotificationsEnabled()) {
                Log.i("push", "已有通知权限");
            } else {
                Log.i("push", "没有通知权限");
                new QMUIDialog.MessageDialogBuilder(this)
                        .setTitle("开启推送通知")
                        .setMessage("打开通知,不错过每一个精彩时刻~")
                        .addAction("以后再说", (dialog, index) -> dialog.dismiss())
                        .addAction("确定", (dialog, index) -> {
                            Intent localIntent = new Intent();
                            localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            if (Build.VERSION.SDK_INT >= 9) {
                                localIntent.setAction("android.settings" +
                                        ".APPLICATION_DETAILS_SETTINGS");
                                localIntent.setData(Uri.fromParts("package",
                                        MainActivity.this.getPackageName(),
                                        null));
                            } else if (Build.VERSION.SDK_INT <= 8) {
                                localIntent.setAction(Intent.ACTION_VIEW);
    
                                localIntent.setClassName("com.android.settings",
                                        "com.android.settings.InstalledAppDetails");
                                localIntent.putExtra("com.android.settings.ApplicationPkgName",
                                        MainActivity.this.getPackageName());
                            }
                            startActivity(localIntent);
                            dialog.dismiss();
                        })
                        .show();
            }
        }
    
    image.png
    4.应用内通知

    应用内通知不在状态栏展示,这个功能就比较有用了,比如通知用户有未读消息,有新的版本发布,有新的广告图去下载,而且不受限是否有通知权限,且可以携带键值对参数方便客户端进行不同的处理。在MessageReceiver的onTextMessage回调中接收到消息,通过回调过来的结果message.getCustomContent
    可以获得json字符串格式的键值对参数,具体格式可以通过Gson转对象为json字符串查看。解析到键值对的值再通过广播或者EventBus等进行所需操作。

     @Override
        public void onTextMessage(Context context, XGPushTextMessage message) {
            Log.i("push", "应用内消息:" + new Gson().toJson(message));
            String customContent = message.getCustomContent();
            if (customContent != null && customContent.length() != 0) {
                try {
                    XGMessageBean bean = new Gson().fromJson(customContent, XGMessageBean.class);
                    EventBus.getDefault().post(new MessageEvent(bean.getType()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
    5.解绑账号

    账户退出登录的时候解除bangd

     TPushManager.getInstance().unRegister(this);
    

    致此信鸽使用基本完成了,下一篇写信鸽集成第三方厂商推送通道华为、小米、魅族

    相关文章

      网友评论

        本文标题:信鸽推送笔记

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