Unity接入华为SDK
文章目录
- 一、sdk下载
- 二、编写java中间件,打成jar包
- 三、Unity部分
- 四、登录错误码
- 五、支付错误码
- 六、问题与解答
- 七、华为自检工具检查易见情况
- 八、开发者账号相关
- 1、如何查看APPID、APPKEY、APP SECRET等参数
- 2、如何查看CPID、支付公钥、支付私钥等参数
- 3、如何查看应用的游戏公钥和游戏私钥
- 4、如何配置应用内商品
有同学要Unity demo,于是写了一个
https://download.csdn.net/download/linxinfa/11939660
一、sdk下载
https://developer.huawei.com/consumer/cn/doc/overview/HMS-2-0
华为文档查询: https://developer.huawei.com/consumer/cn/doc/search
比如要查询login接口
下载HMSAgent_2.6.3.301.zip
我用的是Eclipse工程,所以下载hmssdk-eclipse-2.6.3.301.zip
二、编写java中间件,打成jar包
解压上面的两个zip
,进入HMSAgent_2.6.3.301
目录
看到文档里说要执行Buildcopysrc2jar.bat来生成jar,但是过程中一堆问题,放弃治疗,不走华为文档里说的那套
它其实就是把HMSAgent
的java
代码和sdk
的jar
包打成一个jar包,跟着我说的步骤搞即可。
1 打开eclipse
,新建Android
工程,包名注意和Unity工程的包名相同,假设叫com.linxinfa.sdktest.huawei
(注:华为要求必须以.huawei
结尾)
2 右键工程,点击Properties
,点击Java Build Path/Libraries/Add External JARS...
,添加Unity的classes.jar
classes.jar所在位置:Unity安装目录\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes\classes.jar
3 添加hmssdk-eclipse-2.6.3.301
中各个模块的libs
中的jar
4 把HMSAgent_2.6.3.301/hmsagents/src/main/java/com
目录拷贝到我们的Android
工程的src
中
5 新建一个MyApplication.java
// 注意包名要以.huawei结尾
package com.linxinfa.sdktest.huawei;import android.app.Application;import com.huawei.android.hms.agent.HMSAgent;/*** application类 | application class*/
public class MyApplication extends Application {@Overridepublic void onCreate() {super.onCreate();HMSAgent.init(this);}@Overridepublic void onTerminate() {super.onTerminate();HMSAgent.destroy();}
}
6 修改MainActivity.java
,封装接口供c#
调用,注意要继承UnityPlayerActivity
package com.linxinfa.sdktest.huawei;import java.security.SecureRandom;
import java.text.DateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;import org.json.JSONObject;import android.content.SharedPreferences;
import android.os.Bundle;import com.huawei.android.hms.agent.HMSAgent;
import com.huawei.android.hms.agent.common.handler.CheckUpdateHandler;
import com.huawei.android.hms.agent.common.handler.ConnectHandler;
import com.huawei.android.hms.agent.game.GameLoginSignUtil;
import com.huawei.android.hms.agent.game.handler.ICheckLoginSignHandler;
import com.huawei.android.hms.agent.game.handler.LoginHandler;
import com.huawei.android.hms.agent.game.handler.SaveInfoHandler;
import com.huawei.android.hms.agent.pay.PaySignUtil;
import com.huawei.android.hms.agent.pay.handler.GetOrderHandler;
import com.huawei.android.hms.agent.pay.handler.GetProductDetailsHandler;
import com.huawei.android.hms.agent.pay.handler.GetPurchaseInfoHandler;
import com.huawei.android.hms.agent.pay.handler.ProductPayHandler;
import com.huawei.hms.support.api.entity.game.GamePlayerInfo;
import com.huawei.hms.support.api.entity.game.GameUserData;
import com.huawei.hms.support.api.entity.pay.OrderRequest;
import com.huawei.hms.support.api.entity.pay.PayStatusCodes;
import com.huawei.hms.support.api.entity.pay.ProductDetail;
import com.huawei.hms.support.api.entity.pay.ProductDetailRequest;
import com.huawei.hms.support.api.entity.pay.ProductFailObject;
import com.huawei.hms.support.api.entity.pay.ProductPayRequest;
import com.huawei.hms.support.api.entity.pay.PurchaseInfo;
import com.huawei.hms.support.api.entity.pay.PurchaseInfoRequest;
import com.huawei.hms.support.api.pay.OrderResult;
import com.huawei.hms.support.api.pay.ProductDetailResult;
import com.huawei.hms.support.api.pay.ProductPayResultInfo;
import com.huawei.hms.support.api.pay.PurchaseInfoResult;
import com.huawei.android.hms.agent.HMSAgent;
import com.huawei.android.hms.agent.hwid.handler.SignInHandler;
import com.huawei.android.hms.agent.hwid.handler.SignOutHandler;
import com.huawei.hms.support.api.hwid.SignInHuaweiId;
import com.huawei.hms.support.api.hwid.SignOutResult;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;public class MainActivity extends UnityPlayerActivity {private static final String game_priv_key = IEvnValues.game_priv_key;private static final String game_public_key = IEvnValues.game_public_key;private static final String appId = IEvnValues.appId;private static final String cpId = IEvnValues.cpId;/*** 未确认支付缓存,key:requestId value:False | Unacknowledged payment cache,* Key:requestid Value:false*/private static final String UNCHECK_PAYREQUESTID_FILE = "pay_request_ids";// //@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Init();}// log传到c#端显示private void showLog(String text) {try {JSONObject jo = new JSONObject();jo.put("COMMAND", "LOG");jo.put("TEXT", text);UnityPlayer.UnitySendMessage("SdkCb", "OnSdkCb", jo.toString());} catch (Exception e) {// TODO: handle exception}}public void Init() {// 在首个界面,需要调用connect进行连接 | In the first page, you need to call connectHMSAgent.connect(this, new ConnectHandler() {@Overridepublic void onConnect(int rst) {showLog("HMS connect end:" + rst);}});HMSAgent.checkUpdate(this, new CheckUpdateHandler() {@Overridepublic void onResult(int rst) {showLog("check app update end:" + rst);}});}// 游戏登录接口,如果是游戏类型的应用接入华为帐号体系,则需要使用此游戏登录接口,该接口区别于HUAWEIId的signIn接口。public void Login() {showLog("game login: begin");HMSAgent.Game.login(new LoginHandler() {@Overridepublic void onResult(int retCode, GameUserData userData) {if (retCode == HMSAgent.AgentResultCode.HMSAGENT_SUCCESS&& userData != null) {showLog("game login: onResult: retCode=" + retCode+ " user=" + userData.getDisplayName() + "|"+ userData.getPlayerId() + "|"+ userData.getGameAuthSign() + "|"+ userData.getTs() + "|"+ userData.getIsAuth() + "|"+ userData.getPlayerLevel());// 当登录成功时,此方法会回调2次, | This method recalls 2 times when the// login is successful.// 第1次:只回调了playerid;特点:速度快;在要求快速登录,并且对安全要求不高时可以用此playerid登录// | 1th time: Only callback playerID; features: fast speed;// You can log in with this playerID when you require fast// logon and are not high on security requirements// 第2次:回调了所有信息,userData.getIsAuth()为1;此时需要对登录结果进行验签 | 2nd// time: Callback All information, Userdata.getisauth () is// 1;if (userData.getIsAuth() == 1) {// 如果需要对登录结果进行验签,请发送请求到开发者服务器进行(安全起见,私钥要放在服务端保存)。| If// you need to check your login results, send a request// to the developer server (for security, the private// key is stored on the service side).// 下面工具方法仅为了展示验签请求的逻辑,实际实现应该放在开发者服务端。| The following// tool method is intended only to show the logic of the// verification request, and the actual implementation// should be on the developer server.GameLoginSignUtil.checkLoginSign(appId, cpId,game_priv_key, game_public_key, userData,new ICheckLoginSignHandler() {@Overridepublic void onCheckResult(String code,String resultDesc,boolean isCheckSuccess) {showLog("game login check sign: onResult: retCode="+ code+ " resultDesc="+ resultDesc+ " isCheckSuccess="+ isCheckSuccess);}});}} else {showLog("game login: onResult: retCode=" + retCode);}}@Overridepublic void onChange() {// 此处帐号登录发生变化,需要重新登录 | Account login changed here, login// requiredshowLog("game login: login changed!");Login();}}, 1);}/*** 登录授权 | Login Authorization* @param forceLogin 如果已经授权登录则直接回调结果,否则:forceLogin为true时会拉起界面,为false时直接回调错误码 | If the login is authorized, the result is directly callback, otherwise: When Forcelogin is true, the activity is pulled and the error code is directly invoked when false*/public void SignIn(boolean forceLogin) {HMSAgent.Hwid.signIn(forceLogin, new SignInHandler() {@Overridepublic void onResult(int rtnCode, SignInHuaweiId signInResult) {if (rtnCode == HMSAgent.AgentResultCode.HMSAGENT_SUCCESS && signInResult != null) {//可以获取帐号的 openid,昵称,头像 at信息 | You can get the OpenID, nickname, Avatar, at etc information of Huawei IDshowLog("signIn successful=========");showLog("Nickname:" + signInResult.getDisplayName());showLog("openid:" + signInResult.getOpenId());showLog("accessToken:" + signInResult.getAccessToken());showLog("Head pic URL:" + signInResult.getPhotoUrl());showLog("unionID:" + signInResult.getUnionId());} else {showLog("signIn---error: " + rtnCode);}}});}/*** 退出。此接口调用后,下次再调用signIn会拉起界面,请谨慎调用。如果不确定就不要调用了。 | Exit。 After this method is called, the next time you call signIn will pull the activity, please call carefully. Do not call if you are unsure.*/public void SignOut(){HMSAgent.Hwid.signOut(new SignOutHandler() {@Overridepublic void onResult(int rtnCode, SignOutResult signOutResult) {if (rtnCode == HMSAgent.AgentResultCode.HMSAGENT_SUCCESS && signOutResult != null) {showLog("SignOut successful");} else {showLog("SignOut fail:" + rtnCode);}}});} /*** 游戏显示浮标示例 | Game Show Floating Indicator example*/public void showfloat() {showLog("game showfloat");HMSAgent.Game.showFloatWindow(this);}/*** 游戏隐藏浮标示例 | Game Hidden Floating Indicator example*/public void hidefloat() {showLog("game hidefloat");HMSAgent.Game.hideFloatWindow(this);}/*** 游戏保存玩家信息示例 | Game Save player Information sample*/public void savePlayerInfo() {showLog("game savePlayerInfo: begin");GamePlayerInfo gpi = new GamePlayerInfo();gpi.area = "20";gpi.rank = "level 56";gpi.role = "hunter";gpi.sociaty = "Red Cliff II";HMSAgent.Game.savePlayerInfo(gpi, new SaveInfoHandler() {@Overridepublic void onResult(int retCode) {showLog("game savePlayerInfo: onResult=" + retCode);}});}// /支付/*** PMS支付示例 | PMS Payment Example* 参数由服务器传给客户端*/public void pmsPay(String productNo, String applicationID, String requestId, String merchantId,String serviceCatalog,String merchantName,int sdkChannel,String url,String urlVer,String sign,String pay_pub_key) {showLog("PMS pay: begin");final String tmp_pay_pub_key = pay_pub_key;ProductPayRequest payReq = createProductPayReq(productNo, applicationID, requestId, merchantId, serviceCatalog, merchantName, sdkChannel, url, urlVer, sign);HMSAgent.Pay.productPay(payReq, new ProductPayHandler() {@Overridepublic void onResult(int retCode, ProductPayResultInfo payInfo) {if (retCode == HMSAgent.AgentResultCode.HMSAGENT_SUCCESS&& payInfo != null) {boolean checkRst = PaySignUtil.checkSign(payInfo,tmp_pay_pub_key);showLog("PMS pay: onResult: pay success and checksign="+ checkRst + "\n");if (checkRst) {// 支付成功并且验签成功,发放商品 | Payment successful and successful// verification, distribution of goods} else {// 签名失败,需要查询订单状态:对于没有服务器的单机应用,调用查询订单接口查询;其他应用到开发者服务器查询订单状态。|// Signature failed, need to query order status: For// stand-alone applications without servers, call Query// order interface query, other application to the// Developer Server query order status.}} else if (retCode == HMSAgent.AgentResultCode.ON_ACTIVITY_RESULT_ERROR|| retCode == PayStatusCodes.PAY_STATE_TIME_OUT|| retCode == PayStatusCodes.PAY_STATE_NET_ERROR) {showLog("PMS pay: onResult: need wait for result, rstcode="+ retCode + "\n");// 需要查询订单状态:对于没有服务器的单机应用,调用查询订单接口查询;其他应用到开发者服务器查询订单状态。| Need// to query order status: For stand-alone applications// without servers, call Query order interface query, other// application to Developer Server query order status.} else {showLog("PMS pay: onResult: pay fail=" + retCode + "\n");// 其他错误码意义参照支付api参考 | Other error code meaning reference// payment API reference}}});// 将requestid缓存,供查询订单 | RequestID Cache for Query orderaddRequestIdToCache(payReq.getRequestId());}public void addRequestIdToCache(String requestId) {SharedPreferences sp = getSharedPreferences("pay_request_ids", 0);sp.edit().putBoolean(requestId, false).commit();}public void removeCacheRequestId(String reqId) {SharedPreferences sp = getSharedPreferences("pay_request_ids", 0);sp.edit().remove(reqId).commit();}/*** 创建pms支付的请求对象 | Create a Request object for PMS payments* @param * productNo 商品编码* applicationID 应用ID* requestId 支付订单号* merchantId 商户ID* serviceCatalog 分类,游戏填"X6"* merchantName 商户名称* sdkChannel 渠道号,应用市场填1* url 支付回调地址* urlVer 回调接口版本号,固定填"2"* sign 签名* @return pms支付请求对象 | PMS Payment Request Object*/private static ProductPayRequest createProductPayReq(String productNo, String applicationID, String requestId, String merchantId,String serviceCatalog,String merchantName,int sdkChannel,String url,String urlVer,String sign) {ProductPayRequest payReq = new ProductPayRequest();// 商品编号 | productNopayReq.productNo = productNo;// 应用ID,来源于开发者联盟 | Application ID, from the Developer AlliancepayReq.applicationID = applicationID;// 支付订单号 | requestIdpayReq.requestId = requestId;// 商户ID,来源于开发者联盟,也叫“支付id”、“cpid” | Merchant ID, from the Developer// Alliance, also known as "Payment ID", "cpid"payReq.merchantId = merchantId;// 分类,必填,不参与签名。该字段会影响风控策略 | Categories, required, do not participate in// the signature. This field affects wind control policy// X4:主题,X5:应用商店, X6:游戏,X7:天际通,X8:云空间,X9:电子书,X10:华为学习,X11:音乐,X12 视频, |// X4: Theme, X5: App Store, X6: Games, X7: Sky Pass, X8: Cloud Space,// X9: ebook, X10: Huawei Learning, X11: Music, X12 video,// X31 话费充值,X32 机票/酒店,X33 电影票,X34 团购,X35 手机预购,X36 公共缴费,X39 流量充值 | X31,// X32 air tickets/hotels, X33 movie tickets, X34 Group purchase, X35// mobile phone advance, X36 public fees, X39 flow RechargepayReq.serviceCatalog = serviceCatalog;// 商户名称,必填,不参与签名。会显示在支付结果页面 | Merchant name, must be filled out, do not// participate in the signature. will appear on the Pay results pagepayReq.merchantName = merchantName;// 渠道号 | sdkChannelpayReq.sdkChannel = sdkChannel;// 支付结果回调地址。服务器异步通知页面路径// 华为服务器收到后检查该应用有无在开发者联盟配置回调URL,如果配置了则使用应用配置的URL,否则使用此url作为该次支付的回调URLpayReq.url = url;// 回调接口版本号 | Callback Interface Version numberpayReq.urlVer = urlVer;// 商户保留信息,选填不参与签名,支付成功后会华为支付平台会原样 回调CP服务端 | The merchant retains the// information, chooses not to participate in the signature, the payment// will be successful, the Huawei payment platform will be back to the// CP service//payReq.extReserved = "";// 对单机应用可以直接调用此方法对请求信息签名,非单机应用一定要在服务器端储存签名私钥,并在服务器端进行签名操作。| For// stand-alone applications, this method can be called directly to the// request information signature, not stand-alone application must store// the signature private key on the server side, and sign operation on// the server side.// 在服务端进行签名的cp可以将getStringForSign返回的待签名字符串传给服务端进行签名 | The CP, signed on// the server side, can pass the pending signature string returned by// Getstringforsign to the service side for signaturepayReq.sign = sign;return payReq;}
}
7 拷贝IEvnValues.java
到工程中,记得改下appid、cpid
等
注:IEvnValues.java
可以在华为sdk
示例工程找到,示例工程的链接在文章的开头那里有
// IEvnValues.java
package com.huawei.hmsagent;/*** 环境变量配置,私钥需要放在服务器端,这里只是给个处理示例 | environment variable configuration, the private key needs to be placed on the server side, here is just a sample processing*/
public interface IEvnValues {String game_priv_key = "xxx very long game private key xxx";String game_public_key = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD2zL2j7JsygP6k+0FX5ewrHmw1puikjhbdX1t2GWFAwjOiW4u+ycmvKvPs4ETjba1i7+M35nkiEI3wE2TP+GfMJLcE+5txkJ0sEOqIuvsYAgyZLwf64AoPcgQN50BZO8GFXuHmOG+8Z4nUa2A3/vvMHGWlVOo5ujkoTLj5j0tNIQIDAQAB";String pay_priv_key = "xxx very long pay private key xxx";String pay_pub_key = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIL/7zgG9KCjm5IeGFzq8oVaxCqFJ9+m/3rGMXU2p9K+bHLPR1m3c9TMZRGjkZbTZ0G/VLPO6BxiP+w+VM+Z3fECAwEAAQ==";String appId = "100204335";String cpId = "10086000000000293";
}
8 右键Android
工程的src
,Export
,导出成jar
,假设取名叫huawei_game_sdk.jar
三、Unity部分
1 把hmssdk
的各个jar
包和我们生成的huawei_game_sdk.jar
拷贝到Unity
工程中的Assets/Plugins/Android/libs
目录中
2 拷贝res资源
3 配置AndroidManifest.xml
AndroidManifest
建议拷贝Unity
的模板进行修改,在Unity安装目录\Editor\Data\PlaybackEngines\AndroidPlayer\Apk\
目录中
<?xml version="1.0" encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"package="com.unity3d.player"xmlns:tools="http://schemas.android.com/tools"android:installLocation="preferExternal"android:versionCode="1"android:versionName="1.0"><supports-screensandroid:smallScreens="true"android:normalScreens="true"android:largeScreens="true"android:xlargeScreens="true"android:anyDensity="true"/><applicationandroid:theme="@style/UnityThemeSelector"android:icon="@drawable/app_icon"android:label="@string/app_name"android:debuggable="true"><activity android:name="com.unity3d.player.UnityPlayerActivity"android:label="@string/app_name"><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>
参考sdk demo
的AndroidManifest.xml
,注意几个值的修改:
${PACKAGE_NAME}
替换成你的包名,比如com.linxinfa.sdktest.huawei
${HMSVERSION}
替换成sdk
版本号,比如2.6.3.301
${APPID}
替换成你在开发者账号上申请的应用的appid
${CPID}
替换成你在开发者账号上申请的支付的cpid
最后改成如下这样子:
<?xml version="1.0" encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"package="${PACKAGE_NAME}"xmlns:tools="http://schemas.android.com/tools"android:installLocation="preferExternal"android:versionCode="1"android:versionName="1.0"><!--HMS-SDK引导升级HMS功能,访问OTA服务器需要网络权限 | HMS-SDK upgrade HMS Feature, access to OTA server requires network privileges--><uses-permission android:name="android.permission.INTERNET" /><!--HMS-SDK引导升级HMS功能,保存下载的升级包需要SD卡写权限 | HMS-SDK upgrade HMS Feature, save downloaded upgrade pack requires SD card Write permission--><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><!--检测网络状态 | Detecting Network status--><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/><!--检测wifi状态 | Detecting WiFi status--><uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/><!--获取用户手机的IMEI,用来唯一的标识设备。 | Gets the IMEI of the user's phone, used to uniquely identify the device.--><uses-permission android:name="android.permission.READ_PHONE_STATE"/><!--如果是安卓8.0,应用编译配置的targetSdkVersion>=26,请务必添加以下权限 --><!--<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />--><supports-screensandroid:smallScreens="true"android:normalScreens="true"android:largeScreens="true"android:xlargeScreens="true"android:anyDensity="true"/><applicationandroid:name=".MyApplication"android:theme="@style/UnityThemeSelector"android:icon="@drawable/app_icon"android:label="@string/app_name"android:debuggable="true"><activity android:name=".MainActivity"android:label="@string/app_name"><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><!-- 接入 HMSSDK 配置依赖的HMS版本号 | Access HMSSDK configuration dependent HMS Version number--><meta-dataandroid:name="com.huawei.hms.version"android:value="${HMSVERSION}"/><!-- 接入HMSSDK 需要注册的appid参数。value的值中“${APPID}”用实际申请的appid替换,来源于开发者联盟网站应用的权益详情。格式 android:value="appid=xxxxxx"Access HMSSDK need to register AppID parameters. Value "${APPID}" is replaced with the actual application APPID, derived from the Developer affiliate website application.Format android:value= "appid=xxxxxx"--><meta-dataandroid:name="com.huawei.hms.client.appid"android:value="appid=${APPID}"/><!-- 接入HMSSDK 游戏或支付时需要注册的cpid参数。value的值中“${CPID}”用实际申请的应用cpID替换,来源于开发者联盟网站应用的权益详情。格式 android:value="cpid=xxxxxx"Cpid parameters that need to be registered to access HMSSDK games or payments. Value "${CPID}" is replaced with the application Cpid of the actual application, from the Developer affiliate website application.Format android:value="cpid=xxxxxx"--><meta-dataandroid:name="com.huawei.hms.client.cpid"android:value="cpid=${CPID}"/><!-- 接入HMSSDK 需要注册的provider,authorities 一定不能与其他应用一样,所以这边 ${PACKAGE_NAME} 要替换上您应用的包名Access HMSSDK need to register provider,authorities must not be the same as other applications, so this side ${package_name} to replace the package name you applied--><providerandroid:name="com.huawei.hms.update.provider.UpdateProvider"android:authorities="${PACKAGE_NAME}.hms.update.provider"android:exported="false"android:grantUriPermissions="true"/><!-- 接入HMSSDK 需要注册的provider,authorities 一定不能与其他应用一样,所以这边 ${PACKAGE_NAME} 要替换上您应用的包名Access HMSSDK need to register provider,authorities must not be the same as other applications, so this side ${package_name} to replace the package name you applied--><providerandroid:name="com.huawei.updatesdk.fileprovider.UpdateSdkFileProvider"android:authorities="${PACKAGE_NAME}.updateSdk.fileProvider"android:exported="false"android:grantUriPermissions="true"></provider><!-- 使用 HMSAgent 代码接入HMSSDK 需要注册的activity | Use hmsagent code to access HMSSDK activity that requires registration--><activityandroid:name="com.huawei.android.hms.agent.common.HMSAgentActivity"android:configChanges="orientation|locale|screenSize|layoutDirection|fontScale"android:excludeFromRecents="true"android:exported="false"android:hardwareAccelerated="true"android:theme="@android:style/Theme.Translucent" ><meta-dataandroid:name="hwc-theme"android:value="androidhwext:style/Theme.Emui.Translucent" /></activity><!-- 使用 HMSAgent 代码接入HMSSDK 游戏或支付模块时需要注册的activity | Activity to register when accessing HMSSDK game or payment module using hmsagent code--><activityandroid:name="com.huawei.android.hms.agent.pay.HMSPayAgentActivity"android:configChanges="orientation|locale|screenSize|layoutDirection|fontScale"android:excludeFromRecents="true"android:exported="false"android:hardwareAccelerated="true"android:theme="@android:style/Theme.Translucent" ><meta-dataandroid:name="hwc-theme"android:value="androidhwext:style/Theme.Emui.Translucent" /></activity><!-- 使用 HMSAgent 代码接入HMSSDK 游戏或支付模块时需要注册的activity | Activity to register when accessing HMSSDK game or payment module using hmsagent code--><activityandroid:name="com.huawei.android.hms.agent.pay.HMSPMSPayAgentActivity"android:configChanges="orientation|locale|screenSize|layoutDirection|fontScale"android:excludeFromRecents="true"android:exported="false"android:hardwareAccelerated="true"android:theme="@android:style/Theme.Translucent" ><meta-dataandroid:name="hwc-theme"android:value="androidhwext:style/Theme.Emui.Translucent" /></activity><!-- 使用 HMSAgent 代码接入HMSSDK 帐号模块时需要注册的activity | Activity to register when accessing HMSSDK account module using hmsagent code--><activityandroid:name="com.huawei.android.hms.agent.hwid.HMSSignInAgentActivity"android:configChanges="orientation|locale|screenSize|layoutDirection|fontScale"android:excludeFromRecents="true"android:exported="false"android:hardwareAccelerated="true"android:theme="@android:style/Theme.Translucent" ><meta-dataandroid:name="hwc-theme"android:value="androidhwext:style/Theme.Emui.Translucent" /></activity><!-- 接入HMSSDK 需要注册的activity | Access HMSSDK activity to be registered--><activityandroid:name="com.huawei.hms.activity.BridgeActivity"android:configChanges="orientation|locale|screenSize|layoutDirection|fontScale"android:excludeFromRecents="true"android:exported="false"android:hardwareAccelerated="true"android:theme="@android:style/Theme.Translucent" ><meta-dataandroid:name="hwc-theme"android:value="androidhwext:style/Theme.Emui.Translucent" /></activity><!-- 接入HMSSDK 需要注册的activity | Access HMSSDK activity to be registered--><activityandroid:name="com.huawei.updatesdk.service.otaupdate.AppUpdateActivity"android:configChanges="orientation|screenSize"android:exported="false"android:theme="@style/upsdkDlDialog" ><meta-dataandroid:name="hwc-theme"android:value="androidhwext:style/Theme.Emui.Translucent.NoTitleBar" /></activity><!-- 接入HMSSDK 需要注册的activity | Access HMSSDK activity to be registered--><activityandroid:name="com.huawei.updatesdk.support.pm.PackageInstallerActivity"android:configChanges="orientation|keyboardHidden|screenSize"android:exported="false"android:theme="@style/upsdkDlDialog" ><meta-dataandroid:name="hwc-theme"android:value="androidhwext:style/Theme.Emui.Translucent" /></activity><!-- 接入HMSSDK PUSH模块需要注册,第三方相关 :接收Push消息(注册、Push消息、Push连接状态)广播,此receiver类需要开发者自己创建并继承com.huawei.hms.support.api.push.PushReceiver类,参考示例代码中的类:com.huawei.hmsagent.HuaweiPushRevicerAccess to the HMSSDK push module requires registration:Receive push message (registration, push message, push connection state) broadcast.This receiver class requires the developer to create and inherit the com.huawei.hms.support.api.push.PushReceiver class.Reference to class in sample code: Com.huawei.hmsagent.HuaweiPushRevicer--><receiver android:name="com.huawei.hmsagent.HuaweiPushRevicer" ><intent-filter><!-- 必须,用于接收token | Must, for receiving token --><action android:name="com.huawei.android.push.intent.REGISTRATION" /><!-- 必须,用于接收消息 | Must, used to receive messages--><action android:name="com.huawei.android.push.intent.RECEIVE" /><!-- 可选,用于点击通知栏或通知栏上的按钮后触发onEvent回调 | Optional, click the button on the notification bar or the notification bar to trigger the onevent callback --><action android:name="com.huawei.android.push.intent.CLICK" /><!-- 可选,查看push通道是否连接,不查看则不需要 | Optional, query whether the push channel is connected or not --><action android:name="com.huawei.intent.action.PUSH_STATE" /></intent-filter></receiver><!-- 接入HMSSDK PUSH模块需要注册 :接收通道发来的通知栏消息 | The access HMSSDK push module needs to be registered: the notification bar message sent from the receiving channel --><receiver android:name="com.huawei.hms.support.api.push.PushEventReceiver" ><intent-filter><action android:name="com.huawei.intent.action.PUSH" /></intent-filter></receiver><!-- 接入HMSSDK 需要注册的应用下载服务 | Access HMSSDK need to register app download service--><service android:name="com.huawei.updatesdk.service.deamon.download.DownloadService"android:exported="false"/></application>
</manifest>
4 创建HuaweiSdk.cs
脚本,封装c#
接口调用java
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class HuaweiSdk
{public static void Init(){jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");jo = jc.GetStatic<AndroidJavaObject>("currentActivity");}// 应用授权public static void Login(){jo.Call("Login");}// 应用注销授权public static void SignOut(){jo.Call("SignOut");}public static void pmsPay(string productNo){jo.Call("pmsPay", productNo);}/// <summary>/// 游戏保存玩家信息/// </summary>public static void SavePlayerInfo(){jo.Call("savePlayerInfo");}/// <summary>/// 获取pms商品信息/// </summary>/// <param name="productNos">pms商品编码,多个以“|”分割,最多支持20个</param>public static void GetProductDetail(string productNos){jo.Call("getProductDetail", productNos);}public static void checkPay(){jo.Call("checkPay");}public static void showfloat(){jo.Call("showfloat");}public static void hidefloat(){jo.Call("hidefloat");}private static AndroidJavaClass jc;private static AndroidJavaObject jo;
}
5 新建SdkCb.cs
脚本,监听java
回调
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SdkCb : MonoBehaviour
{public void OnSdkCb(string args){Debug.Log(args);}
}
6 场景中创建一个空物体,取名叫SdkCb
,并挂上SdkCb.cs
脚本
7 创建Runner.cs
脚本,挂在主摄像机上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Runner: MonoBehaviour
{void Awake(){HuaweiSdk.Init();}void OnGUI(){if(GUILayout.Button("SignIn")){HuaweiSdk.Login();}// TODO 绑定ui按钮的点击事件,去调用sdk的接口进行测试,不列举了...}
}
四、登录错误码
https://developer.huawei.com/consumer/cn/doc/development/HMS-2-References/hmssdk_jointOper_api_reference_c9
五、支付错误码
https://developer.huawei.com/consumer/cn/doc/development/HMS-2-References/hmssdk_jointOper_api_reference_c20
六、问题与解答
1、sdk
初始化的时候提示安装 “华为移动服务”,点安装按钮,提示检查华为移动服务更新失败
解答:非华为 手机,需要下载华为服务,如果提示更新失败,很可能是因为下载的res
(包括layout、value、drawable
)没有放到工程里,请检查
2、浮标无显示、浮标隐藏不了等
见我另一篇关于华为浮标的文章 https://blog.csdn.net/linxinfa/article/details/102727686
3、cipd在哪里看
在华为开发者联盟网站上,在支付服务里,看这里 https://developer.huawei.com/consumer/cn/service/hms/doc/hmssdk_jointOper_querypayinfo.html
4、启动一直白屏,没有任何反应
很可能是权限问题,可以在设置里把权限全部勾上重启app
5、用户的AccessToken
有效期是多长时间?
用户的AccessToken
为1个小时的有效期。
6、用户的AccessToken
过期后怎么处理?
重新调用login
接口,不需要用户重新授权。
7、应用开发者是否需要对登录接口获取的ACCESSTOKEN
进行验签?
应用通过登录接口返回值中获取的ACCESSTOKEN
由华为移动服务客户端进行有效性验证,只有合法有效的ACCESSTOKEN
才会返回给应用,所以应用不需要对ACCESSTOKEN
进行验签,可以直接使用。
8、接入华为帐号,是否可以获取UID
?
不可以,由于需要隐私保护,接入华为帐号后只能获取openid
。
9、不同的应用接入华为帐号登录,是否返回同一openid
?
不是,不同应用登录同一华为帐号获取的openid不
一样,openid
是应用内的唯一标识。
10、HMS SDK 2.0升级变更说明(目前最新版4.0)
https://developer.huawei.com/consumer/cn/doc/development/AppGallery-connect-Guides/appgallerykit-hms-2-change
11、华为游戏市场中,部分游戏游客登录可以直接拉起支付,他们是怎么做到的?
联运游戏,支付(接口productPay
)必须先授权登录,如果自行开发了游客登录模式,在2.0版的SDK版本,有个HMSAgent.Pay.pay
接口,这个接口不需要先登录,可用于游客模式的支付,但此接口在4.0版的SDK已经废弃,请慎用。
12、关于游戏图标的要求
可以不用角标,图片不能圆角,必须正方形,尺寸为216x216px,格式png。
13、华为SDK有区分联运版和单机版吗?
华为SDK全球一套,不会区分单机还是非单机的
七、华为自检工具检查易见情况
八、开发者账号相关
1、如何查看APPID、APPKEY、APP SECRET等参数
登录华为开发者联盟https://developer.huawei.com/consumer/cn/
进入 管理中心,可以看到有个AppGallery Connect,点击进入
再点 我的项目
选择具体的项目,即可查看到对应项目的APPID等参数了
2、如何查看CPID、支付公钥、支付私钥等参数
登录华为开发者联盟https://developer.huawei.com/consumer/cn/
进入 管理中心,可以看到有个支付,点击进入
点击具体的应用
即可看到CPID、支付公钥、支付私钥等参数
3、如何查看应用的游戏公钥和游戏私钥
4、如何配置应用内商品
https://developer.huawei.com/consumer/cn/doc/distribution/app/agc-create_product
Unity接入华为SDK相关推荐
- Unity接入微信SDK——iOS(接入微信SDK)
Unity接入微信SDK--iOS(一 接入微信SDK) 下载微信SDK 下载地址:微信开放平台 导出Unity Xcode项目 导出Unity Xcode项目,并打开 微信SDK导入Xcode项目 ...
- Unity接入安卓sdk查看应用内存占用
注:若不清楚如何在unity中接入android sdk可先了解下相关流程.项目地址:http://download.csdn.net/download/yhuangher/9976564 在项目后期 ...
- Unity 接入第三方SDK打包闪退
在接入穿山甲sdk的时候,打包apk的时候出现适配部分机型,部分机型闪退,出现如下错误 图中可以看出是.so文件引起的问题. 接入第三方sdk的时候,有时候常常需要导入第三方jar包以及aar包,有些 ...
- Unity游戏开发——unity接入多渠道sdk
最近游戏进入最后测试和接入sdk阶段,对接了多个sdk简单记录和分享一下在接入各个渠道sdk中遇到的问题和坑,在之后或其他人看到之后可以绕过,提高效率仅此而已. 我们使用的unity开发,在选择sdk ...
- [Unity]对接华为sdk 登录
首先先下载并引入这个package 华为SDK-UnityPackage 然后 华为Plugins\\Android插件-C#文档类资源-CSDN下载 下载这2个插件 丢到Plugins\Androi ...
- Unity接入高德SDK实现定位
一.在高德官网下载需要对应的SDK http://lbs.amap.com/api/android-location-sdk 通过SHA1值获取对应的key值 a.SHA1值得获取: 1.在cmd ...
- unity接入facebook SDK时 警告:“OpenSSL not found. Make sure that OpenSSL is installed
接入facebook的SDK后配置FacebookSettings时警告OpenSSL not found. 解决方法: 1.下载并安装OpenSSL.http://slproweb.com/prod ...
- [SDK]Unity接入Facebook SDK获取用户头像
官方文档 官方文档:Facebook Login For Gaming 总结如下: 1,你的FB账户内还有一个游戏账户,在Unity中使用FB的官方SDK提供的接口进行登录时,比如 var perms ...
- Unity接入Facebook SDK出现的问题
问题: Android Build Facebook Settings打不开,里面是空白的,并且报以下错误. Win32Exception: ApplicationName='cmd', Comman ...
- unity接入咪咕SDK遇到的坑
1.unity 4.3后默认会使用 arm-v7a . 2.CmApplication就是一个简单的.jar 当成全局变量使用
最新文章
- 34篇Java基础总结博客陪博主入门Java
- 全国计算机等级考试题库二级C操作题100套(第97套)
- 什么是 Native、Web App、Hybrid、React Native和Weex?
- 【OS学习笔记】十 实模式:实现一个程序加载器-程序加载器如何将用户程序加载到内存并执行
- mysql5.6.24安装perl_mysql5.6源码安装
- Java 程序 ——感想
- 简便无刷新文件上传系统
- python工具箱_python 工具箱
- python3.4编程,麻瓜编程·python实战·4-3自学:给4-2作业换新界面
- 太实用了!这几个Python数据可视化案例!(文末送书)
- 使用nginx配置一级域名和多个二级域名
- plsql developer工具栏按钮不见了解决办法
- c语言中字节数如何判断,C语言中怎样判断输入的是整数还是浮点数
- tableau_9_快速表计算、自定义表计算、计算字段
- ikea营销_用于企业的AI开发人员工具存在的问题(以及IKEA与之相关的问题)
- 单片机音频节奏灯_使LED灯随音乐闪烁的控制方法及音乐节奏闪灯技术
- docker manifest 使用实战
- 猫扑网互动营销六大模式
- opencv java lean.png_text-lean_opencv VS2015.使用 实现水平面的文本倾斜,调整角度可 矫正。 256万源代码下载- www.pudn.com...
- tekla中梁位置属性的详解