美文网首页
Android 华为集成消息推送sdk

Android 华为集成消息推送sdk

作者: 全球顶尖伪极客 | 来源:发表于2020-05-19 18:42 被阅读0次

    本来是想吐槽的,写到最好发现官网好清晰

    不容易发现的官方API

    image.png

    集成步骤:开发准备官方链接地址

    创建应用,添加签名证书
      1. 打开命令行工具(使用CMD命令),执行cd命令进入keytool.exe所在的目录
      1. 执行命令keytool -list -v -keystore <keystore-file>,按命令行提示进行操作。<keystore-file>为应用签名文件的完整路径。填写SHA256,然后等十几分钟后下载对应的agcibbetct0services.json文件。
    keytool -list -v -keystore I:\yhxx\releasexxxxx.keystore
    
    image.png image.png
    image.png
    添加应用的AppGallery Connect配置文件

    a. 登录 AppGallery Connect 网站,选择“我的项目”。
    b. 在项目列表中找到您的项目,在项目中点击需要集成HMS SDK的应用。
    c. 在“项目设置”页面中,单击“应用”栏下的agconnect-services.json下载配置文件。
    d. 将agconnect-services.json文件拷贝到应用级根目录下。

    image.png

    配置HMS SDK的maven仓地址

    a. 打开AndroidStudio项目级project下的build.gradle文件。

    image.png
    b. 在allprojects ->repositories里面配置HMS SDK的maven仓地址。
    allprojects {
        repositories {
            google()
            jcenter()
            maven {url 'https://developer.huawei.com/repo/'}
        }
    }
    

    c. 在buildscript ->repositories里面配置HMS SDK的maven仓地址。

    buildscript {
        repositories {
            google()
            jcenter()
            maven {url 'https://developer.huawei.com/repo/'}
        }
    }
    

    d. 在buildscript -> dependencies里面增加配置。

    buildscript {
        dependencies {
            classpath 'com.huawei.agconnect:agcp:1.2.1.301'
        }
    }
    
    添加编译依赖

    a. 打开应用级modulebuild.gradle文件。

    image.png
    b. 在dependencies中添加如下编译依赖。
    说明:{version}替换为实际的·SDK·版本号:implementation 'com.huawei.hms:push:4.0.3.301'

    根据文档来填写,版本号好像更新

    dependencies {
         //其它已存在的依赖不要删除 implementation 'com.huawei.hms:push:4.0.3.301
         implementation 'com.huawei.hms:push:{version}'
    }
    

    c. 在应用级build.gradle文件尾添加配置。

    apply plugin: 'com.huawei.agconnect'
    

    配置签名(不可少,否则会获取不到token,6003错误)

    android {
         signingConfigs {
             config {
                 keyAlias 'yalun'
                 keyPassword '123456'
                 storeFile file('I:/yhxx/release1.keystore')
                 storePassword '123456'
             }
         }
         buildTypes {
             debug {
                 signingConfig signingConfigs.config
             }
             release {
                 signingConfig signingConfigs.config
                 minifyEnabled false
                 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
             }
         }
     }
    
    同步工程

    修改完的build.gradle文件,点击右上方出现Sync Now等待同步完成。

    注册HWPushReceiverService:

    配置完成后,可以通过两种方式获取token,一种是清单文件直接加入配置,可以再onNewToken方法里面直接获取,推荐。再一种是设置一下,也是在onNewToken方法中获取token。参考本项目中的类HWPushReceiverService

    HWPushReceiverService类需要开发者自己定义,继承于com.huawei.hms.push.HmsMessageService类并实现其中的方法。
    exported属性需要设置为false

    image.png
    package com.cc.pushallsdk;
    
    import android.text.TextUtils;
    import android.util.Log;
    
    import com.huawei.hms.push.HmsMessageService;
    import com.huawei.hms.push.RemoteMessage;
    
    import java.util.Arrays;
    
    
    public class HWPushReceiverService extends HmsMessageService {
        private static String TAG=HWPushReceiverService.class.getSimpleName();
        @Override
        public void onMessageReceived(RemoteMessage remoteMessage) {
            super.onMessageReceived(remoteMessage);
            Log.i(TAG, "getCollapseKey: " + remoteMessage.getCollapseKey()
                    + "\n getData: " + remoteMessage.getData()
                    + "\n getFrom: " + remoteMessage.getFrom()
                    + "\n getTo: " + remoteMessage.getTo()
                    + "\n getMessageId: " + remoteMessage.getMessageId()
                    + "\n getOriginalUrgency: " + remoteMessage.getOriginalUrgency()
                    + "\n getUrgency: " + remoteMessage.getUrgency()
                    + "\n getSendTime: " + remoteMessage.getSentTime()
                    + "\n getMessageType: " + remoteMessage.getMessageType()
                    + "\n getTtl: " + remoteMessage.getTtl());
            RemoteMessage.Notification notification = remoteMessage.getNotification();
            if (notification != null) {
                Log.i(TAG, "\n getImageUrl: " + notification.getImageUrl()
                        + "\n getTitle: " + notification.getTitle()
                        + "\n getTitleLocalizationKey: " + notification.getTitleLocalizationKey()
                        + "\n getTitleLocalizationArgs: " + Arrays.toString(notification.getTitleLocalizationArgs())
                        + "\n getBody: " + notification.getBody()
                        + "\n getBodyLocalizationKey: " + notification.getBodyLocalizationKey()
                        + "\n getBodyLocalizationArgs: " + Arrays.toString(notification.getBodyLocalizationArgs())
                        + "\n getIcon: " + notification.getIcon()
                        + "\n getSound: " + notification.getSound()
                        + "\n getTag: " + notification.getTag()
                        + "\n getColor: " + notification.getColor()
                        + "\n getClickAction: " + notification.getClickAction()
                        + "\n getChannelId: " + notification.getChannelId()
                        + "\n getLink: " + notification.getLink()
                        + "\n getNotifyId: " + notification.getNotifyId());
    
            }
        }
        @Override
        public void onDeletedMessages() {
            super.onDeletedMessages();
    
        }
        /**
        *
        *清单文件设置了自动初始化能力的应用,不需要显式的调用getToken申请token,
        * Push SDK会自动申请token,并通过onNewToken回调方法返回。
        */
        @Override
        public void onNewToken(String token) {
            super.onNewToken(token);
            if (!TextUtils.isEmpty(token)) {
    //            refreshedTokenToServer(token);
            }
        }
    
        @Override
        public void onTokenError(Exception e) {
            super.onTokenError(e);
        }
    }
    
    
    清单文件AndroidManifest.xml集成的所有的可能用得到的
    <application>
            <!--华为-->
            <provider
                android:name="com.huawei.agconnect.core.provider.AGConnectInitializeProvider"
                android:authorities="${applicationId}.AGCInitializeProvider"
                android:exported="false" />
    
            <service
                android:name="com.huawei.agconnect.core.ServiceDiscovery"
                android:exported="false" />
    
            <service
                android:name="com.huawei.hms.support.api.push.service.HmsMsgService"
                android:enabled="true"
                android:exported="true"
                android:process=":pushservice">
                <intent-filter>
                    <action android:name="com.huawei.push.msg.NOTIFY_MSG" />
                    <action android:name="com.huawei.push.msg.PASSBY_MSG" />
                </intent-filter>
            </service>
            <!-- 自定义的HWPushReceiverService extends HmsMessageService-->
            <service
                android:name="com.cc.pushallsdk.HWPushReceiverService"
                android:exported="false">
                <intent-filter>
                    <action android:name="com.huawei.push.action.MESSAGING_EVENT" />
                </intent-filter>
            </service>
            <!-- 通知消息:点击不需要程序内容做处理,需要自定义跳转就要定义协议-->
            <!-- 透传消息:继承HmsMessageService里面复写onMessageReceived该方法,接收透传参数-->
            <activity android:name="com.cc.pushallsdk.TargetActivity">
                <intent-filter>
                    <action android:name="android.intent.action.VIEW" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <data
                        android:host="com.cc.pushallsdk"
                        android:path="/wandanotify"
                        android:scheme="wandapushscheme" />
                </intent-filter>
            </activity>
    
    </application>
    

    配置工程project.properties文件(不知是否必要,官方写了反正我添加了)

    打开您的工程的project.properties文件,添加如下代码,用于合并子工程中的Manifest文件。

    manifestmerger.enabled=true
    

    集成步骤:[基础能力官方链接地址]

    https://developer.huawei.com/consumer/cn/doc/development/HMS-Guides/push-basic-capability

    基础能力概览

    image.png
    • Step1与Step2,开发者的App集成HMS SDK,再调用HmsInstanceId.getToken接口获取到Push Token,请参考申请Push Token章节。

    • Step3,开发者的App将获取到的Push Token上报到开发者服务器App Provider Server上。

    • Step4,开发者使用服务器保存的Push Token调用Push服务端提供的API推送Push消息,请参考服务端开发指导章节。

    • Step5,Push服务器将开发者推送的Push消息发送给Push Token对应的用户设备,设备接收Push消息,请参考接收透传消息章节。

    • Step6与Step7,Push服务器检测到设备回复消息响应时,将响应状态回执给开发者,开发者需实现消息回执接收能力,请参考服务端开发指导章节。

    2. 客户端开发指导

    本章节指导开发者完成Push基础能力开发中的客户端开发,通过本开发指导的学习能够帮助开发者快速掌握客户端开发所需的知识技能,快速体验华为Push服务。基础能力客户端开发主要包括如下4个功能点:

    1、开发者集成Push SDK后申请Push Token,请参考申请Push Token章节,同时Push SDK 4.0版本我们提供了自动初始化获取token的能力,请参考自动初始化章节

    2、开发者App客户端接收服务端推送的Push透传消息,请参考接收透传消息章节

    3、是否允许NC(Notification Center)显示通知栏消息,请参考设置是否显示通知栏消息章节

    4、自定义点击消息的动作以及向App传递数据可以参考点击通知消息章节

    1、调用getToken方法获取Token
    private void getToken() {
        new Thread() {
            @Override
            public void run() {
                try {
                    // read from agconnect-services.json
                    String appId = AGConnectServicesConfig.fromContext(this).getString("client/app_id");
                    String token = HmsInstanceId.getInstance(this).getToken(appId, "HCM");
                    Log.i(TAG, "get token:" + token);
                    if(!TextUtils.isEmpty(token)) {
                        sendRegTokenToServer(token);
                    }
                } catch (ApiException e) {
                    Log.e(TAG, "get token failed, " + e);
                }
            }
        }.start();
    }
    private void sendRegTokenToServer(String token) {
        Log.i(TAG, "sending token to server. token:" + token);
    }
    

    2.3 接收透传消息

    2.3.1 场景介绍

    App如果订阅了主题消息或者服务器主动推送的透传消息(包括通知消息前台展示功能中设置通知消息由应用自己处理,区别于NC (Notification Center)通知栏消息),都需要App通过实现onMessageReceived回调方法来接收消息,收到消息的后续行为由应用自己处理
    重写onMessageReceived 继承于HmsMessageService所复写的方法获取透传消息数据。

    @Override
    public void onMessageReceived(RemoteMessage message) {
        Log.i(TAG, "onMessageReceived is called");
        if (message == null) {
            Log.e(TAG, "Received message entity is null!");
            return;
        }
        Log.i(TAG, "getCollapseKey: " + message.getCollapseKey()
                + "\n getData: " + message.getData()
                + "\n getFrom: " + message.getFrom()
                + "\n getTo: " + message.getTo()
                + "\n getMessageId: " + message.getMessageId()
                + "\n getOriginalUrgency: " + message.getOriginalUrgency()
                + "\n getUrgency: " + message.getUrgency()
                + "\n getSendTime: " + message.getSentTime()
                + "\n getMessageType: " + message.getMessageType()
                + "\n getTtl: " + message.getTtl());
        RemoteMessage.Notification notification = message.getNotification();
        if (notification != null) {
            Log.i(TAG, "\n getImageUrl: " + notification.getImageUrl()
                    + "\n getTitle: " + notification.getTitle()
                    + "\n getTitleLocalizationKey: " + notification.getTitleLocalizationKey()
                    + "\n getTitleLocalizationArgs: " + Arrays.toString(notification.getTitleLocalizationArgs())
                    + "\n getBody: " + notification.getBody()
                    + "\n getBodyLocalizationKey: " + notification.getBodyLocalizationKey()
                    + "\n getBodyLocalizationArgs: " + Arrays.toString(notification.getBodyLocalizationArgs())
                    + "\n getIcon: " + notification.getIcon()
                    + "\n getSound: " + notification.getSound()
                    + "\n getTag: " + notification.getTag()
                    + "\n getColor: " + notification.getColor()
                    + "\n getClickAction: " + notification.getClickAction()
                    + "\n getChannelId: " + notification.getChannelId()
                    + "\n getLink: " + notification.getLink()
                    + "\n getNotifyId: " + notification.getNotifyId());
        }
        Boolean judgeWhetherIn10s = false;
        // If the messages are not processed in 10 seconds, the app needs to use WorkManager for processing.
        if (judgeWhetherIn10s) {
            startWorkManagerJob(message);
        } else {
            // Process message within 10s
            processWithin10s(message);
        }
    }
    private void startWorkManagerJob(RemoteMessage message) {
        Log.d(TAG, "Start new job processing.");
    }
    private void processWithin10s(RemoteMessage message) {
        Log.d(TAG, "Processing now.");
    }
    

    2.4 设置是否显示通知栏消息

    2.4.1 场景介绍

    通知消息是由系统直接在通知中心下拉列表呈现的即时消息。开发者如果想控制应用是否允许显示通知栏消息,可以调用HmsMessaging.turnOnPush或者HmsMessaging.turnOffPush接口。如果开发者不调用此接口,系统默认是允许显示通知栏消息。

    HmsMessaging.getInstance(context).turnOnPush().addOnCompleteListener(new OnCompleteListener<Void>() {
        @Override
        public void onComplete(Task<Void> task) {
            if (task.isSuccessful()) {
                Log.i(TAG, "turnOnPush Complete");
            } else {
                Log.e(TAG, "turnOnPush failed: ret=" + task.getException().getMessage());
            }
        }
    });
    

    2.5 点击通知消息

    关于通知消息,开发者可以自定义点击消息的动作,包括:打开App首页、打开特定URL、打开自定义富媒体消息、打开自定义App页面。其中打开App首页与自定义App页面需要开发者端云协同开发来完成,下面我们讲下如何实现这两种动作并从服务端接收数据。

    注意:
    1、点击动作触发打开应用首页或者自定义App页面,都是通过跨应用启动Activity的方式来实现,需要保证要拉起的目标Activity的exported属性为true,即目标Activity要对外界公开,并且无权限保护,这样才能启动成功。
    2、通过通知消息传递数据给应用需要推送服务App版本为10.0.0及以上。

    2.5.1 打开自定义App页面

    打开自定义App页面有两种方式,一种是通过服务端REST API指定intent参数,另一种是指定action参数。如果同时指定了两个参数,会优先选取使用intent参数。

    指定intent参数

    跨应用启动Activity必须使用显式intent方式,通过intent可以携带额外的数据给客户端App
    1、intent参数生成
    在AndroidStudio工程中参照如下代码生成intent。

    Intent intent = new Intent(Intent.ACTION_VIEW);
    // Scheme协议(pushscheme://com.huawei.codelabpush/deeplink?)需要开发者自定义比如:`"wandapushscheme://com.cc.pushallsdk/wandanotify?`content=thisistest")
    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);
    

    intentUri

    开发者传参有两种方法:这些通过本地写获取得到intentUri给到服务端或者网页端进行传输
    方法1:参数之间用“&”相连,其中参数name=abc与age=180两个参数之间用“&”相连。例如:

    intent.setData(Uri.parse("pushscheme://com.huawei.codelabpush/deeplink?name=abc&age=180"));
    

    方法2:intent直接添加参数:

    intent.setData(Uri.parse("pushscheme://com.huawei.codelabpush/deeplink?"));
    intent.putExtra("name", "abc");
    intent.putExtra("age", 180);
    

    2、App服务端消息体中指定intent值

    服务端如何发送消息请参考服务端开发指导。消息体样例:

    {
        "message": {
            "data": "{'score':'7','time': '16:42'}",
            "notification": {
                "title": "message title",
                "body": "message body"
            },
            "android": {
                "data":"{'androidData':'7','time':'16:42'}",
                "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"
            ]
        }
    }
    

    3、客户端AndroidManifest.xml文件注册待启动的Activity类
    参照如下配置注册自定义的Activity,其中host、path、scheme需与步骤1中协议的配置相对应,否则不能跳转到指定的界面。

    <activity android:name=".DeeplinkActivity">
        <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

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

    自动初始化2

    方式2
    应用显式调用HmsMessaging.setAutoInitEnabled(boolean enable)方法,设置为true即为启用了自动初始化,反之为未启用。设置后值会保存在应用本地的shared_prefs目录下的文件中。
    
    

    相关文章

      网友评论

          本文标题:Android 华为集成消息推送sdk

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