Unity 华为HMS/AGC SDK集成简介(以接入华为广告变现服务为例)
内容概述中国Unity封装了基于华为HMS/AGC服务的SDK,对于移动端项目开发,可以直接在Unity工程中集成使用各种华为功能,所构建出的安卓包可以使用户直接调用各种华为服务,以此打造高品质应用与体验。希望其效率与便捷性将能使开发工作变得更轻松!SDK下载地址:https://assetstore.unity.com/packages/add-ons/services/huawei-hms-a
·
内容概述
中国Unity封装了基于华为HMS/AGC服务的SDK,对于移动端项目开发,可以直接在Unity工程中集成使用各种华为功能,所构建出的安卓包可以使用户直接调用各种华为服务,以此打造高品质应用与体验。希望其效率与便捷性将能使开发工作变得更轻松!
SDK下载地址:
SDK功能涵盖:
目前Unity程序包中各服务对应的类、函数名称、以及用法均与华为保持一致,目前阶段所涵盖的华为服务具体包括:
1. 华为HMS:
App服务类(Ads广告变现、Analytics分析、GameService游戏服务、Location定位、Push推送)
2. 华为AGC:
开发类(AuthServices认证、CloudFunctions云函数、CloudDB云数据库、CloudStorage云存储)
质量类(Crash崩溃服务、APM性能管理)
增长类(RemoteConfiguration远程配置、AppLinking应用链接、AppMessaging应用内消息)
三步集成SDK:
使用方法为下载程序包并导入到Unity项目中进行开发。由于存在的差异,在开发过程中仍然需要进行简单的配置与代码添加,以最终完成对具体服务的集成。以下以实现对华为广告流量变现服务(Ads)的集成为例,分为三部分进行介绍,分别是:
一,华为账号设置 二,Unity项目设置 三,SDK集成开发

一,华为账号设置
首先需要为集成华为服务进行所需的账号服务的开通与配置。
-
开发者联盟账号注册及实名认证
-
开通商户服务
-
创建应用
-
开通API服务
-
签署《华为Ads 媒体服务协议》
-
添加媒体
-
添加广告位并获取广告ID
1,开发者联盟账号注册及实名认证
登录 华为开发者联盟 ,创建华为开发者账号,以及完成实名认证。参考华为文档: https://developer.huawei.com/consumer/cn/doc/distribution/monetize/registration-0000001061752683

2,开通商户服务
填写信息并开通华为商户服务。参考华为文档: https://developer.huawei.com/consumer/cn/doc/start/merchant-service-0000001053025967

3,创建应用
登录 华为开发者联盟 ,点击"管理中心",在AppGallery Connect控制台页面上创建项目,以及创建应用。创建成功后,自动跳转到对应的应用信息页面,在此页面你可以看到系统分发给此应用的APP ID和SecretKey等信息。

4,开通API服务
在项目的应用信息页面,选择API管理页签,根据实际需要选择打开对应API服务。

5,签署《华为Ads 媒体服务协议》
需要注意境内或境外身份开发主体对于使用广告服务的区别与限制!

6,添加媒体
登录 华为流量变现服务平台 ,在创建的应用添加媒体

7,添加广告位并获取广告ID
目前Unity华为服务SDK中支持的广告形式为“Rewarded Ads激励式广告”和“Interstitial插播式广告”两种,请根据对华为广告位形式的需求添加广告位。并获得广告位ID。





至此,成功获取上述广告位ID。请注意:此正式广告ID将用于后续的SDK集成开发中。
以上Unity所整理的华为步骤,也可以直接到华为开发者社区参考华为文档: https://developer.huawei.com/consumer/cn/doc/distribution/monetize/process-0000001062698798
二,Unity项目设置
为你的Unity项目设置构建环境,并为华为 SDK配置仓库及依赖包。
-
创建模版
-
设置模版
-
生成签名证书
-
生成签名证书指纹
-
回到华为添加指纹证书
-
下载并添加Agconnect-services.json 到Unity项目
-
设置构建包名,及其他设置
1,创建模版
首先,确保你的Unity项目构建平台切换为安卓平台:
Editor -> Build Settings -> Platform -> Andriod -> Switch Platform//切换到安卓平台
可选项:这个时候也可以选择连上你的华为手机进行调试(手机打开开发者模式,以及USB调试)Run device
--
>
选择测试设备

