今年再次负责这个模块,最大亮点就是支持了系统的推送,也就是说你设备退出后台应用了,发推送还可以收到推送

android 友盟推送统计设置角标 友盟消息推送原理_android 友盟推送统计设置角标


测试方案

选择测试模式,可以无限制的发送数量
公司测试手机设备 token

  • 下发路径
    com.niaoyun.nycloud.AppStarActvitiy


集成其它厂商的注意点

使用弹窗功能

android 友盟推送统计设置角标 友盟消息推送原理_android 友盟推送统计设置角标_02

一定要指定某个activity,继承自UmengNotifyClickActivity 2 launchMode=”singleTask”和exported=”true” ,注意提醒后台也要此功能

1 现在的android手机对后台进程做了诸多限制。若使用一键清理,应用的channel进程被清除,将接收不到推送。通过接入小米托管弹窗功能,可有效防止以上情况,增加推送消息的送达率。通知将由小米系统托管弹出,点击通知栏将跳转到指定的Activity。该Activity需继承自UmengNotifyClickActivity,同时实现父类的onMessage方法,对该方法的intent参数进一步解析即可,该方法异步调用,不阻塞主线程.
2 如果不指定exported=”true”,进行一键清理后台所有应用(仅仅清楚指定的应用无影响),还是不能离线推送成功

缺陷

自测用通知模式可以收到离线后的消息
自定义的不行
不知是哪里错了吗

使用exported=”true”

发现每次进去那个页面老是显示出来,比如我以启动页设置了这个属性后
解决方式

Activity aty = AppManager.getActivity(MainActivity.class);
if ((aty != null && !aty.isFinishing())) {
        finish();
 }

百度查了exported

android:exported这个属性用于指示该服务是否能够被其他应用程序组件调用或跟它交互。如果设置为true,则能够被调用或交互,否则不能。设置为false时,只有同一个应用程序的组件或带有相同用户ID的应用程序才能启动或绑定该服务。
它的默认值依赖与该服务所包含的过滤器。没有过滤器则意味着该服务只能通过指定明确的类名来调用,这样就是说该服务只能在应用程序的内部使用(因为其他外部使用者不会知道该服务的类名),因此这种情况下,这个属性的默认值是false。另一方面,如果至少包含了一个过滤器,则意味着该服务可以给外部的其他应用提供服务,因此默认值是true。
这个属性不是限制把服务暴露给其他应用程序的唯一方法。还可以使用权限来限制能够跟该服务交互的外部实体。

检查app是否已注册到系统通道

调试设备,看logcat日志,在搜索框填入以下筛选条件 device token|MiPushBroadcastReceiver|HuaWeiReceiver|MeizuPushReceiver



  • 小米
//小米Push通道
implementation 'com.umeng.umsdk:xiaomi-push:3.6.17
implementation 'com.umeng.umsdk:xiaomi-umengaccs:1.1.0’

MiPushRegistar.register(final Context context, final String XIAOMI_ID, final String XIAOMI_KEY);
"mipush":true
"mi_activity":"com.umeng.message.example.MipushTestActivity" //此处请填写Activity完整包路径

{
"appkey": "",
"mi_activity": "com.umeng.message.example.MipushTestActivity"
"mipush": true,
"timestamp": 1473225266373,
"production_mode": "true",
"type": "unicast",
"device_tokens": "",
"payload":
    {"body":
       {"text": "from pa36a",
        "after_open": "go_app",
        "ticker": "Hello World",
        "title": "listcastpa43"
       }, 
     "display_type": "notification",
    }
}
  • 华为
//华为Push通道
    api 'com.umeng.umsdk:huawei-basetb:2.6.3.305'
    api 'com.umeng.umsdk:huawei-pushtb:2.6.3.305'
    api 'com.umeng.umsdk:huawei-umengaccs:1.2.1'

 HuaWeiRegister.register(context); // 华为appid 需要去另外配置 TODO
 <!--配置华为AppID,无法通过代码设置-->
        <meta-data
            android:name="com.huawei.hms.client.appid"
            android:value="appid=xxxxxx" />

处理方式和小米一样

