针对AndroidStudio开发环境,华为提供了maven仓集成方式的WalletKit SDK包。在开始开发前,您需要将WalletKit SDK集成到您的AndroidStudio开发环境中:
在AndroidStudio开发环境中添加当前应用的AppGallery Connect配置文件。
配置HMS SDK的maven仓地址。
添加编译依赖。
步骤1:登录AppGallery Connect 网站,选择“我的应用”。
步骤2:在名称列表中找到应用所在的产品,点击对应的“Android应用”链接。

步骤3:选择“开发 > 概览”。
步骤4:单击“应用”栏下的“agconnect-service.json”下载配置文件。
步骤5:将agconnect-service.json文件拷贝到项目级根目录下。

----结束
步骤1:打开AndroidStudio项目级build.gradle文件。

步骤2:在allprojects ->repositories里面配置HMS SDK的maven仓地址。
- allprojects {
- repositories {
- google()
- jcenter()
- maven {url 'https://developer.huawei.com/repo/'}
- }
- }
步骤3:在buildscript->repositories中配置HMS SDK的maven仓地址。
- buildscript {
- repositories {
- google()
- jcenter()
- maven {url 'https://developer.huawei.com/repo/'}
- }
- }
步骤4:在buildscript -> dependencies里面增加配置。
- buildscript {
- dependencies {
- classpath 'com.huawei.agconnect:agcp:1.2.1.301'
- }
- }
*注:maven仓地址直接在浏览器中打开无法访问,只能在IDE中配置。
----结束
步骤1:打开应用级的build.gradle文件。

步骤2:在“dependencies” 中添加如下编译依赖。
- dependencies {
- implementation 'com.huawei.hms:wallet:{version}'
- }
*注:{version}替换为实际的SDK版本号,如:implementation 'com.huawei.hms:wallet:4.0.2.300'。
步骤3:在文件头添加配置。
- apply plugin: 'com.huawei.agconnect'
----结束
重新打开修改完的“build.gradle”文件,右上方出现“Sync Now”链接。单击“Sync Now”等待同步完成。

如果出现错误,请检查网络连接是否正常,以及检查gradle文件是否正确。
如果您的应用不需要设置只支持某些特定语言,则请忽略本步骤。应用将默认支持所有HMS SDK支持的语言。
如果您的应用需要设置只支持某些特定语言,则可通过本步骤配置。
打开应用级根目录的“build.gradle”文件。
在“android>defaultConfig”中新增“resConfigs”配置,“en”(英语)和“zh-rCN”(简体中文)为必须配置的语种,配置格式如下:
- android {
- defaultConfig {
- ...
- resConfigs "en", "zh-rCN", "需要支持的其他语言"
- }
- }
HMS SDK支持的语言列表请参考HMS SDK支持的语言。
针对Eclipse开发环境,华为提供了下载HMS SDK包本地集成的方式。在开始开发前,您需要将HMS SDK集成到您的Eclipse开发环境中。
步骤1:下载HMS Base SDK和WalletKitSDK,并解压zip包。
下载地址请参见:Eclipse SDK下载
步骤2:将所有SDK工程导入到您的工作空间。
选择菜单“File > Import”,再选择“Android > Existing Android Code Into Workspace”,单击“Next”。

单击“Browse”,选择工程所在的文件夹。在“Projects”下显示待导入的工程,默认全部勾选,单击“Finish”。
*注:待导入的工程必须和工作空间在相同的磁盘空间里,例如都在“D:\”。如果不在,您可以选择“Copy projects into workspace”,将工程文件复制到工作空间。

步骤3:将WalletKit SDK的jar文件导入您的工作空间中。
在您的工作空间新建libs目录,并将WalletKit SDK放入libs目录中。

右键您的工程选中Build Path-->Add Libraries,选中User Library。

新建User Library名称。

点击Add JARs...,并选中之前导入libs下的jar文件。

点击Finish即完成了WalletKit SDK的jar文件导入。
----结束
步骤1:右键单击您的工程,选择“Properties”。
步骤2:在左侧选择“Android”,单击“Add”,选择已导入空间的工程,单击“Apply and Close”。

步骤3:由于Eclipse的xml文件不支持$符号,将HMSSdkBase和Agconnect-core工程下AndroidManifest.xml文件中的“${applicationId}”替换成您的应用包名。
- <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" />
- </application>
----结束
将HMSSdkBase工程中assets目录下的资源文件拷贝到您的工程中assets目录下。

*注:如果依赖其他的kit资源,还需要复制对应kit的资源文件到您的工程目录下。