2,设置模版
其次,完成以下构建环境的设置:
Edit -> Project Settings -> Player -> Android(icon) -> Publishing Settings -> Build -> 勾选以下环境配置项目:
-
Custom Main Manifest --> AndriodManifest.xml
-
Custom Launcher Manifest --> LauncherManifest.xml
-
Custom Main Gradle Template --> mainTemplate.gradle
-
Custom Launcher Gradle Template --> launcherTemplate.gradle
-
Custom Base Grade Template --> baseProjectTemplate.gradle

在Publishing Setting中勾选后,这些文件将自动出现在Unity项目文件夹中,项目文件夹路径为:
Project -> Assets -> Plugins -> Android ->
分别找到这些文件,并对它们进行以下代码修改配置:
1, AndroidManifest.xml
<
?
xml
version
=
"1.0"
encoding
=
"utf-8"
?
>
<
!
--
GENERATED BY UNITY
.
REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN
--
>
<
manifest
xmlns
:
android
=
"http://schemas.android.com/apk/res/android"
package
=
"com.unity3d.player"
xmlns
:
tools
=
"http://schemas.android.com/tools"
>
<
application
>
<
activity
android
:
name
=
"com.unity3d.player.UnityPlayerActivity"
android
:
theme
=
"@style/UnityThemeSelector"
>
<
intent
-
filter
>
<
action
android
:
name
=
"android.intent.action.MAIN"
/
>
<
category
android
:
name
=
"android.intent.category.LAUNCHER"
/
>
<
/
intent
-
filter
>
<
meta
-
data
android
:
name
=
"unityplayer.UnityActivity"
android
:
value
=
"true"
/
>
<
/
activity
>
<
/
application
>
<
/
manifest
>
P.S. 调用Push 和Location SDK请 参考文档 添加其他代码
2, LauncherManifest.xml
<
?
xml
version
=
"1.0"
encoding
=
"utf-8"
?
>
<
!
--
GENERATED BY UNITY
.
REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN
--
>
<
manifest
xmlns
:
android
=
"http://schemas.android.com/apk/res/android"
package
=
"com.unity3d.player"
xmlns
:
tools
=
"http://schemas.android.com/tools"
android
:
installLocation
=
"preferExternal"
>
<
supports
-
screens
android
:
smallScreens
=
"true"
android
:
normalScreens
=
"true"
android
:
largeScreens
=
"true"
android
:
xlargeScreens
=
"true"
android
:
anyDensity
=
"true"
/
>
<
application
android
:
extractNativeLibs
=
"true"
android
:
label
=
"@string/app_name"
android
:
icon
=
"@mipmap/app_icon"
/
>
<
/
manifest
>
3,mainTemplete.gradle
// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN
apply
plugin
:
'com
.
android
.
library'
*
*
APPLY_PLUGINS
*
*
dependencies
{
implementation
fileTree
(
dir
:
'libs'
,
include
:
[
'
*
.
jar'
]
)
implementation 'com
.
huawei
.
hms
:
hianalytics
:
5.0
.0
.301
'
implementation 'com
.
huawei
.
agconnect
:
agconnect
-
core
:
1.2
.0
.300
'
implementation 'com
.
huawei
.
hms
:
base
:
4.0
.1
.300
'
implementation 'com
.
huawei
.
hms
:
hwid
:
4.0
.1
.300
'
implementation 'com
.
huawei
.
hms
:
game
:
4.0
.1
.300
'
*
*
DEPS
*
*
}
android
{
compileSdkVersion
*
*
APIVERSION
*
*
buildToolsVersion '
*
*
BUILDTOOLS
*
*
'
compileOptions
{
sourceCompatibility JavaVersion
.
VERSION_1_8
targetCompatibility JavaVersion
.
VERSION_1_8
}
defaultConfig
{
minSdkVersion
*
*
MINSDKVERSION
*
*
targetSdkVersion
*
*
TARGETSDKVERSION
*
*
ndk
{
abiFilters
*
*
ABIFILTERS
*
*
}
versionCode
*
*
VERSIONCODE
*
*
versionName '
*
*
VERSIONNAME
*
*
'
consumerProguardFiles 'proguard
-
unity
.
txt'
*
*
USER_PROGUARD
*
*
}
lintOptions
{
abortOnError
false
}
aaptOptions
{
noCompress
=
[
'
.
ress'
,
'
.
resource'
,
'
.
obb'
]
+
unityStreamingAssets
.
tokenize
(
'
,
'
)
ignoreAssetsPattern
=
"!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~"
}
*
*
PACKAGING_OPTIONS
*
*
}
*
*
REPOSITORIES
*
*
*
*
IL_CPP_BUILD_SETUP
*
*
*
*
SOURCE_BUILD_SETUP
*
*
*
*
EXTERNAL_SOURCES
*
*
4,launcherTemplate.gradle
// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN
apply
plugin
:
'com
.
android
.
application'
dependencies
{
implementation
project
(
'
:
unityLibrary'
)
implementation 'com
.
huawei
.
hms
:
ads
-
lite
:
13.4
.29
.303
'
implementation 'com
.
huawei
.
hms
:
ads
-
consent
:
3.4
.30
.301
'
implementation 'com
.
huawei
.
hms
:
push
:
4.0
.3
.301
'
implementation 'com
.
huawei
.
hms
:
hianalytics
:
5.1
.0
.300
'
implementation 'com
.
android
.
support
:
appcompat
-
v7
:
28.0
.0
'
implementation 'com
.
huawei
.
hms
:
hianalytics
:
5.0
.0
.301
'
implementation 'com
.
huawei
.
agconnect
:
agconnect
-
core
:
1.2
.0
.300
'
implementation 'com
.
huawei
.
hms
:
base
:
4.0
.1
.300
'
implementation 'com
.
huawei
.
hms
:
hwid
:
4.0
.1
.300
'
implementation 'com
.
huawei
.
hms
:
game
:
4.0
.1
.300
'
implementation 'com
.
huawei
.
hms
:
location
:
4.0
.3
.301
'
}
android
{
compileSdkVersion
*
*
APIVERSION
*
*
buildToolsVersion '
*
*
BUILDTOOLS
*
*
'
compileOptions
{
sourceCompatibility JavaVersion
.
VERSION_1_8
targetCompatibility JavaVersion
.
VERSION_1_8
}
defaultConfig
{
minSdkVersion
*
*
MINSDKVERSION
*
*
targetSdkVersion
*
*
TARGETSDKVERSION
*
*
applicationId '
*
*
APPLICATIONID
*
*
'
ndk
{
abiFilters
*
*
ABIFILTERS
*
*
}
versionCode
*
*
VERSIONCODE
*
*
versionName '
*
*
VERSIONNAME
*
*
'
}
aaptOptions
{
noCompress
=
[
'
.
ress'
,
'
.
resource'
,
'
.
obb'
]
+
unityStreamingAssets
.
tokenize
(
'
,
'
)
ignoreAssetsPattern
=
"!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~"
}
*
*
SIGN
*
*
lintOptions
{
abortOnError
false
}
buildTypes
{
debug
{
minifyEnabled
*
*
MINIFY_DEBUG
*
*
proguardFiles
getDefaultProguardFile
(
'proguard
-
android
.
txt'
)
*
*
SIGNCONFIG
*
*
jniDebuggable
true
}
release
{
minifyEnabled
*
*
MINIFY_RELEASE
*
*
proguardFiles
getDefaultProguardFile
(
'proguard
-
android
.
txt'
)
*
*
SIGNCONFIG
*
*
}
}
*
*
PACKAGING_OPTIONS
*
*
*
*
SPLITS
*
*
*
*
BUILT_APK_LOCATION
*
*
bundle
{
language
{
enableSplit
=
false
}
density
{
enableSplit
=
false
}
abi
{
enableSplit
=
true
}
}
}
*
*
SPLITS_VERSION_CODE
*
*
*
*
LAUNCHER_SOURCE_BUILD_SETUP
*
*
5,baseProjectTemplate.gradle
// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN
allprojects
{
buildscript
{
repositories
{
*
*
ARTIFACTORYREPOSITORY
*
*
google
(
)
jcenter
(
)
maven
{
url 'https
:
/
/
developer
.
huawei
.
com
/
repo
/
'
}
}
dependencies
{
// If you are changing the Android Gradle Plugin version, make sure it is compatible with the Gradle version preinstalled with Unity
// See which Gradle version is preinstalled with Unity here https://docs.unity3d.com/Manual/android-gradle-overview.html
// See official Gradle and Android Gradle Plugin compatibility table here https://developer.android.com/studio/releases/gradle-plugin#updating-gradle
// To specify a custom Gradle version in Unity, go do "Preferences > External Tools", uncheck "Gradle Installed with Unity (recommended)" and specify a path to a custom Gradle version
classpath 'com
.
android
.
tools
.
build
:
gradle
:
3.6
.0
'
classpath 'com
.
huawei
.
agconnect
:
agcp
:
1.2
.1
.301
'
*
*
BUILD_SCRIPT_DEPS
*
*
}
}
repositories
{
*
*
ARTIFACTORYREPOSITORY
*
*
google
(
)
jcenter
(
)
flatDir
{
dirs
"${project(':unityLibrary').projectDir}/libs"
}
maven
{
url 'https
:
/
/
developer
.
huawei
.
com
/
repo
/
'
}
}
}
task
clean
(
type
:
Delete
)
{
delete rootProject
.
buildDir
}
3,生成签名证书
在本流程中,可利用Unity编辑器来生成签名证书
Keytore... -> create new
注意:
生成并记住证书保存的路径,稍后将需要文件路径创建签名证书指纹!
设定并记住密码,并在最终构建前需要输入密码,否则无法成功构建!

