华为推送集成

本文主要参考了华为推送官方提供的集成及开发流程,在华为推送官网还提供了多种消息方式设置,可查看参考。

目录

一、配置AppGallery Connect

创建项目与应用

生成证书指纹

开通API服务

二、集成HMS Core SDK

配置文件

Maven仓地址配置

添加编译依赖

配置签名

同步工程

三、配置Manifest文件

四、基础能力

获取token

注销Push Token

发送测试消息

网站推送

API推送

获取消息数据

消息提示


一、配置AppGallery Connect

创建项目与应用

开发应用前需要您在 AppGallery Connect中配置相关信息。
登录后进入AGC控制台,点击我的项目配置项目资料,并添加应用

添加应用中需注意应用包名需与程序包名保持一致,并且应该一旦创建之后无法修改

添加应用后需要添加当前应用的证书指纹

生成证书指纹

通过Android Studio创建一个新的签名文件并使用其对APK进行签名。此签名文件后续会用于生成SHA256指纹。
  • 在新建的Android Studio工程的菜单栏中选择"Build > Generate Signed Bundle/APK..."。
  • 在"Generate Signed Bundle or APK"页面,选择"APK"签名,并点击"Next"。
  • 在填写签名文件信息页面,如果已经存在签名文件,则点击"Choose existing..."选择签名文件,并填写对应签名文件的"Key store password"、"Key alias"、"Key password",然后点击"Next",不存在签名文件的话可以点击"Create new..."创建。这里生成的签名文件需记住保存位置,后边要用到。
  • 通过JDK的Keytool工具以及签名文件,导出SHA256指纹,在keytool.exe目录下使用keytool -list -v -keystore 命令运行,为应用签名证书的完整路径。
  • AppGallery Connect上添加指纹证书,将上一步生成的SHA256指纹配置到AppGallery Connect上,配置完成后,点击"保存"

开通API服务

在配置完证书指纹后需要在AppGallery Connect上开启API服务
  • 在项目的"应用"信息页面,选择"API管理"页签。
  • 在"API管理"页签中,找到想要开通的服务,打开该服务所在行的开关。例如这里选择推送服务。

二、集成HMS Core SDK

配置文件

在“项目设置 > 常规”页面的“应用”区域,点击“agconnect-services.json”下载配置文件。
将“agconnect-services.json”文件拷贝到应用级根目录下。

Maven仓地址配置

华为官网提供了 Gradle插件7.0以下版本、7.0版本和7.1及以上版本三个版本的配置方法,每个版本的配置各不相同,这里由于项目采用的Gradle插件版本在7.1以上,所以我只是实现了7.1及以上版本的配置。
  • 7.0以下版本
打开Android Studio项目级“build.gradle”文件。

添加HUAWEI AGC插件以及Maven代码库。
  • 在“buildscript > repositories”中配置HMS Core SDK的Maven仓地址。
  • 在“allprojects > repositories”中配置HMS Core SDK的Maven仓地址。
  • 如果App中添加了“agconnect-services.json”文件则需要在“buildscript > dependencies”中增加AGC插件配置。
buildscript {
    repositories {
        google()
        jcenter()
        // 配置HMS Core SDK的Maven仓地址。
        maven {url 'https://developer.huawei.com/repo/'}
    }
    dependencies {
        ...
        // 增加AGC插件配置,请您参见AGC插件依赖关系选择合适的AGC插件版本。
        classpath 'com.huawei.agconnect:agcp:1.6.0.300'
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        // 配置HMS Core SDK的Maven仓地址。
        maven {url 'https://developer.huawei.com/repo/'}
    }
} 
  • 7.0版本
打开Android Studio项目级“build.gradle”文件。

添加HUAWEI AGC插件以及Maven代码库。
  • 在“buildscript > repositories”中配置HMS Core SDK的Maven仓地址。
  • 在“buildscript > dependencies”中增加Android Gradle插件配置。
  • 如果App中添加了“agconnect-services.json”文件,则还需要在“buildscript > dependencies”中增加AGC插件。