开发者编译APK前需要配置不要混淆HMS SDK,避免功能异常。
步骤1:打开Android工程的混淆配置文件。
步骤2:加入排除HMS SDK的混淆配置。
- -ignorewarning
- -keepattributes *Annotation*
- -keepattributes Exceptions
- -keepattributes InnerClasses
- -keepattributes Signature
- -keepattributes SourceFile,LineNumberTable
- -keep class com.hianalytics.android.**{*;}
- -keep class com.huawei.updatesdk.**{*;}
- -keep class com.huawei.hms.**{*;}
步骤3:如果开发者使用了AndResGuard,需要在混淆配置文件中加入AndResGuard允许清单。
- "R.string.hms*",
- "R.string.connect_server_fail_prompt_toast",
- "R.string.getting_message_fail_prompt_toast",
- "R.string.no_available_network_prompt_toast",
- "R.string.third_app_*",
- "R.string.upsdk_*",
- "R.layout.hms*",
- "R.layout.upsdk_*",
- "R.drawable.upsdk*",
- "R.color.upsdk*",
- "R.dimen.upsdk*",
- "R.style.upsdk*"
----结束
商户应用通过Wallet Kit SDK的接口判断当前移动设备是否满足加卡条件,是否已安装华为钱包App并且当前钱包版本支持该能力。
- //判断是否可以添加卡劵,请线程内调用
- WalletPassApiResponse response = mWalletKitApi.canAddPass(appId, passType);
商户服务器通过证书和私钥来签名卡劵数据,并生成卡劵包文件。
商户需要替换服务器示例代码“src\test\resources\release.config.properties”文件中私钥和证书(证书和私钥请通过接入准备章节操作获取,然后将整个文件做base64转码后得到字符串放入到配置文件中),此证书和私钥用于签名卡劵数据。
卡劵包由home.png, detail.png, signature, hwpass.json, manifest.json, home@2x.png, detail@2x.png七个文件组成,其中signture, manifest.json两个文件在调用服务端demo生成签名卡劵包时会自动生成,不需要商户提供,商户需要按照下方的hwpass.json文件的生成规则生成hwpass.json文件并提供四张图片(图片为可选操作,如果商户不提供则使用钱包内默认底图)。
卡劵包大小应小于150KB,否则无法添加。
卡券包在华为钱包的存储采用文件形式,每个卡劵包都需要遵循相同的格式,整个文件采用zip压缩,文件后缀命名为.hwpass,文件名字字符只允许“a-z”,“A-Z”,“0-9”,“_”。
卡劵包组成:
文件名 | 文件描述 | 必选/可选 | 格式要求 | 备注(以电影票为例) |
hwpass.json | 卡券数据文件 | 必选 | 取票号、影院、场次、座位、联系电话等变量由华为根据hwpass.json来填充 | |
signature | 签名文件 | 必选 | ||
manifest.json | 对包中各文件的SHA256的Hash值 | 必选 | ||
home.png | 首页展示图片 | 可选 | 图片大小的要求: 规格:320*200px 大小:小于等于25kb | 商户商标、影片图片、影片上固定文字,可以采用本图片展示; 影片失效后,需要生成新的home.png;通过更新pass压缩包来实现 |
detail.png | 详情页展示图片 | 可选 | 图片大小的要求: 规格:656*405px 大小:小于等于40kb | 商户商标、影片图片、影片上固定文字,可以采用本图片展示; 影片失效后,需要生成新的detail.png;通过更新pass压缩包来实现 |
home@2x.png | 大屏展示时首页图片 | 可选 | 图片大小的要求: 规格:480*300px 大小:小于等于 25kb | 商户商标、影片图片、影片上固定文字,可以采用本图片展示; 影片失效后,需要生成新的home@2x.png;通过更新pass压缩包来实现 |
detail@2x.png | 大屏展示时详情页图片 | 可选 | 图片大小的要求: 规格:984*608px 大小:小于等于40kb | 商户商标、影片图片、影片上固定文字,可以采用本图片展示; 影片失效后,需要生成新的detail@2x.png;通过更新pass压缩包来实现 |
hwpass.json定义:
段名 | 备注 | 示例 | 必选/可选 |
formatVersion | 目前固定填写1.0 | 1.0 | 必选 |
passTypeIdentifier | 在开发者联盟注册的卡券类型Id; | hwpass.membership.hotel | 必选 |
passStyleIdentifier | 卡券在钱包的展示样式定义,目前以华为提供的为准,后续展示部分开放定制后可以在开发者联盟上注册对应卡券类型id的时候注册展示样式;建议和 passTypeIdentifier保持一致 | hwpass.membership.hotel | 必选 |
passesUpdateSince | 用于手机端侧与发卡系统交互,获取pass更新列表接口时作为参数传递给第三方,第三方根据此参数拿取最新的Pass包给钱包端测 | 414994617 | 必选 |
organizationName | 展示在卡券上的发行机构名称; | XX酒店会员卡 | 必选 |
organizationPassId | 具体的卡券号; | E15285WF65 | 必选 |
webServiceURL | 用于手机端侧与发卡系统交互,交互链接地址 | http://www.XXX.com/ download/pass | 必选 |
authorizationToken | 用于手机端侧与发卡系统交互,鉴权token | ae13d3bsdfsfwwd7f9a4a5235f10803c09 | 必选 |
serialNumber | 用于手机端侧与发卡系统交互,建议与 organizationPassId不相同,防止卡号泄露 | 8a452215a35855dsffgwfce3aa94bbee | 必选 |
fields.commonFields | 对于某种类型的卡券的必备展示字段 | { "key": "name", "label": "名称", "value": "XXX" } | 必选 |
fields.appendFields | 对于某种类型的卡券的可选展示字段 | { "key": "detail", "label": "详细信息", "value": "http://xxx" } | 可选 |
commonFields、appendFields区域,至少有一个区域有值。
commonFields、appendFields区域规则:
字段名 | 字段描述 | 示例 | 可空 |
Key | 字段关键字 | name | 不可 |
label | 字段名称 | 名称 | 不可 |
value | 字段值 | XXX国际酒店 | 不可 |
- // 使用证书和私钥生成PassFileService用于生成签名卡劵包
- public PassFileService getPassFileService(Properties properties, String passKeyPrefix) {
- PassCertificateService passCertificateService = new PassCertificateService() {
- @Override
- public byte[] getCertificateByPassType(String passTypeIdentifier) {
- String property = properties.getProperty(passKeyPrefix + "certificate." + passTypeIdentifier, "");
- return Base64.decodeBase64(property);
- }
- @Override
- public byte[] getPrivateKeyByPassType(String passTypeIdentifier) {
- String property = properties.getProperty(passKeyPrefix + "privatekey." + passTypeIdentifier, "");
- return Base64.decodeBase64(property);
- }
- @Override
- public byte[] getPassCACertificate() {
- String property = properties.getProperty(passKeyPrefix + "ca", "");
- return Base64.decodeBase64(property);
- }
- PassFileService passFileService = new PassFileServiceImpl(passCertificateService);
- return passFileService;
- }
- }
- // 生成签名卡劵包
- public byte[] createRandomPass(String passType, PassFileService passFileService) throws IOException, NoSuchAlgorithmException, PassException, CertificateException, InvalidKeySpecException,InvalidKeyException, SignatureException, NoSuchProviderException {
- String passNumber = utilService.getCompressUUID();
- ObjectNode passJson = JsonNodeFactory.instance.objectNode();
- passJson.put("passTypeIdentifier", "hwpass.com.huawei.wallet.pass.sdktest");
- passJson.put("passStyleIdentifier", "hwpass.com.huawei.wallet.pass.sdktest");
- passJson.put("organizationName", "Business Name");
- passJson.put("organizationPassId", "passPackage unique value");
- passJson.put("webServiceURL", "Card update interface webServiceURL");
- passJson.put("authorizationToken", "Card update interface token");
- passJson.put("serialNumber", "Card update interface serialNumber");
- // fields中放入各商户卡劵对应显示字段
- ObjectNode fieldsPassJson = JsonNodeFactory.instance.objectNode();
- passJson.put("fields", fieldsPassJson);
- // 如果涉及到图片资源,请将图片资源放到fileMap中
- Map<String, byte[]> fileMap = new HashMap<String, byte[]>();
- byte[] signBytes = passFileService.createPass(fileMap, passJson);
- return signBytes;
- }
商户应用向商户服务器请求到卡劵包后将其做Base64加密后,通过SDK的接口推送给华为钱包。
商户App将已签名过的卡劵包推送给华为钱包,钱包会对接收到的卡劵包进行验签操作,验签通过后将卡劵包保存至钱包应用,用户可打开钱包卡包界面进行查看。
- //createRandomPass()为服务器生成卡劵包接口
- String base64ZipData= Base64.encode(createRandomPass(),Base64.NO_WRAP);
- // addPass(String base64ZipData)添加卡券包接口
- WalletPassApiResponse response = mWalletPassApi.addPass(base64ZipData);