4,生成签名证书指纹
在命令窗口,通过Keytool工具以及签名文件保存路径下的签名文件及验证密码,导出SHA256指纹。
Windows:
打开命令窗口,在安装JDK的bin目录下运行,输入keytool查看签名文件指令,并运行。 keytool -list -v -keystore D:\Android\WorkSpcae\HmsDemo\app\HmsDemo.jks 在信息中输入签名文件密钥库口令(口令即生成签名文件时的Password) 获取对应SHA256指纹。
MacOS:
在Terminal终端输入keytool查看签名文件指令,并运行。 keytool -list -v -keystore /Users/admin/Downloads/HmsDemo.jks 在信息中输入签名文件密钥库口令(口令即生成签名文件时的Password)。 获取对应SHA256指纹。
参照华为 HMS Core集成准备 Step4 生成SHA256证书指纹

生成/配置签名证书以及指纹的详情,可参考华为文档说明: https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#2
5,回到华为添加指纹证书
参照华为 HMS Core集成准备 Step5 在AppGAllery Connect里添加指纹。

6,下载并添加Agconnect-services.json 到Unity项目

下载 agconnect-services 的json文件
从华为开发者账号内下载此json 文件后,在其中加入以下信息。
"agcgw"
:
{
"backurl"
:
"connect-drcn.dbankcloud.cn"
,
"url"
:
"connect-drcn.hispace.hicloud.com"
}
,
加入所需信息后,放回到Unity项目中此文件夹路径之下
Assets/Plugins/Android
7,设置构建包名,及其他设置
Edit -> Project Settings -> Player
构建的包名由如下组成 com.${Company Name}.${Product Name} 同时也可以在此步骤完成其余的所需设置,比如您的应用版本号、应用的图标、设置显示的分辨率等……

