推送接入记录(华为篇)

推送系类文章 开篇吐槽

华为平台的SDK 是接入最费劲的,其原因是我参考了腾讯Demo中的华为接入。

这里给大家提个醒:接入三方SDK,直接看官方文档就行了,不然真心耽误时间。

接入时间(一天)

遇到问题:

步骤一、配置签名证书指纹;

恩,不错。配置一个SHA256,卡了我一上午。其原因呢~ 可能是我太蠢吧。(或者是华为官网适配和设计,我已经无力吐槽了)

贴图

这是提的工单

这是华为给我的回答

瞬间让我有一种摔电脑的冲动。这个对号,某种意思上难道不是一种校验成功的提示吗?你告诉我是确认按钮。更扯的是,我的屏幕是竖屏。所以在我电脑上看,这个对号是折行的。好了 真的是我太蠢。

 

步骤二:

按照官方文档步骤接入就行了。

https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/android-integrating-sdk-0000001050040084

1、添加AppGallery Connect文件

2、添加Maven 代码库

3、添加依赖:com.huawei.hms:push:5.0.1.300   这个应该是最新版本了。

4、文件头添加配置 apply plugin: 'com.huawei.agconnect'

到这里,我们添加的华为一些文件库已经完毕了。

步骤三:

配置Manifest文件

这一点比老版本强多了,老版本各种配置添加,如果你一部分配置是参考Demo 那就更完蛋,直接绕晕,

    <service
        android:name=".DemoHmsMessageService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.huawei.push.action.MESSAGING_EVENT"/>
        </intent-filter>
    </service>
这是我写的具体实现,没什么东西。直接贴出来,为偷懒的兄弟谋福利。
public class HuWeiService extends HmsMessageService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        // 接收透传消息方法。
        Logger.e("onMessageReceived:" + JSON.toJSONString(remoteMessage));
    }

    @Override
    public void onNewToken(String s) {
        super.onNewToken(s);
        // 服务端刷新token。
        if (TextUtils.isEmpty(s)) {
            Logger.e("HuWei Token 为空");
        } else {
            Logger.e("HuWei Token" + s);
            if (IMFunc.isBrandHuawei()) {
                UserInfo.setHwPushRegId(s);
// 我这里是记录一下Token。你可以直接给后台,或者腾讯IM校验令牌。
            }
        }
    }


}

配置混淆就随意了,我直接没开  哈哈

步骤四:

1、申请Token

    方式一:客户端调用HmsInstanceId类中的getToken方法向服务端请求应用的唯一标识 (不推荐使用)

   方式二: 清单文件配置:自动初始化,Token 会在 步骤三 服务的 onNewToken 中返回。(看自己意愿,如果不是华为手机,会报错,但不影响程序)

    <meta-data
        android:name="push_kit_auto_init_enabled"
        android:value="true"/>
</application>

   方式三: 应用在主Activity类中显式调用setAutoInitEnabled(boolean enable)方法(推荐使用,最主要的是,可以判断启动手机型号,判断是否初始化)

HmsMessaging.getInstance(this).setAutoInitEnabled(true);

判断是否是华为手机的方法:

    public static boolean isBrandHuawei() {
        return "huawei".equalsIgnoreCase(Build.BRAND) || "huawei".equalsIgnoreCase(Build.MANUFACTURER);
    }

步骤五:处理转跳

到此为止,你可以接受正常的推送消息。并且点击 会打开APP

华为转跳目标界面,是后台发送的消息直接指定的。

这一点我必须吐槽(不知道为什么要这样设计,而不是按照老版本的在一个通知回调中 监听点击,并处理数据)这简直是对我们移动端侮辱,你说 你让我怎么刚过后台呢,后台姥爷们怎么能够这么便宜 弱小可怜的 移动端呢,毕竟人家  IOS ~~省略一万字

文档中 栗子数据:

    {
        "message": {
            "notification": {
                "title": "message title",
                "body": "message body"
            },
            "android": {
                "notification": {
                    "click_action": {
                        "type": 1,
                        "intent": "intent://com.huawei.codelabpush/deeplink?#Intent;scheme=pushscheme;launchFlags=0x4000000;i.age=180;S.name=abc;end"
                    }
                }
            },
            "token": [
                "pushtoken1"
            ]
        }
    }

