推送

信鸽推送笔记

2019-06-27  本文已影响14人  Chenyangqi

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

开发步骤
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);

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

上一篇 下一篇

猜你喜欢

热点阅读