但是需要额外配置些

  • 魅族
    3、配置系统通知图标
    请在drawable目录下添加一个图标,命名为stat_sys_third_app_notify.png,建议尺寸64px * 64px,图标四周留有透明。若不添加此图标,可能在部分魅族手机上无法弹出通知。

需要处理方式和华为差不多

  • vivo 和 oppo

貌似得上线才具有push 能力
找他们的建立的app,太绕了

/**
 * 友盟push 帮助类
 * @author bingley
 * @date 2019/9/4.
 */
public class UmPushHelper {


    /**
     * 初始化友盟推送信息
     * @param context
     */
    public static void initUmengSDK(Application context) {
        UMConfigure.setLogEnabled(false);
        // 参数一:当前上下文context;
        // 参数二:应用申请的Appkey(需替换);
        // 参数三:渠道名称;
        // 参数四:设备类型,必须参数,传参数为UMConfigure.DEVICE_TYPE_PHONE则表示手机;传参数为UMConfigure.DEVICE_TYPE_BOX则表示盒子;默认为手机;
        // 参数五:Push推送业务的secret 填充Umeng Message Secret对应信息(需替换)
        UMConfigure.init(context, UmConfig.UM_APP_KEY, "umeng", UMConfigure.DEVICE_TYPE_PHONE,
                UmConfig.UM_MESSAGE_SECRET);

        initPush(context);
    }

    private static void initPush(final Application context) {
        PushAgent pushAgent = PushAgent.getInstance(context);

        /**
         * 自定义行为的回调处理,参考文档:高级功能-通知的展示及提醒-自定义通知打开动作
         * UmengNotificationClickHandler是在BroadcastReceiver中被调用,故
         * 如果需启动Activity,需添加Intent.FLAG_ACTIVITY_NEW_TASK
         * */
        UmengMessageHandler messageHandler = new UmengMessageHandler() {

            /**
             * 通知的回调方法(通知送达时会回调)
             */
            @Override
            public void dealWithNotificationMessage(Context context, UMessage msg) {
                //调用super,会展示通知,不调用super,则不展示通知。
                super.dealWithNotificationMessage(context, msg);
                LogUtil.e("UmPushHelper---dealWithNotificationMessage");

                handlerUmessage(msg);
            }

            /**
             * 自定义消息的回调方法
             */
            @Override
            public void dealWithCustomMessage(final Context context, final UMessage msg) {
                LogUtil.e("UmPushHelper---dealWithCustomMessage");
                handlerUmessage(msg);
            }

            /**
             * 自定义通知栏样式的回调方法
             */
            @Override
            public Notification getNotification(Context context, UMessage msg) {
                LogUtil.e("UmPushHelper---getNotification");
                /*switch (msg.builder_id) {
                    case 1:
                        Notification.Builder builder = new Notification.Builder(context);
                        RemoteViews myNotificationView = new RemoteViews(context.getPackageName(),
                                R.layout.notification_view);
                        myNotificationView.setTextViewText(R.id.notification_title, msg.title);
                        myNotificationView.setTextViewText(R.id.notification_text, msg.text);
                        myNotificationView.setImageViewBitmap(R.id.notification_large_icon, getLargeIcon(context, msg));
                        myNotificationView.setImageViewResource(R.id.notification_small_icon,
                                getSmallIconId(context, msg));
                        builder.setContent(myNotificationView)
                                .setSmallIcon(getSmallIconId(context, msg))
                                .setTicker(msg.ticker)
                                .setAutoCancel(true);

                        return builder.getNotification();
                    default:
                        //默认为0,若填写的builder_id并不存在,也使用默认。
                        return super.getNotification(context, msg);
                }*/
                return super.getNotification(context, msg);
            }
        };
        pushAgent.setMessageHandler(messageHandler);

        /**
         * 自定义行为的回调处理,参考文档:高级功能-通知的展示及提醒-自定义通知打开动作
         * UmengNotificationClickHandler是在BroadcastReceiver中被调用,故
         * 如果需启动Activity,需添加Intent.FLAG_ACTIVITY_NEW_TASK
         * */
        UmengNotificationClickHandler notificationClickHandler = new UmengNotificationClickHandler() {

            @Override
            public void launchApp(Context context, UMessage msg) {
                super.launchApp(context, msg);
                LogUtil.e("UmPushHelper---launchApp");

                hanlderEventUI(context);
            }

            @Override
            public void openUrl(Context context, UMessage msg) {
                super.openUrl(context, msg);
                LogUtil.e("UmPushHelper---openUrl");

                hanlderEventUI(context);
            }

            @Override
            public void openActivity(Context context, UMessage msg) {
                super.openActivity(context, msg);
                LogUtil.e("UmPushHelper---openActivity");

                hanlderEventUI(context);
            }

            @Override
            public void dealWithCustomAction(Context context, UMessage msg) {
                LogUtil.e("UmPushHelper---dealWithCustomAction");

                hanlderEventUI(context);
            }
        };
        //使用自定义的NotificationHandler
        pushAgent.setNotificationClickHandler(notificationClickHandler);
        // //使用完全自定义处理
        //pushAgent.setPushIntentServiceClass(UmengNotificationService.class);


        //注册推送服务 每次调用register都会回调该接口
        pushAgent.register(new IUmengRegisterCallback() {

            @Override
            public void onSuccess(String deviceToken) {
                LogUtil.e("initUmengSDK", "--->>> onSuccess, deviceToken is " + deviceToken);
                SPUtils.put(context, CacheKey.SP_DEVICE_TOKEN, deviceToken);

            }

            @Override
            public void onFailure(String s, String s1) {
                LogUtil.e("initUmengSDK", "--->>> onFailure, s is " + s + ", s1 is " + s1);
            }
        });

        //https://developer.umeng.com/docs/66632/detail/98589
        // 小米平台注册
        MiPushRegistar.register(context, UmConfig.XIAOMI_APP_ID, UmConfig.XIAOMI_KEY);
        // 华为Push初始化
        HuaWeiRegister.register(context); // 华为appid 需要去另外配置 TODO
        // 魅族Push通道
        MeizuRegister.register(context, UmConfig.MZ_APP_ID, UmConfig.MZ_APP_KEY);
        // oppo
        OppoRegister.register(context, UmConfig.OPPO_APP_KEY, UmConfig.OPPO_APP_SECRET);
        //vivo 通道  // vivo appid 需要去另外配置 TODO
        VivoRegister.register(context);
        // 如果还有其它平台…… TODO
    }


