PnSDK - Android SDK接入文档

文章推薦指數: 80 %
投票人數:10人

请在文档的引导下,进行必要的编码,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(ListskuDetailsList){ //查询失败 if(null==skuDetailsList) return; for(SkuDetailssku:skuDetailsList){ sku.getSku(); --产品ID //只有海外Google发行渠道的包需要查询价格 StringdisplayPrice=PnSDK.formatPrice(sku); --格式化价格,包含货币符号 //displayPrice可直接用于价格显示 //sku.getSku();//充值项ID //sku.getPrice();//格式化价格,包括其货币符号。

价格不含税。

//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(); idList.add("推送ID1"); idList.add("推送ID2"); PnSDK.deleteNotifications(idList); //移除所有本地推送 PnSDK.deleteNotifications(null); Google商店推荐 返回和向上导航的规则 “向上”按钮用于根据屏幕之间的层级关系在某个应用内部导航。

例如,如果屏幕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 以下是经过提炼的需求,一般做到本文档需求即可获得推荐 在AndroidManifest.xml中appilication层加上主题 targetSdkVersion30或者更高 AppIcon须提供以下规格 切换至后台,或者设备锁屏时,游戏应处于暂停状态。

游戏有可暂停的功能时,当在游戏界面弹出对话框时,必须把游戏暂停。

微信&阿里相关功能 微信登录&微信支付 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里添加以下内容 相关参考链接https://developer.android.com/about/versions/pie/android-9.0-changes-28 Android9.0网络请求问题 在AndroidP系统的设备上,如果应用使用的是非加密的明文流量的http网络请求,则会导致该应用无法进行网络请求,https则不会受影响,同样地,如果应用嵌套了webview,webview也只能使用https请求。

否则会导致:java.io.IOException:CleartextHTTPtrafficto****notpermitted 有以下两种解决方案 APP改用https请求 在res下新增一个xml目录,然后创建一个名为:network_security_config.xml文件(名字自定),内容如下,大概意思就是允许开启http请求(默认允许所有网址使用非安全连接) 然后在APP的AndroidManifest.xml文件下的application标签增加以下属性 接入准备 SDK包文件结构 检查AndroidX配置项 AGP版本选择 依赖项 SDKAPI 初始化 广播监听 登录 切换账号 客服中心 用户中心 事件埋点 评分 动态申请权限 系统回调 充值 查询价格 充值 查询订阅 补单功能测试 服务器对接 登录验证 充值回调 订阅通知(非必需) 网页充值(非必需) 网页充值流程图(非必需) 在线数据统计接口 推送接口(非必需) 进阶 本地推送 Google商店推荐 隐藏虚拟键盘 整理权限    权限接口    必要权限流程    非必要权限流程 推荐标准 微信&阿里相关功能 微信登录&微信支付 阿里相关功能 国内数据统计支持 其它接口(非必需) 服务接口 Facebook图片分享 Facebook链接分享 Instagram分享 Twitter分享 聊天室屏蔽规则 社区 多语言(非必需) 设置SDK语言 常见问题 充值项价格查询失败? 游客可以充值吗? 登录通行证账号出现问题? 怎样测试Facebook分享和邀请? Android9.0崩溃问题&网络请求问题 Backtotop



請為這篇文章評分?