备注:Get Activity 如果需要在项目中调用华为函数,可使用
Common
.
GetActivity
(
)
三,SDK集成开发
本程序包中目前集成华为广告服务的广告形式有两种,分别为“Rewarded Ads激励式广告” 和 “Interstitial插播式广告”。最终完成我们将需要完成:
-
创建广告的点击入口
-
获取广告
-
展示广告
-
更多华为广告Api功能的调用
-
挂载脚本到广告位
-
打包运行并完成效果测试
-
申请上架
1,创建广告的点击入口
我们以一个最简单的Unity Roll a Ball项目为例。当玩家失败后可通过点击观看广告获得生命。
在Canvas分别创建“Rewarded Ads激励式广告”(视频广告)和“Interstitial插播式广告”(图像广告)两个Button按钮式 广告位入口。

2,获取广告
用loadAd()方法来获取广告 用你之前在华为账号内获取的真实广告ID替换代码中的测试ID
using
UnityEngine
;
using
HuaweiService
;
using
HuaweiService
.
ads
;
//获取华为图片广告
public
void
LoadImageAds
(
)
{
InterstitialAd
ad
=
new
InterstitialAd
(
new
Context
(
)
)
;
ad
.
setAdId
(
"teste9ih9j0rc3"
)
;
//此处为测试广告ID
ad
.
setAdListener
(
new
MAdListener
(
ad
)
)
;
AdParam
.
Builder
builder
=
new
AdParam
.
Builder
(
)
;
AdParam
adParam
=
builder
.
build
(
)
;
ad
.
loadAd
(
adParam
)
;
}
//获取华为视频广告
public
void
LoadVideoAds
(
)
{
InterstitialAd
ad
=
new
InterstitialAd
(
new
Context
(
)
)
;
ad
.
setAdId
(
"testb4znbuh3n2"
)
;
//此处为测试广告ID
ad
.
setAdListener
(
new
MAdListener
(
ad
)
)
;
AdParam
.
Builder
builder
=
new
AdParam
.
Builder
(
)
;
ad
.
loadAd
(
builder
.
build
(
)
)
;
}
//获取华为激励式广告
public
void
LoadRewardAds
(
)
{
RewardAd
ad
=
new
RewardAd
(
new
Context
(
)
,
"testx9dtjwj8hp"
)
;
//此处为测试广告ID
AdParam
adParam
=
new
AdParam
.
Builder
(
)
.
build
(
)
;
MRewardLoadListener
rewardAdLoadListener
=
new
MRewardLoadListener
(
ad
)
;
ad
.
loadAd
(
adParam
,
rewardAdLoadListener
)
;
}
3,监听广告事件
通过实现AdListener类中的方法来监听广告事件
using
HuaweiService
;
using
HuaweiService
.
ads
;
namespace
HuaweiServiceDemo
{
public
partial
class
Util
{
public
static
void
showToast
(
string
message
)
{
Toast
.
makeText
(
new
Context
(
)
,
message
,
Toast
.
LENGTH_SHORT
)
.
show
(
)
;
}
}
public
class
MAdListener
:
AdListener
{
private
InterstitialAd
ad
;
public
MAdListener
(
InterstitialAd
_ad
)
:
base
(
)
{
ad
=
_ad
;
}
public
override
void
onAdLoaded
(
)
{
Util
.
showToast
(
"AdListener onAdLoaded"
)
;
TestTip
.
Inst
.
ShowText
(
"AdListener onAdLoaded"
)
;
ad
.
show
(
)
;
}
public
override
void
onAdFailed
(
int
arg0
)
{
Util
.
showToast
(
$"Ad failed to load with error code
{
arg0
}
."
)
;
}
public
override
void
onAdOpened
(
)
{
Util
.
showToast
(
"Ad Opened"
)
;
}
public
override
void
onAdClicked
(
)
{
Util
.
showToast
(
"Ad Clicked"
)
;
}
public
override
void
onAdLeave
(
)
{
Util
.
showToast
(
"Ad Leave"
)
;
}
public
override
void
onAdClosed
(
)
{
Util
.
showToast
(
"Ad Closed"
)
;
}
}
public
class
MRewardLoadListener
:
RewardAdLoadListener
{
private
RewardAd
ad
;
public
MRewardLoadListener
(
RewardAd
_ad
)
{
ad
=
_ad
;
}
public
override
void
onRewardAdFailedToLoad
(
int
errorCode
)
{
Util
.
showToast
(
"RewardAdLoadListener onRewardAdFailedToLoad "
+
errorCode
)
;
TestTip
.
Inst
.
ShowText
(
"RewardAdLoadListener onRewardAdFailedToLoad "
+
errorCode
)
;
}
public
override
void
onRewardedLoaded
(
)
{
Util
.
showToast
(
"RewardAdLoadListener onRewardedLoaded"
)
;
TestTip
.
Inst
.
ShowText
(
"RewardAdLoadListener onRewardedLoaded"
)
;
ad
.
show
(
new
Context
(
)
,
new
MRewardAdStatusListener
(
)
)
;
}
}
4,更多高级Api功能的调用
//基于受众人群的设置
public
void
setRequestOptionsNonPersonalizedAd
(
)
{
RequestOptions
reqOptions
=
HwAds
.
getRequestOptions
(
)
.
toBuilder
(
)
.
setNonPersonalizedAd
(
new
Integer
(
NonPersonalizedAd
.
ALLOW_ALL
)
)
.
build
(
)
;
HwAds
.
setRequestOptions
(
reqOptions
)
;
TestTip
.
Inst
.
ShowText
(
"RequestOptions NonPersonalizedAd:"
+
HwAds
.
getRequestOptions
(
)
.
getNonPersonalizedAd
(
)
)
;
}
//征求用户意见获取广告
public
void
SetConsentStatus
(
bool
personal
)
{
Consent
consentInfo
=
Consent
.
getInstance
(
new
Context
(
)
)
;
var
consentStatus
=
personal
?
ConsentStatus
.
PERSONALIZED
:
ConsentStatus
.
NON_PERSONALIZED
;
consentInfo
.
setConsentStatus
(
consentStatus
)
;
Util
.
showToast
(
$"set consent status as
{
consentStatus
}
"
)
;
}
//更新用户意见状态
public
void
checkConsentStatus
(
)
{
Consent
consentInfo
=
Consent
.
getInstance
(
new
Context
(
)
)
;
consentInfo
.
requestConsentUpdate
(
new
MConsentUpdateListener
(
)
)
;
}
5,挂载脚本到广告位
-
选中Canvas上的“Interstitial插播式广告”广告位(举例:HuaweiImageAds)
-
将上述脚本挂载上去(举例:RewardedAdsButton)
-
在Button的OnClick() 上定义调用上述脚本以及脚本内对应的函数(举例:LoadImageAds() )

“Rewarded Ads激励式广告”广告位(举例:HuaweiVideoAds)脚本挂载方法同上!

6,打包运行并完成效果测试
输入签名证书Key及密码
Project Settings --> Player --> Publish Settings

Build and run并得到APK

确认SDK集成效果:





7,申请上架
至此,你的移动应用APK内已集成了华为广告流量变现服务。
接下来,请参考华为文档,对应用进行上架前的确认,并申请上架。祝您成功! https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/pre-release-check-0000001050064994

辅助信息:
关于其他华为HMS / AGC 服务的基本集成步骤,请参阅以下Unity在线文档进行代码编写并完成SDK的集成: https://docs.unity.cn/cn/Packages-cn/com.unity.huaweiservice@1.3/manual/index_cn.html
同时,强烈建议下载中国Unity在Github上的开源示例项目,根据其中所需集成的具体服务进行参考: https://github.com/Unity-Technologies/HuaweiServiceSample 在示例项目中,对应的场景是:
Assets/HuaweiServiceDemo/Scenes/HmsAdsSampleScene.unity
而对应的代码是:
Assets/HuaweiServiceDemo/demo/test/ads/AdsTest.cs
更多推荐
所有评论(0)