文章目录

  • 一、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,但是过程中一堆问题,放弃治疗,不走华为文档里说的那套
它其实就是把HMSAgentjava代码和sdkjar包打成一个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工程的srcExport,导出成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 demoAndroidManifest.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相关推荐

  1. Unity接入微信SDK——iOS(接入微信SDK)

    Unity接入微信SDK--iOS(一 接入微信SDK) 下载微信SDK 下载地址:微信开放平台 导出Unity Xcode项目 导出Unity Xcode项目,并打开 微信SDK导入Xcode项目 ...

  2. Unity接入安卓sdk查看应用内存占用

    注:若不清楚如何在unity中接入android sdk可先了解下相关流程.项目地址:http://download.csdn.net/download/yhuangher/9976564 在项目后期 ...

  3. Unity 接入第三方SDK打包闪退

    在接入穿山甲sdk的时候,打包apk的时候出现适配部分机型,部分机型闪退,出现如下错误 图中可以看出是.so文件引起的问题. 接入第三方sdk的时候,有时候常常需要导入第三方jar包以及aar包,有些 ...

  4. Unity游戏开发——unity接入多渠道sdk

    最近游戏进入最后测试和接入sdk阶段,对接了多个sdk简单记录和分享一下在接入各个渠道sdk中遇到的问题和坑,在之后或其他人看到之后可以绕过,提高效率仅此而已. 我们使用的unity开发,在选择sdk ...

  5. [Unity]对接华为sdk 登录

    首先先下载并引入这个package 华为SDK-UnityPackage 然后 华为Plugins\\Android插件-C#文档类资源-CSDN下载 下载这2个插件 丢到Plugins\Androi ...

  6. Unity接入高德SDK实现定位

    一.在高德官网下载需要对应的SDK  http://lbs.amap.com/api/android-location-sdk 通过SHA1值获取对应的key值 a.SHA1值得获取:  1.在cmd ...

  7. unity接入facebook SDK时 警告:“OpenSSL not found. Make sure that OpenSSL is installed

    接入facebook的SDK后配置FacebookSettings时警告OpenSSL not found. 解决方法: 1.下载并安装OpenSSL.http://slproweb.com/prod ...

  8. [SDK]Unity接入Facebook SDK获取用户头像

    官方文档 官方文档:Facebook Login For Gaming 总结如下: 1,你的FB账户内还有一个游戏账户,在Unity中使用FB的官方SDK提供的接口进行登录时,比如 var perms ...

  9. Unity接入Facebook SDK出现的问题

    问题: Android Build Facebook Settings打不开,里面是空白的,并且报以下错误. Win32Exception: ApplicationName='cmd', Comman ...

  10. unity接入咪咕SDK遇到的坑

    1.unity 4.3后默认会使用 arm-v7a . 2.CmApplication就是一个简单的.jar 当成全局变量使用

最新文章

  1. 34篇Java基础总结博客陪博主入门Java
  2. 全国计算机等级考试题库二级C操作题100套(第97套)
  3. 什么是 Native、Web App、Hybrid、React Native和Weex?
  4. 【OS学习笔记】十 实模式:实现一个程序加载器-程序加载器如何将用户程序加载到内存并执行
  5. mysql5.6.24安装perl_mysql5.6源码安装
  6. Java 程序 ——感想
  7. 简便无刷新文件上传系统
  8. python工具箱_python 工具箱
  9. python3.4编程,麻瓜编程·python实战·4-3自学:给4-2作业换新界面
  10. 太实用了!这几个Python数据可视化案例!(文末送书)
  11. 使用nginx配置一级域名和多个二级域名
  12. plsql developer工具栏按钮不见了解决办法
  13. c语言中字节数如何判断,C语言中怎样判断输入的是整数还是浮点数
  14. tableau_9_快速表计算、自定义表计算、计算字段
  15. ikea营销_用于企业的AI开发人员工具存在的问题(以及IKEA与之相关的问题)
  16. 单片机音频节奏灯_使LED灯随音乐闪烁的控制方法及音乐节奏闪灯技术
  17. docker manifest 使用实战
  18. 猫扑网互动营销六大模式
  19. opencv java lean.png_text-lean_opencv VS2015.使用 实现水平面的文本倾斜,调整角度可 矫正。 256万源代码下载- www.pudn.com...
  20. tekla中梁位置属性的详解

热门文章

  1. opencv python 的基本操作案例(一) 记录,可查看
  2. GB28181国标平台资料整理
  3. 系统u盘测试软件,u盘检测工具操作教程
  4. 威金病毒(感染EXE文件)专杀工具
  5. 如何在ps添加箭头_PS里怎么画箭头?PS画箭头三种方法介绍
  6. 物联网和区块链:挑战与风险
  7. 浙江大学深蓝质感简约答辩PPT模板
  8. JavaScript编辑器推荐
  9. Xpose框架的入门学习
  10. 满足AUTOSAR基础软件要求的硬件安全模块(HSM)加密运算