buildscript {
    repositories {
        google()
        jcenter()
        // 配置HMS Core SDK的Maven仓地址。
        maven {url 'https://developer.huawei.com/repo/'}
    }
    dependencies {
        ...
        // 增加Android Gradle插件版本号配置,{version}为实际的Gradle插件版本号,例如7.0.1。
        classpath 'com.android.tools.build:gradle:{version}'
        // 增加AGC插件配置,请您参见AGC插件依赖关系选择合适的AGC插件版本。
        classpath 'com.huawei.agconnect:agcp:1.6.0.300'
    }
}

打开项目级“settings.gradle”文件,配置HMS Core SDK的Maven仓地址。

dependencyResolutionManagement {
    ...
    repositories {
        google()
        jcenter() 
        // 配置HMS Core SDK的Maven仓地址。
        maven {url 'https://developer.huawei.com/repo/'}
    }
}
  • 7.1及以上版本
打开Android Studio项目级“build.gradle”文件。

在“buildscript > dependencies”中增加Android Gradle插件配置。
如果App中添加了“agconnect-services.json”文件,则还需要在“buildscript > dependencies”中增加AGC插件。
buildscript {
    dependencies {
        // 增加agcp插件配置,推荐您使用最新版本的agcp插件。
        classpath 'com.android.tools.build:gradle:8.5.2'
        classpath 'com.huawei.agconnect:agcp:1.9.1.301'
    }
}
plugins {
    .......
}

打开项目级“settings.gradle”文件,配置HMS Core SDK的Maven仓地址。

pluginManagement {
    repositories {
        gradlePluginPortal()
        google()
        mavenCentral()
        // 配置HMS Core SDK的Maven仓地址。
        maven { url 'https://developer.huawei.com/repo/' }
    }
}
dependencyResolutionManagement {
    ...
    repositories {
        google()
        mavenCentral()
        // 配置HMS Core SDK的Maven仓地址。
        maven { url 'https://developer.huawei.com/repo/' }
    }
}

添加编译依赖

打开应用级的“build.gradle”文件。

在“dependencies”中添加如下编译依赖。
dependencies {
    implementation 'com.huawei.hms:push:6.11.0.300'
    // 可选,自动引导用户下载HMS Core APK,如果您的应用上架其他应用市场(例如:Google Play),请跳过该配置。
    implementation 'com.huawei.hms:hmscoreinstaller:6.7.0.300'
}
添加AGC插件配置。请根据实际情况选择:
  • 方式一:在文件头部声明下一行添加如下配置。
apply plugin: 'com.huawei.agconnect'
  • 方式二:在plugins中添加如下配置。
plugins {
    alias(libs.plugins.android.application)
    alias(libs.plugins.jetbrains.kotlin.android)
    id("kotlin-parcelize")
    id 'com.huawei.agconnect'
}

配置签名