这里的数据需要我们生成并给与后台,

"intent://com.huawei.codelabpush/deeplink?#Intent;scheme=pushscheme;launchFlags=0x4000000;i.age=180;S.name=abc;end"

生成方式:

    Intent intent = new Intent(Intent.ACTION_VIEW);
    // Scheme协议(例如:pushscheme://com.huawei.codelabpush/deeplink?)需要开发者自定义
    intent.setData(Uri.parse("pushscheme://com.huawei.codelabpush/deeplink?"));
    // 往intent中添加参数,用户可以根据自己的需求进行添加参数:
    intent.putExtra("name", "abc");
    intent.putExtra("age", 180);
    // 应用必须带上该Flag,如果不添加该选项有可能会显示重复的消息
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    String intentUri = intent.toUri(Intent.URI_INTENT_SCHEME);
    // 打印出的intentUri值就是设置到推送消息中intent字段的值
    Log.d("intentUri", intentUri);

其实没必要这么麻烦,Scheme 协议不懂,和 H5的小妹妹总是经常交流吧。自己拼呗

步骤六:

到这里,所以的问题才算解决。但是 步骤五提出的疑问,你怎么刚得过后台大爷们呢~ 自己写一个中间页吧,

public class HuWeiDevelopmentActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_development);
        Intent intent = getIntent();
             String name1 = intent.getData().getQueryParameter("name");
            int age1 = Integer.parseInt(intent.getData().getQueryParameter("age"));
    }
}

清单文件中:

    <activity android:name=".HuWeiDevelopmentActivity">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data
                android:host="com.huawei.codelabpush"
                android:path="/deeplink"
                android:scheme="pushscheme" />
        </intent-filter>
    </activity>

 

结束:

这次接入华为推送,工时一天 ,但是真正的接入 感觉一个小时都富裕

总结原因:

1.自己脑残,配置一个工程 。一个SHA256,我花费一上午时间。

2.拿来主义,或者偷懒,因为之前接入腾讯IM,腾讯提供的工程中已经接入了华为推送,所以我就偷懒直接copy,然后出现问题,解决问题。最后全部删除,按照文档一步一步接入。

3、前后台没有统一时间接入。我在看文档的时候后台在解决bug,我接入完成,后台开始接入。中间配合等待时间略长。

 

好在完成任务,小米  VIVO 极光 ,我就不写啥了。

小米SDK中规中矩,设计思路,和自己脑子逻辑完美契合。我缺啥,他有啥。所以一个小时结束。

VIVO SDK是最牛逼的,牛逼之处在与完全是提开发者着想的平台,接入步骤一溜到底。粘贴复制,不给你太多选择,也不让你操太多心。

极光 SDK 忘记了,接入太快,没啥印象 ,并且没有遇到什么问题。

 

 

 

 

 