    /**
     * 处理和后台交接的数据
     * @param uMessage
     */
    public static void handlerUmessage(UMessage uMessage) {
        try {
            String custom = uMessage.custom;
            if (StringUtils.isEmpty(custom)) {
                CustomBean customBean = GsonUtil.createGson().fromJson(custom, CustomBean.class);
                if (customBean == null) {
                    return;
                }

                uMessage.title = customBean.getTitle();
                uMessage.text = customBean.getText();


                String msgType = customBean.getMsgType();
                String bodyType = customBean.getBodyType();
                String msg = customBean.getMsg();
                String msgId = customBean.getMsgId();

                Packet packet = new Packet();
                Header header = new Header();
                Body body = new Body();


                if (!StringUtils.isEmpty(msgType)) {
                    header.setMsgType(Short.valueOf(msgType));
                }
                if (!StringUtils.isEmpty(bodyType)) {
                    body.setType(Short.valueOf(bodyType));
                }
                if (!StringUtils.isEmpty(msg)) {
                    byte[] secretContent = ApiUtil.getSecretContent(AppConfig.PUSH_KEY, msg);
                    body.setMsg(secretContent);
                }

                if (!StringUtils.isEmpty(msgId)) {

                }

                packet.setHeader(header);
                packet.setBody(body);

                PushMsgHelper.handler(packet);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 跳转UI处理
     * @param context
     */
    public static void hanlderEventUI(Context context) {
        boolean isLogin = (boolean) SPUtils.get(context, CacheKey.KEY_IS_LOGIN, false);
        if (isLogin) {
            //打开主页
            Intent i = new Intent(context, MainActivity.class);
            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(i);
            EventBus.getDefault().post(new MainUIEvent());
        } else {
            Intent i = new Intent(context, AppStarActvitiy.class);
            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(i);
        }
    }


}