将上边生成签名证书指纹步骤中生成的签名文件拷贝到工程应用级别目录下,在应用级的“build.gradle”文件中配置签名。
signingConfigs {
    config {
        // 根据您实际的签名信息,替换以下参数中的xxxx
        keyAlias 'key0'
        keyPassword 'xxxx'
        storeFile file('xxxx.jks')
        storePassword 'xxxx'
    }
}
buildTypes {
    debug {
        signingConfig signingConfigs.config
    }
    release {
        signingConfig signingConfigs.config
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}

同步工程

在完成以上的配置后,点击工具栏中的gradle同步图标完成“build.gradle”文件的同步,然后将相关依赖下载到本地。或者点击弹出的Sync Now同步工程。

三、配置Manifest文件

在您的项目中创建一个新的“service”并继承HmsMessageService类,用于接收透传消息、获取Token。此处以“DemoHmsMessageService”类为例。
...
import com.huawei.hms.push.HmsMessageService;
...
    public class DemoHmsMessageService extends HmsMessageService {
    ...
}

在“AndroidManifest.xml”文件的“application”标签中找到您上一步定义的“service”,在“intent-filter”标签中传入推送服务的“action”值,如下所示。

<service android:name=".DemoHmsMessageService" android:exported="false">
    <intent-filter>
        <action android:name="com.huawei.push.action.MESSAGING_EVENT"/>
    </intent-filter>
</service>
说明
  • exported属性需要设置为false,限制其他应用的组件唤醒该service。
  • 请确保仅定义了一个继承HmsMessageService类的“service”。
  • 当设备开机或重启后但用户尚未解锁设备时,若定义的“service”未配置“直接启动”模式,在您发送透传消息时会无法拉起透传服务。

四、基础能力

获取token

Token是每台设备上每个应用的唯一标识,应用调用getToken方法向Push服务端请求Token,当getToken方法返回为空时,Token可通过onNewToken方法返回,因此您必须实现onNewToken方法。您也可以通过SDK的自动初始化能力来自动获取Token。获取到Token后需要将Token上报到您自己的应用服务器。后续您可以调用下行消息API,根据Token来推送消息。
Token与华为帐号不相关,仅与您的App ID相关,因此切换华为帐号后Token不会变化。建议您直接使用推送服务提供的帐号校验功能来开发帐号相关功能,无需通过Token来判断。
Token一般情况不会变化,仅下列场景Token会发生变化。因此,禁止频繁申请Token,尤其严禁常驻应用定期频繁申请Token。
  • 清除应用数据(例如卸载应用并重新安装、设备恢复出厂设置等)后重新打开应用。
  • 应用显式调用注销Push TokengetToken
  • 建议在应用启动后首个Activity的onCreate方法中调用getToken方法。
JAVA
private void getToken() {
    // 创建一个新线程
    new Thread() {
        @Override
        public void run() {
            try {
                // 从agconnect-services.json文件中读取APP_ID
                String appId = "your APP_ID";

                // 输入token标识"HCM"
                String tokenScope = "HCM";
                String token = HmsInstanceId.getInstance(MainActivity.this).getToken(appId, tokenScope);
                Log.i(TAG, "get token success");
                
                // 判断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.");
}

Kotlin

private fun getToken() {   
    // 创建一个新线程
    object : Thread() {
        override fun run() {
            try {
                // 从agconnect-services.json文件中读取APP_ID
                val appId = "your APP_ID"
                
                // 输入token标识"HCM"
                val tokenScope = "HCM"
                val token = HmsInstanceId.getInstance(this@MainActivity).getToken(appId, tokenScope)
                Log.i(TAG, "get token success")
                
                // 判断token是否为空
                if (!TextUtils.isEmpty(token)) { 
                    sendRegTokenToServer(token)
                }                
            } catch (e: ApiException) { 
                Log.e(TAG, "get token failed, $e")
            }
        }
    }.start()
}
private fun sendRegTokenToServer(token: String) { 
    Log.i(TAG, "sending token to server.")
}

注销Push Token

JAVA

private void deleteToken() {
    // 创建一个新线程
    new Thread() {
        @Override
        public void run() {
            try {
                // 从agconnect-services.json文件中读取APP_ID
                String appId = "your APP_ID";
                
                // 输入token标识"HCM"
                String tokenScope = "HCM";

                // 注销Token
                HmsInstanceId.getInstance(context).deleteToken(appId, tokenScope);
                Log.i(TAG, "token deleted successfully");
            } catch (ApiException e) {
                Log.e(TAG, "delete token failed." + e);
            }
        }
    }.start();
}

Kotlin

private fun deleteToken() {   
    // 创建一个新线程
    object : Thread() {
        override fun run() {
            try {
                // 从agconnect-services.json文件中读取appId
                val appId = "your APP_ID"
                
                // 输入token标识"HCM"
                val tokenScope = "HCM"

                // 注销token
                HmsInstanceId.getInstance(this@MainActivity).deleteToken(appId, tokenScope)
                Log.i(TAG, "token deleted successfully")
            } catch (e: ApiException) { 
                Log.e(TAG, "delete token failed, $e")
            }
        }
    }.start()
}

华为官方还提供了自动初始化的方法,可参考华为推送官网查看。

发送测试消息

  • 网站推送

登录 AppGallery Connect网站,点击“我的项目”,在项目列表中找到您的项目,通过“增长 > 推送服务 >自动推送通知(Beta)”,在“推送通知”页签下点击“添加地理围栏推送通知”即或者“添加情景智能推送通知”可新建一个推送任务。目前只要在自动推送通知下的通知支持安卓端的推送,推送通知V3、V2仅支持鸿蒙下的推送。
在消息内容模块中填写消息名称、消息标题和内容,设置消息类型为通知栏消息,其他字段内容请参见场景介绍。
点击“效果测试”,填入您的Push Token,最后点击“确定”即可。
  • API推送

华为还提供了多种语言的推送API,可在文档中心中,查看。

这里以python语言为例,在github中下载华为提供的推送DEMO,下载后,包含python27与python37版本,经测试python37的版本可在python39下运行。

下载解压后,在python37目录下运行python setup.py install安装运行库,在test目录下提供了多种示例方法。

在代码里需要分别添加app_id,app_secret,token其中app_id,app_secret可在AppGallery Connect中的项目中查看,

token则为上边获取到的token,token可以根据实际情况添加多个。

获取消息数据

获取通知栏或者透传消息的数据,需要实现onMessageReceived回调方法,收到消息的后续行为由应用处理。
您需要在“AndroidManifest.xml”文件的“application”标签下注册您自己的service,且只继承HmsMessageService类并实现其中的方法,此处以DemoHmsMessageService类为例。
Java
@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, "get Data: " + message.getData()
            + "\n getFrom: " + message.getFrom()
            + "\n getTo: " + message.getTo()
            + "\n getMessageId: " + message.getMessageId()
            + "\n getSentTime: " + message.getSentTime()
            + "\n getDataMap: " + message.getDataOfMap()
            + "\n getMessageType: " + message.getMessageType()
            + "\n getTtl: " + message.getTtl());

    Boolean judgeWhetherIn10s = false;
    // 如果消息在10秒内没有处理,需要您自己创建新任务处理
    if (judgeWhetherIn10s) {
        startWorkManagerJob(message);
    } else {
        // 10秒内处理消息
        processWithin10s(message);
    }
}
private void startWorkManagerJob(RemoteMessage message) {
    Log.d(TAG, "Start new job processing.");
}
private void processWithin10s(RemoteMessage message) {
    Log.d(TAG, "Processing now.");
}

Kotlin

override fun onMessageReceived(message: RemoteMessage?) {
    Log.i(TAG, "onMessageReceived is called")
    
    // 判断消息是否为空
    if (message == null)
    {        
        Log.e(TAG, "Received message entity is null!")
        return    
    }    
    
    // 获取消息内容
    Log.i(TAG, """getData: ${message.data}        
        getFrom: ${message.from}        
        getTo: ${message.to}        
        getMessageId: ${message.messageId}
        getSentTime: ${message.sentTime}           
        getDataMap: ${message.dataOfMap}
        getMessageType: ${message.messageType}   
        getTtl: ${message.ttl}""".trimIndent())

    val judgeWhetherIn10s = false   
    // 如果消息在10秒内没有处理,需要您自己创建新任务处理    
    if (judgeWhetherIn10s) {        
        startWorkManagerJob(message)    
    } else {     
        // 10秒内处理消息               
        processWithin10s(message)    
    }
}
private fun startWorkManagerJob(message: RemoteMessage?) {    
    Log.d(TAG, "Start new Job processing.")
}
private fun processWithin10s(message: RemoteMessage?) {    
    Log.d(TAG, "Processing now.")
}

需要注意,使用onMessageReceived方法接收,只能接收到透传消息或者是设置“message.android.notification.foreground_show”值为“false”。也就是python API中提供的send_data_message.py。

消息提示

由于发送透传消息无法显示通知栏消息,因此需要手动实现消息提示,这里在 processWithin10s(message) 中实现消息提示。主要实现了消息提示,以及点击消息跳转到程序首界面。

private fun processWithin10s(message: RemoteMessage?) {
    val intent = Intent(this, MainActivity::class.java).apply {
        flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
    }
    val pendingIntent: PendingIntent = PendingIntent.getActivity(
        this, 0, intent, PendingIntent.FLAG_IMMUTABLE
    )

    val builder = NotificationCompat.Builder(this, "default_channel")
        .setSmallIcon(R.drawable.xxxx)  // 设置小图标
        .setContentTitle("xxxx")  // 设置标题
        .setContentText("xxxxx")  // 设置内容
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)  // 设置优先级
        .setAutoCancel(true)  // 设置点击后自动消失
        .setContentIntent(pendingIntent)


    val notificationManager = NotificationManagerCompat.from(this)
    if (ActivityCompat.checkSelfPermission(
            this,
            Manifest.permission.POST_NOTIFICATIONS
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        return
    }
    notificationManager.notify(1, builder.build())  // 1 为通知 ID
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花满城南春巳至

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值