/** * 初始化SDK */ private static void initSDK(String appid, String appkey) { ProxySelector defaultProxySelector = ProxySelector.getDefault(); Proxy proxy = null; List<Proxy> proxyList = null; try { proxyList = defaultProxySelector.select(new URI( "http://www.google.it")); } catch (URISyntaxException e) { e.printStackTrace(); } if (proxyList != null && proxyList.size() > 0) { proxy = proxyList.get(0); Log.d(TAG, "Current Proxy Configuration: " + proxy.toString()); } AppInfo appInfo = new AppInfo(); appInfo.setAppId(appid);// 应用ID appInfo.setAppKey(appkey);// 应用Key appInfo.setCtx(ctx); /* * VersionCheckLevelNormal 版本检查失败可以继续进行游戏 VersionCheckLevelStrict * 版本检查失败则不能进入游戏 默认取值为VersionCheckLevelStrict */ appInfo.setVersionCheckStatus(AppInfo.VERSION_CHECK_LEVEL_STRICT); // 初始化SDK Commplatform.getInstance().Init(0, appInfo, new CallbackListener<Integer>() { @Override public void callback(final int paramInt, Integer paramT) { ctx.runOnUiThread(new Runnable() { @Override public void run() { Log.i(TAG, "Init paramInt = " + paramInt); // ok.setEnabled(true); LogUtil.send("初始化: " + paramInt); } }); } }); } /** * 用户登录 * */ public static void loginEx(Context context) { Bundle bundle = new Bundle(); bundle.putString("nounce", UUID.randomUUID().toString() .replace("-", "")); Commplatform.getInstance().LoginEx(context, bundle, new CallbackListener<Bundle>() { @Override public void callback(int resultCode, Bundle bundle) { if (resultCode == ErrorCode.COM_PLATFORM_SUCCESS) { // 完成参数验签 // 处理登录成功逻辑 // HomeActivity.show(ctx); // String uin= bundle.getString("uin"); LogUtil.send("登录成功 :"); // String uin= bundle.get("nounce").toString(); String uin = Commplatform.getInstance() .getLoginUin(); LogUtil.send("登录成功 uin :" + uin); UnityPlayer.UnitySendMessage("MainScript", "HuaweiLoginBack", uin); } else { // 处理登录失败逻辑 LogUtil.send("登录失败"); } } }); } /** * 充值 * */ public static int pay(String currency) { isPaying = true; Payment payment = new Payment(); ProductBean productBean = productMap.get(currency); makeSerial(); payment.setTradeNo(orderKen); payment.setProductId(productBean.getProductId()); payment.setSubject(productBean.getTitle()); payment.setDesc(productBean.getDescription()); payment.setAmount(productBean.getPrice_amount()); payment.setCurrency(productBean.getPrice_currency_code()); payment.setNote(""); payment.setNotifyURL(""); payment.setThirdAppId(id); payment.setThirdAppName("Spot Battle"); payment.setThirdAppPkgname("com.testcrecool.mi"); final String tradeNo = payment.getTradeNo(); final String productId = payment.getProductId(); // 将订单的详细信息插入数据库 PaymentTableAdapter.insert(ctx, payment); int res = Commplatform.getInstance().UniPayExt(payment, ctx, new CallbackListener<PayResult>() { @Override public void callback(final int code, final PayResult arg1) { ctx.runOnUiThread(new Runnable() { public void run() { // 回调结果,即支付过程结束 isPaying = false; LogUtil.send("回调结果,即支付过程结束 code: " + code); if (code == ErrorCode.COM_PLATFORM_SUCCESS) { // TODO Example 1 // 根据final 的 productID 或者 orderId // 去处理商品,比如查询道具,发放道具等 // TODO Example 2 // 可以根据订单号查询订单详细信息,在做订单的处理,比如查询道具,发放道具等 // 如下: Payment payment = PaymentTableAdapter .queryByOrderId(ctx, orderKen); // 购买有结果,即删除此订单号 PaymentTableAdapter.deleteByOrderId(ctx, orderKen); Log.i(TAG, "COM_PLATFORM_SUCCESS"); LogUtil.send("成功"); UnityPlayer.UnitySendMessage("MainScript", "hwPayCallback", orderKen); } else if (code == ErrorCode.COM_PLATFORM_ERROR_PAY_FAILURE) { Log.i(TAG, "COM_PLATFORM_ERROR_PAY_FAILURE"); } else if (code == ErrorCode.COM_PLATFORM_ERROR_PAY_CANCEL) { // 购买失败 // 购买有结果,即删除此订单号 PaymentTableAdapter.deleteByOrderId(ctx, tradeNo); Log.i(TAG, "COM_PLATFORM_ERROR_PAY_CANCEL"); UnityPlayer.UnitySendMessage("MainScript", "hwPayCallback", "error"); } else if (code == ErrorCode.COM_PLATFORM_ERROR_PAY_CANCEL) { LogUtil.send("取消购买"); // 取消购买 // 购买有结果,即删除此订单号 PaymentTableAdapter.deleteByOrderId(ctx, tradeNo); UnityPlayer.UnitySendMessage("MainScript", "hwPayCallback", "error"); } else { LogUtil.send("Purchase failed. Error code:" + code); Log.i(TAG, "COM_PLATFORM_ERROR_UNKNOWN"); } } }); } }); if (res == 0) { LogUtil.send("000"); return 0; } else { // 返回错误,即支付过程结束 isPaying = false; LogUtil.send("返回错误,即支付过程结束"); return -1; } } /** * 获取应用内商品信息 **/ public static void querySkuDetail() { Commplatform.getInstance().getSkuDetails(ctx, new CallbackListener<List<SkuDetail>>() { @Override public void callback(int errorCode, List<SkuDetail> skuDetails) { if (errorCode == ErrorCode.COM_PLATFORM_SUCCESS && skuDetails != null) { for (SkuDetail detail : skuDetails) { ProductBean prBean = new ProductBean(); prBean.setProductId(detail.productId); prBean.setPrice(detail.price); prBean.setPrice_amount(detail.price_amount); prBean.setPrice_currency_code(detail.price_currency_code); prBean.setTitle(detail.title); prBean.setDescription(detail.description); productMap.put(detail.productId, prBean); } // showText.setText(buffer.toString()); LogUtil.send("获取应用内商品信息"); } else { // showText.setText("query error"); LogUtil.send("query error"); } } }); } /** * 生成订单号 * */ private static String makeSerial() { // 生成订单号 orderKen = UUID.randomUUID().toString().replaceAll("-", ""); return orderKen; } // 同步支付订单的漏单查询接口调用 private static void checkPay(final Payment paymentSerial) { QueryPayment queryPayment = new QueryPayment(); queryPayment.setTradeNo(paymentSerial.getTradeNo()); queryPayment.setThirdAppId(paymentSerial.getThirdAppId()); final String tradeNo= queryPayment.getTradeNo(); Commplatform.getInstance().queryPayment(queryPayment, ctx, new CallbackListener<PaymentState>() { @Override public void callback(int paramInt, PaymentState paramT) { if (paramInt == ErrorCode.COM_PLATFORM_SUCCESS) { // Step2:订单查询成功 从数据库删除此订单号 PaymentTableAdapter.deleteByOrderId(ctx,tradeNo); // 订单支付成功,可以根据订单号查询订单详细信息,在做订单的处理,比如查询道具,发放道具等 // TODO… 游戏代码 LogUtil.send("漏单查询成功!!!"); UnityPlayer.UnitySendMessage("MainScript", "hwPayCallback", orderKen); } else if (paramInt == ErrorCode.COM_PLATFORM_ERROR_UNEXIST_ORDER) { // Step2:订单不存在 从数据库删除此订单号 PaymentTableAdapter.deleteByOrderId(ctx, tradeNo); // 根据游戏自身的体验决定如何处理 UnityPlayer.UnitySendMessage("MainScript", "hwPayCallback", "error"); } else if (paramInt == ErrorCode.COM_PLATFORM_ERROR_PAY_FAILURE) { // Step2:订单支付失败 从数据库删除此订单号 PaymentTableAdapter.deleteByOrderId(ctx, tradeNo); // 根据游戏自身的体验决定如何处理 UnityPlayer.UnitySendMessage("MainScript", "hwPayCallback", "error"); } else if (paramInt == ErrorCode.COM_PLATFORM_ERROR_SERVER_RETURN_ERROR) { // Step2:服务端返回错误 从数据库删除此订单号 PaymentTableAdapter.deleteByOrderId(ctx, tradeNo); // 根据游戏自身的体验决定如何处理 UnityPlayer.UnitySendMessage("MainScript", "hwPayCallback", "error"); } else if (paramInt == ErrorCode.COM_PLATFORM_ERROR_PAY_REQUEST_SUBMITTED) { // 订单已提交 // 根据游戏自身的体验决定如何处理 // 后续还需要继续查询 UnityPlayer.UnitySendMessage("MainScript", "hwPayCallback", "error"); } else { // 未知错误 // 根据游戏自身的体验决定如何处理 // 后续还需要继续查询 } } }); }
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值