PnSDK - Android SDK接入文档
文章推薦指數: 80 %
请在文档的引导下,进行必要的编码,SDK开发包请与技术人员联系后获取。
接入准备. 工程必须使用Android 最新SDK 编译. APK包必须签名,提交Google ...
AndroidSDK接入手册使用aar资源包,不支持Eclipse
请在文档的引导下,进行必要的编码,SDK开发包请与技术人员联系后获取。
接入准备
工程必须使用Android最新SDK编译
APK包必须签名,提交GooglePlay商店以后,签名不可更改
APK包必须zipalign优化
必须保证测试手机的Google框架完整
minSdkVersion21(最低支持Android5.0)
SDK支持AndroidX检查AndroidX配置项
SDK包文件结构
(ANDROID)com.pn.sdk(游戏名)版本.zip/
├──SDK更新说明(Bundleidentifier).txt
├──PnSDK-XXXXXXX.aar该资源放入您的libs中(app/libs中)
└──google-services.json该文件放入您的应用级模块中(通常是app/..中)
项目需支持AndroidX,检查配置
检查gradle.properties中是否缺少以下配置:
android.useAndroidX=true
android.enableJetifier=true
AndroidGradleplugin(AGP)版本选择
SDK中的清单文件中添加了
该元素要求AGP版本为4.1及更高版本,为了兼容较低版本,针对AGP3.3及更高版本发布一组补丁程序。
如果您使用的是旧版AGP,请升级到以下某个版本:配置参考:classpath'com.android.tools.build:gradle:3.5.4'
如果您使用的AGP版本...
请升级到
4.0.*
4.0.1
3.6.*
3.6.4
3.5.*
3.5.4
3.4.*
3.4.3
3.3.*
3.3.3
引用依赖项
添加GoogleServicesGradle插件(用以处理google-services.json文件)
a.在项目的根级build.gradle中添加相应依赖。
buildscript{
repositories{
//Checkthatyouhavethefollowingline(ifnot,addit):
google()//Google'sMavenrepository
jcenter()
mavenCentral()
}
dependencies{
classpath'com.android.tools.build:gradle:3.5.4'
//...
//Addthefollowingline:
classpath'com.google.gms:google-services:4.3.3'//GoogleServicesplugin
}
}
allprojects{
//...
repositories{
//Checkthatyouhavethefollowingline(ifnot,addit):
google()//Google'sMavenrepository
jcenter()
mavenCentral()
//...
}
}
b.在您的模块(应用级)Gradle文件(通常是app/build.gradle)中,末尾添加一行内容,应用GoogleServicesGradle插件:
applyplugin:'com.android.application'
android{
//...
}
//Addthefollowinglinetothebottomofthefile:
applyplugin:'com.google.gms.google-services'//GooglePlayservicesGradleplugin
c.将google-services.json文件放入app/目录中
GoogleServicesGradle插件自动处理google-services.json文件,并产生在程序代码中使用的资源
以下依赖项正确应用到工程(放到libs文件夹下)
依赖库
PnSDK-vXXXX.aar
PnSDK
向您的模块级build.gradle文件添加规则,以纳入插件:
//...
dependencies{
//...
implementationfileTree(dir:'libs',include:['*.jar','*.aar'])
defappcompat_version="1.3.0"
implementation"androidx.appcompat:appcompat:$appcompat_version"
//Forloadingandtintingdrawablesonolderversionsoftheplatform
implementation"androidx.appcompat:appcompat-resources:$appcompat_version"
implementation'com.google.code.gson:gson:2.8.6'
//appsflyer
implementation'com.appsflyer:af-android-sdk:6.5.1'
implementation'com.android.installreferrer:installreferrer:2.2'
//Google
implementation'com.google.android.gms:play-services-base:17.3.0'
implementation'com.google.android.gms:play-services-auth:18.1.0'//Google帐号登录
implementation'com.google.android.gms:play-services-identity:17.0.0'//Google登录
//Google支付
defbilling_version="3.0.3"
api"com.android.billingclient:billing:$billing_version"
//Google游戏内评价Android5.0+
implementation'com.google.android.play:core:1.8.0'
//firebase数据统计
implementation'com.google.firebase:firebase-analytics:17.2.0'
//firebase推送
implementation'com.google.firebase:firebase-messaging:20.2.4'
implementation'androidx.work:work-runtime:2.4.0'
//facebook登录
implementation'com.facebook.android:facebook-login:12.3.0'
//facebook分享
implementation'com.facebook.android:facebook-share:12.3.0'
//WorkManager
defwork_version="2.7.0"
implementation("androidx.work:work-runtime:$work_version")
SDKAPI使用说明
初始化SDK
请确保在LauncherActivityOnCreate函数中初始化SDK
protectedvoidonCreate(BundlesavedInstanceState){
StringappID="APPID";
StringappKey="APPKEY";
Stringchannel="渠道标识";
StringlangID="语言字符";//查看多语言标签
PnSDK.startWithAppID(activity,appId,appKey,channel,langID);
}
所需要的参数,可以在对接需求文件中找到.
广播监听
publicclassMyBroadcastReceiverextendsBroadcastReceiver{
finalStringTAG="MyBroadcastReceiver";
@Override
publicvoidonReceive(Contextcontext,Intentintent){
Stringaction=intent.getAction();
if(TextUtils.equals(action,PnSDK.ACTION_SDK_PASSPORT)){
//通行证状态发生变化,已登录或者已登出
Log.v(TAG,"游戏接收到广播:"+PnSDK.ACTION_SDK_PASSPORT);
MapaccountInfoMap=PnSDK.getAccountInfo();
if(null==accountInfoMap){
Log.d(TAG,"游戏接收到"+PnSDK.ACTION_SDK_PASSPORT+"广播,账户没登录不向下执行代码");
//TODO没有登录
return;
}
Stringuid=(String)accountInfoMap.get("uid");//获取用户唯一ID
Stringjwt=(String)accountInfoMap.get("jwt");//登录凭证
intage=(int)accountInfoMap.get("age");//实名制用户年龄,未登记返回为“”
Stringidmd5=(String)accountInfoMap.get("idmd5");//实名制用户身份证md5,未登记返回为“”
StringaaStatus=(String)accountInfoMap.get("aa-status");//防沉迷状态,返回"restricted"禁止继续游戏
intguest=(int)accountInfoMap.get("guest");//是否游客,1为游客,0为其它账号或者已绑定游客
Log.d(TAG,"PnAccountInfo,uid:"+uid+"jwt:"+jwt);
//TODO客户端需要将jwt登录凭证上传至游戏服务器,游戏服务器再通过SDK服务器验证接口进行验证,以确保登录账号合法。
return;
}
if(TextUtils.equals(action,PnSDK.ACTION_PAYMENT)){
//TODO充值结束(返回充值信息)
Log.v(TAG,"游戏接收到广播:"+PnSDK.ACTION_PAYMENT);
Stringproductid=intent.getStringExtra("productid");
Stringnonce=intent.getStringExtra("nonce");
Stringorderid=intent.getStringExtra("orderid");
Stringtransactionid=intent.getStringExtra("transactionid");
if(TextUtils.isEmpty(transactionid)){
//TODO用户取消或者充值失败
Log.d(TAG,"游戏广播接收,充值失败,transactionidisempty!");
}else{
Log.d(TAG,"游戏广播接收,充值成功"+productid);
//TODO充值成功
}
return;
}
if(TextUtils.equals(action,PnSDK.ACTION_REQUEST_PAYMENT)){
//发起充值(返回充值项ID),用于完成补单
Log.v(TAG,"游戏接收到广播:"+PnSDK.ACTION_REQUEST_PAYMENT);
//TODO当玩家购买掉单或者应用外购买完成时,游戏内会收到此事件通知,客户端需要根据事件通知指定的产品项ID发起一次购买.
StringproductId=intent.getStringExtra("productid");
Stringsrvid="游戏服务器";//TODO游戏传入
Stringnonce="透传参数";//TODO游戏传入
Log.d(TAG,"需要发起购买的产品项ID:"+productId);
PnSDK.payWithProductID((Activity)context,productId,srvid,nonce,null);
return;
}
}
}
publicclassMainActivityextendsActivity{
privateMyBroadcastReceivermyBroadcastReceiver;
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
myBroadcastReceiver=newMyBroadcastReceiver();
IntentFilterintentFilter=newIntentFilter();
intentFilter.addAction(PnSDK.ACTION_SDK_PASSPORT);
intentFilter.addAction(PnSDK.ACTION_REQUEST_PAYMENT);
intentFilter.addAction(PnSDK.ACTION_PAYMENT);
registerReceiver(myBroadcastReceiver,intentFilter);
}
@Override
protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){
super.onActivityResult(requestCode,resultCode,data);
//...
PnSDK.onActivityResult(requestCode,resultCode,data);
}
@Override
protectedvoidonDestroy(){
super.onDestroy();
unregisterReceiver(myBroadcastReceiver);
}
}
登录通行证
PnSDK.signIn(activity);
切换账号
//首先登出当前账号
PnSDK.signOut(activity);
//紧接着调登入接口
PnSDK.signIn(activity);
客服中心
游戏必须接入SDK的客服中心,建议在游戏内设置界面和登录界面放置客服中心按钮,详情需求请参阅对接需求文件。
若未登录游戏服务器,服务器ID请传入"none"
若游戏角色未登录,角色昵称请传入"notloggedin"
extraMap扩展参数需增加roleid(角色ID),level(角色等级)参数,角色未登录时可为NULL
MapextraMap=newHashMap();
extraMap.put("roleid",角色ID);
extraMap.put("level",角色等级);
...
PnSDK.bugReport(activity,"服务器ID","角色昵称","游戏客户端版本号",extraMap);
用户中心
//用户中心主要提供账号绑定,重置游客等功能,建议在游戏设置界面中放置用户中心按钮
extraMap扩展参数需增加roleid(角色ID),level(角色等级)参数,角色未登录时可为NULL
MapextraMap=newHashMap();
extraMap.put("roleid",角色ID);
extraMap.put("level",角色等级);
...
PnSDK.userCenter(activity,"服务器ID","角色昵称","游戏客户端版本号",extraMap);
事件埋点
//事件标识详细说明,请查阅对接需求文件
PnSDK.evtTrack(activity,"eventName");
评分接口
//用户评分接口的使用时机,请参阅对接需求文件
若未登录游戏服务器,服务器ID请传入"none"
若游戏角色未登录,角色昵称请传入"notloggedin"
extraMap扩展参数需增加roleid(角色ID),level(角色等级)参数
MapextraMap=newHashMap();
extraMap.put("roleid",角色ID);
extraMap.put("level",角色等级);
...
PnSDK.appReview(activity,"服务器ID","角色昵称","游戏客户端版本号",extraMap);
动态申请权限
Android6.0及更高版本中,用户与需要相关权限的功能进行互动时动态请求权限。
/**
*@paramactivity
*@paramlistener请求监听(所请求的权限全部允许回调onSuccess)
*@parampermissions权限名称(可以传递多个,用逗号隔开):
*Manifest.permission.WRITE_EXTERNAL_STORAGE
*...
*/
PnSDK.requestPermission(this,newIRequestPermissionsListener(){
@Override
publicvoidonSuccess(){
Log.d(TAG,"获取授权成功。
");
}
@Override
publicvoidonFailed(){
Log.d(TAG,"获取授权失败。
");
}
},Manifest.permission.WRITE_EXTERNAL_STORAGE
);
调用该接口前,确认应用清单(AndroidManifest.xml)中已经声明需要请求的权限。
声明权限例子:
以及官方说明:
官方参考:https://developer.android.com/training/permissions/requesting?hl=zh-cn(需要翻墙)
单个权限请求流程参考:
1.请求权限前,询问是否同意授权
2.点击“去授权”,请求系统授权。
点击“关闭”,授权失败,允许游戏继续进行。
3.点击“始终允许”权限,继续游戏,下面的过程不需要执行。
点击“禁止”,询问是否重新授权。
4.点击“重新授权”,重新请求系统授权。
点击“关闭”,授权失败,允许游戏继续进行。
5.点击“始终允许”权限,继续游戏。
点击“禁止”,询问是否重新授权(上一步)。
勾选“禁止后不再询问”并点击“禁止”,询问是否跳转设置页面。
6.点击“去设置”权限,跳转到应用的设置页面。
点击“关闭”,授权失败,允许游戏继续进行。
系统回调
实现系统回调,否则SDK无法正常工作
onActivityResult
@Override
protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){
super.onActivityResult(requestCode,resultCode,data);
//...
PnSDK.onActivityResult(requestCode,resultCode,data);
}
充值接入说明
充值界面由游戏开发方提供.
充值项的设定,请参阅对接需求文件.
支付产品的价格需要通过SDK提供的接口查询.
查询充值项价格
请在游戏启动过程中,后台异步查询价格.
避免在显示商店时同步查询价格,这会导致打开商店界面有明显的延迟.
Listproducts=newArrayList();
products.add("game_001");
products.add("game_002");
PnSDK.queryWithProducts(activity,products,newISkuDetailsResponseListener(){
@Override
publicvoidonSkuDetailsResponse(List
价格不含税。
//sku.getPriceAmountMicros();//微单位价格,其中1,000,000微单位等于货币的一单位。
long类型
//StringpriceCurrencyCode=sku.getPriceCurrencyCode();//货币代码
//StringcurrencySymbol=Currency.getInstance(priceCurrencyCode).getSymbol();//货币符号
}
}
});
价格格式说明
如未使用PnSDK.formatPrice(sku)格式化价格,则需要将小数部分为0的情况,化为整数去掉小数部分.
e.g.$100.00=>$100
$99.99=>不变$99.99
注意
某些情况下queryWithProducts会失败,返回空的产品列表,请显示默认的产品价格,默认价格请查阅对接需求文件
充值
product充值产品ID
srvid服务器ID
nonce透传参数充值透传参数,SDK充值平台会原样传回到游戏服务器,,详见支付服务器对接
extraMap扩展参数需增加roleid(角色ID),level(角色等级)参数
MapextraMap=newHashMap();
extraMap.put("roleid",角色ID);
extraMap.put("level",角色等级);
...
PnSDK.payWithProductID(activity,"产品ID","服务器ID","nonce透传参数",extraMap);
//充值完成后,SDK会发送广播PnSDKPaymentNotification,查看广播监听说明
注意
收到PnSDKPaymentNotification回调不代表充值已到账,以游戏服务端收到SDK充值平台回调为准.
充值流程图
查询订阅
用于查询当前生效的订阅项,如游戏没有可续订充值项则无需处理
查询特定订阅项目
StringsubscriptionId="com.subs.01";
PnSDK.querySubscription(this,subscriptionId,newISpeificPurchaseListener(){
@Override
publicvoidonPurchaseResponse(com.android.billingclient.api.Purchasepurchase){
if(null==purchase){
return;
}
Log.d(TAG,"purchaseoriginalJson:"+purchase.getOriginalJson());
/*
{
"orderId":"GPA.3304-7399-****-21711",---商店订单ID
"packageName":"com.xxx.demo",---包名
"productId":"com.subs.01",---订阅项ID
"purchaseTime":1637899846435,---订阅时间
"purchaseState":0,---订阅状态
"purchaseToken":"alajnicmlhiip******Fo0LQVaJTw",---订阅token
"autoRenewing":true,---是否自动续订
"acknowledged":true---订阅是否确认
}
*/
}
});
查询所有有效的订阅项目
PnSDK.querySubscriptions(activity,newIPurchaseResponseListener(){
@Override
publicvoidonPurchaseResponse(List
例如,如果屏幕A显示项目列表,并且选择某个项目会调出屏幕B(该屏幕显示项目的更多详情),则屏幕B应提供可返回屏幕A的“向上”按钮。
如果屏幕是应用中层级最高的屏幕(即应用的主屏幕),则无需提供向上按钮。
系统的“返回”按钮用于按照用户最近操作的屏幕历史记录,按时间逆序导航。
它通常基于屏幕之间的时间关系,而非应用的层级关系。
如果之前查看的屏幕也是当前屏幕的父级项,按下“返回”按钮的作用跟按下“向上”按钮一样—这种情况很常见。
但是,“向上”按钮可确保用户留在应用内,与此不同的是,“返回”按钮可让用户返回到主屏幕,甚至返回不同的应用。
战斗支持暂停的游戏,战斗中按返回键要暂停
战斗支持暂停的游戏,返回桌面时游戏要自动暂停
关闭按钮需要关闭窗口不能返回上一层级
隐藏虚拟键盘
publicvoidhideNavigationBar(){
intuiFlags=View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|View.SYSTEM_UI_FLAG_HIDE_NAVIGATION//hidenavbar
|View.SYSTEM_UI_FLAG_FULLSCREEN//hidestatusbar
|View.SYSTEM_UI_FLAG_IMMERSIVE;
if(android.os.Build.VERSION.SDK_INT>=19){
uiFlags|=0x00001000;
}else{
uiFlags|=View.SYSTEM_UI_FLAG_LOW_PROFILE;
}
getWindow().getDecorView().setSystemUiVisibility(uiFlags);
}
@Override
publicvoidonWindowFocusChanged(booleanhasFocus){
super.onWindowFocusChanged(hasFocus);
if(hasFocus){
hideNavigationBar();
}
}
整理权限
推荐使用PnSDK提供的接口,动态申请权限
尽量避免在启动时候请求设备权限。
仅在需要使用的位置请求权限。
详情参考:https://developer.android.com/training/permissions/index.html
必须去掉的权限(文档中要求增加的除外)
android.permission.WRITE_SETTINGS
android.permission.NFC
android.permission.MANAGE_ACCOUNTS
android.permission.GET_ACCOUNTS
android.permission.USE_CREDENTIALS
android.permission.AUTHENTICATE_ACCOUNTS
android.permission.MOUNT_UNMOUNT_FILESYSTEMS
android.permission.CHANGE_WIFI_STATE
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
android.permission.CHANGE_CONFIGURATION
android.permission.SEND_SMS
android.permission.CALL_PHONE
android.permission.CHANGE_NETWORK_STATE
android.permission.PROCESS_OUTGOING_CALLS
android.permission.RECEIVE_BOOT_COMPLETED
android.permission.READ_SMS
android.permission.RECEIVE_SMS
android.permission.DOWNLOAD_WITHOUT_NOTIFICATION
com.android.vending.CHECK_LICENSE
建议去掉的权限(文档中要求增加的除外)
android.permission.ACCESS_COARSE_LOCATION
android.permission.ACCESS_FINE_LOCATION
android.permission.BROADCAST_STICKY
android.permission.GET_TASKS
android.permission.KILL_BACKGROUND_PROCESSES
android.permission.SYSTEM_ALERT_WINDOW
android.permission.RECORD_AUDIO
android.permission.READ_LOGS
android.permission.CAMERA
android.permission.READ_PHONE_STATE
推荐标准
获得GooglePlay商店推荐的必做需求
Google官方文档http://developer.android.com/intl/zh-cn/design/style/devices-displays.html
以下是经过提炼的需求,一般做到本文档需求即可获得推荐
游戏有可暂停的功能时,当在游戏界面弹出对话框时,必须把游戏暂停。
微信&阿里相关功能
微信登录&微信支付
1、向您的模块级build.gradle文件添加规则,以纳入微信需要的插件:
//...
dependencies{
//...
implementation'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'//微信
}
2、正常使用微信功能,必须完成以下操作:
在你的包名相应目录下新建一个wxapi目录,并在该wxapi目录下新增两个类:
a、WXEntryActivity类,该类必须继承自com.pn.sdk.wxapi.BaseWXEntryActivity,不需要实现任何功能。
b、WXPayEntryActivity类,该类必须继承自com.pn.sdk.wxapi.BaseWXPayEntryActivity,不需要实现任何功能。
(例如应用程序的包名为com.pn.app,则新添加的类如下图所示)
一键登录&支付宝支付
1、向您的模块级build.gradle文件添加规则,以纳入阿里需要的插件:
//...
dependencies{
//...
implementation'com.alibaba:fastjson:1.2.61'
}
2、将下面aar正确应用到工程:(在提供的zip包中包含以下aar)
alipaySdk-15.7.9-20200727142846.aar
crashshield-2.0.1-release.aar
logger-2.0.1-release.aar
main-2.0.1-release.aar
phoneNumber-L-AuthSDK-2.12.0.1.aar
PnAliSDK.aar
国内数据统计支持
将下面两个aar正确应用到工程:(在提供的zip包中包含以下aar)
msa_mdid_1.0.13.aar//OAID
RangersAppLog-Lite-cn-3.3.12.aar//巨量引擎
其它接口
服务接口
service服务名
MapextraMap扩展参数,角色未登录时可为NULL
MapextraMap=newHashMap();
extraMap.put("roleid","角色ID");
extraMap.put("nickname","角色昵称");
...
PnSDK.openService(this,"服务名",extraMap);
服务名
extraMap参数
说明
survey
roleid角色ID(可选)nickname角色昵称(可选)
打开调查问卷
terms
打开服务条款
privacy
打开隐私条款
Facebook分享
Facebook应用由PnSDK平台配置,并提供可以测试分享的Facebook账号.
测试Facebook的相关功能,需要翻墙!
Facebook图片分享
BitmapBitmap类型图片对象
MapextraMap扩展参数,传入null
PnSDK.facebookFeedWithImage(activity,Bitmap,extraMap,newIFeedListener(){
@Override
publicvoidonError(Stringerror){
if(TextUtils.isEmpty(error)){
//分享成功
}else{
//分享失敗
}
}
});
Facebook链接分享
MapextraMap扩展参数,传入null
PnSDK.facebookFeedWithMessage(this,"测试分享链接","https://www.yourlink.com",extraMap,newIFeedListener(){
@Override
publicvoidonError(Stringerror){
if(TextUtils.isEmpty(error)){
PnLog.d(TAG,"Facebook分享链接成功");
}else{
PnLog.d(TAG,"Facebook分享链接失败:"+error);
}
}
});
Instagram分享
BitmapBitmap类型图片对象
MapextraMap扩展参数,传入null
PnSDK.instagramFeedWithImage(activity,Bitmap,extraMap);
Twitter分享
在平台营运提出需求时,才需要接入此接口
Twitter分享接口
msg分享文本
URL跳转链接
bitmap图片
MapextraMap扩展参数,传入null
PnSDK.twitterFeedWithImage(activity,"msg",URL,Bitmap,extraMap);
Twitter接入注意事项:
分享时必须安装Twitter客户端,否则分享失败。
聊天室屏蔽规则
聊天屏蔽規則:
1,对指定等级做屏蔽字限制;
2,对等级高于我们设定值的玩家不做限制;
3,被屏蔽发言自己客户端可正常显示,无特殊提示;
4,被屏蔽的发言整句都不显示在聊天频道,触发屏蔽的玩家和其他玩家都无法得知是哪句话触发了屏蔽
舉例:
我們限制等級15級以下的玩家,聊天有限制
15級以下的玩家,如果聊天中包涵:line,LINE,=,元寶,等字眼,他所發的消息,就只有他自己看得到,其他玩家是收不到了。
社区
facebook,twitter,navercafeApp内打开网页
//Facebook社区
Stringurl="https://facebook.com/UltimateSchool";
PackageManagerpm=this.getPackageManager();
Uriuri=Uri.parse(url);
try{
ApplicationInfoapplicationInfo=pm.getApplicationInfo("com.facebook.katana",0);
if(applicationInfo.enabled){
uri=Uri.parse("fb://facewebmodal/f?href="+Uri.encode(url));
}
}catch(PackageManager.NameNotFoundExceptionignored){
}
startActivity(newIntent(Intent.ACTION_VIEW,uri));
//Twitter社区
Stringurl="https://twitter.com/Ultimate";
PackageManagerpm=this.getPackageManager();
Uriuri=Uri.parse(url);
startActivity(newIntent(Intent.ACTION_VIEW,uri));
//Café社区
Stringurl="https://cafe.naver.com/UltimateSchool";
PackageManagerpm=this.getPackageManager();
Uriuri=Uri.parse(url);
try{
ApplicationInfoapplicationInfo=pm.getApplicationInfo("com.nhn.android.navercafe",0);
if(applicationInfo.enabled){
uri=Uri.parse("navercafe://cafe?cafeUrl="+Uri.encode("UltimateSchool"));
}
}catch(PackageManager.NameNotFoundExceptionignored){
}
startActivity(newIntent(Intent.ACTION_VIEW,uri));
url参数由平台提供
多语言
设置SDK语言
设置SDK的系统语言(多语言游戏适用)
PnSDK.setLanguage("语言字符");
tw
繁体
cn
简体
en
英语
de
德语
jp
日语
ko
韩语
th
泰国
id
印尼语
tr
土耳其语
es
西班牙语
ru
俄语
fr
法语
pt
葡萄牙语
vi
越南语
常见问题
充值项价格查询失败?
首先平台需要先配置好充值项
必须使用真机测试,模拟器取不到价格,也不可测试充值
必须翻墙!!!
APK包名必须正确,而且正确签名
游客可以充值吗?
YES,游客账号和普通账号是同样的,可以正常充值
游客账号在下次登录通行证时,可以绑定到自选账号,升级未普通账号
游客账号绑定后,uid不会变化。
游戏不用处理绑定后账号的变化.
登录通行证账号出现问题?
显示游戏错误,平台没有开放登录,请与平台运营联系
使用Facebook方式登录时,FacebookApp显示应用处于开发模式。
请使用平台提供的Facebook测试账号登录,或者请与平台运营联系
使用Facebook方式登录时,登录成功跳回游戏后,SDK界面没有继续操作。
系统回调部分编码没正确完成.
怎样测试Facebook分享和邀请?
手机网络必须翻墙
APK包必须正确签名
Facebook账号必须是FacebookApp的测试人员账号,邀请的好友也必须是测试人员。
邀请信息只能在手机FacebookApp中看到.
Android9.0崩溃问题&网络请求问题
Android9.0崩溃问题
在android9.0中,ApacheHTTP被弃用并且被移除。
会缺少必要的类导致程序崩溃
解决方法:
在AndroidManifest.xml的中Application里添加以下内容
否则会导致:java.io.IOException:CleartextHTTPtrafficto****notpermitted
有以下两种解决方案
APP改用https请求
在res下新增一个xml目录,然后创建一个名为:network_security_config.xml文件(名字自定),内容如下,大概意思就是允许开启http请求(默认允许所有网址使用非安全连接)
延伸文章資訊
- 1Google In App Billing串接學習筆記(Android+Nodejs) - iT 邦幫忙
最近有需求用到應用程式內購買,距離上一次串內購已經好幾年,Code都不知道丟哪去了 ... 應用程式-> 商店發布-> 應用程式內商品-> 受管理商品-> 建立要納入管理的產品
- 2《Android》『In-app Billing V3 API』- 應用程式內購買的基本 ...
當虛擬貨品消耗成功以後,我們就可以去執行我們要做的動作,像是為使用者增加汽油或者魔法石…等等。 《程式測試》. 要測試透過IAB 所寫的金流服務程式碼,有兩種方式, ...
- 3建立應用程式內產品- Play 管理中心說明 - Google Support
如要提供應用程式內產品,您必須在應用程式的APK 資訊清單檔案中宣告 com.android.vending.BILLING 權限。如果您在全球發行應用程式,仍可以在所有國家/地區發布使用 ...
- 4Google Play上架全攻略
版本名稱. 1.0. 預設版本名稱為1.0。 A.1.3 下載apk 檔. 要將App Inventor 2 的應用程式發佈到Google Play 上,請先 ...
- 5[Android] In-App Billing/Purchases 實作與測試 - 一日工程師
前往Google Play Developer Console建立一個新的應用程式. 點擊"新增應用程式"; 填入標題; 倘若您無法進入此頁面,代表您沒有支付25美金的上架費.