前言

  Google Play应用商店在国外Android市场中地位基本与AppStore在IOS中的地位一致,为此考虑国外的应用时,Android首要考虑的是接入GooglePlay的排行榜等支持。

同样的由于Google未进入大陆市场,在大陆还是需要VPN才可以访问这些服务。

登录

  官方文档: https://developers.google.com/games/services/android/quickstart

  1、设置 AndroidManifest.xml中的标签项。

   <meta-data android:name="com.google.android.gms.games.APP_ID"
android:value="@string/app_id" />
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>

  2、在res\values\string.xml中添加应用的app_id。

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">XXX_NAME</string>
<string name="app_id">XXXXXXXXXX</string>
</resources>

  app_id 需要在google play 开发控制台添加对应的应用获取,网址:https://play.google.com/apps/publish

在游戏服务中添加新游戏,点进游戏项即可在游戏名下看到app_id,如下图:

              

  3、登录并设置监听回调。直接new 新的监听添加到 mGoogleApiClient 上。

     mGoogleApiClient = new GoogleApiClient.Builder(activity)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(Bundle bundle) {
OnConnected();
} @Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "onConnectionSuspended");
}
})
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
@Override
public void onConnectionFailed(com.google.android.gms.common.ConnectionResult connectionResult) {
Log.i(TAG, "onConnectionFailed getErrorCode:" + connectionResult.getErrorCode());
if (connectionResult.hasResolution()) {
try {
// !!!
connectionResult.startResolutionForResult(_gameActivity, RC_SIGN_IN);
}
catch (SendIntentException e) {
mGoogleApiClient.connect();
}
}
}
})
.addApi(Plus.API).addScope(Plus.SCOPE_PLUS_LOGIN)
.addApi(Games.API).addScope(Games.SCOPE_GAMES)
.build();

  回调设置原因如所述: http://stackoverflow.com/questions/22935861/android-implementing-google-plus-login-error-on-mconnectionresult-hasresolution  

大致是,登录时会先判断应用是否已有帐号登录,有的话回调登录成功onConnected,否则会转到 onConnectionFailed,此时会返回一个connectionResult可以用来新建一个登录窗口。

  

  4、直接登录测试。

    // 登录
public static void login()
{
Log.i(TAG, "login");
if (mGoogleApiClient.isConnected())
{
OnConnected();
}
else
{
mGoogleApiClient.connect();
}
}

测试登录注意事项:

  1、将测试帐号在https://play.google.com/apps/publish 加入到应用的测试帐号里。

  2、如果手机Google Play已经登录帐号没退出,且该帐号不是测试帐号,会出现登录界面闪下消失。

为了做帐号区分需要获取帐号信息,需要添加AndroidManifest.xml标签项。

<!-- To access accounts configured on device -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />

然后用 如下代码获取名字:

 mAccountName = Plus.AccountApi.getAccountName(mGoogleApiClient);
排行榜

  官网地址: https://developers.google.com/games/services/android/leaderboards

  1、首先接入上述的登录。

  2、在Google Play应用开发后台中的应用添加新的排行榜,得到排行榜ID LEADERBOARD_ID 如下图:

                  

    3、显示排行榜,代码如下:

    private static final String LEADERBOARD_ID = "XXXXXXXXXX";
private static final int REQUEST_LEADERBOARD =100;
// 显示排行榜
public static void showLeaderboards()
{
Log.i(TAG, "showLeaderboards");
if (mGoogleApiClient.isConnected())
{
_gameActivity.startActivityForResult(Games.Leaderboards.getLeaderboardIntent(mGoogleApiClient,LEADERBOARD_ID),REQUEST_LEADERBOARD);
}
else
{
mGoogleApiClient.connect();
}
}

   4、提交分数

    // 排行榜 提交
public static void commit(long score)
{
if (!mGoogleApiClient.isConnected())
{
mGoogleApiClient.connect();
return;
}
Log.i(TAG, "commit " + score);
Games.Leaderboards.submitScore(mGoogleApiClient,LEADERBOARD_ID,score);
}

    5、登录后获取原来的排行榜数据

    public static void OnConnected()
{
mAccountName = Plus.AccountApi.getAccountName(mGoogleApiClient);
Log.i(TAG, "onConnected "+ mAccountName);
Games.Leaderboards.loadCurrentPlayerLeaderboardScore(mGoogleApiClient,LEADERBOARD_ID,
LeaderboardVariant.TIME_SPAN_ALL_TIME, LeaderboardVariant.COLLECTION_PUBLIC)
.setResultCallback(new ResultCallback<LoadPlayerScoreResult>() {
@Override
public void onResult(LoadPlayerScoreResult arg0) {
LeaderboardScore c = arg0.getScore();
if(c!=null)
{
Log.i(TAG, "onResult " + c.getDisplayScore() + " rawScore:" + c.getRawScore());
mAccountScore = c.getRawScore();
}
loginCallback();
} });
}
支付

  官网地址: http://developer.android.com/training/in-app-billing/preparing-iab-app.html

  1、从SDK Manager中下载安装对应Google 服务,如下:

      

      

  2、从对应的sdk路径下 ~sdk\extras\google\play_billing  拷贝  IInAppBillingService.aidl  到 游戏目录下 ~proj.android\src\com\android\vending\billing

  3、将sample\TrivialDrive\src\com\example\android\trivialdrivesample\util 整个目录拷贝到游戏目录下并修改目录下文件的响应引用库路径。

  4、在AndroidManifest.xml添加对应的权限,注意大小写。

<uses-permission android:name="com.android.vending.BILLING" />

  5、在Google Play 商店添加商品信息。

     a、生成一个添加好上述第4点的权限的带有签名的release包,可参考cocos2dx - android环境配置及编译

     b、将生成的包上传到Google Play商店对应应用的Apk项。并将其关联到游戏服务中。(这里是为了后面测试支付等上传信息验证)

                

      c、在所以应用 ->应用内商品 -> 添加新商品,然后将添加的商品激活,此时同时得到一个商品Id(xxxxxxxxx)。如下图:

         

   6、几个重要函数,可参考sample\TrivialDrive\src\com\example\android\trivialdrivesample\MainActivity.java文件。

初始化设置Inpay_publickey可以在Google Play后台应用服务及API选项找到,调试log显示,添加消耗监听 OnConsumeFinishedListener,并进行 startSetup。只有在 startSetup成功回调后才可以进行下一步的购买。

        /// google pay
// compute your public key and store it in base64EncodedPublicKey
mHelper = new IabHelper(_gameActivity, Inpay_publickey);
// enable debug logging (for a production application, you should set this to false).
mHelper.enableDebugLogging(true); // Called when consumption is complete
mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() {
@Override
public void onConsumeFinished(Purchase purchase, IabResult result) {
Log.d(TAG, "Consumption finished. Purchase: " + purchase + ", result: " + result); // if we were disposed of in the meantime, quit.
if (mHelper == null) return; // We know this is the "gas" sku because it's the only one we consume,
// so we don't check which sku was consumed. If you have more than one
// sku, you probably should check...
if (result.isSuccess()) {
// successfully consumed, so we apply the effects of the item in our
// game world's logic, which in our case means filling the gas tank a bit
Log.d(TAG, "Consumption successful. Provisioning." + purchase);
// String[] parts = purchase.getSku().split("_");
// String part3 =parts[2];
// buyCallback(Integer.parseInt(part3));
}
else {
Log.e(TAG,"Error while consuming: " + result);
}
}
}; mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
Log.i(TAG, "onIabSetupFinished " );
if (!result.isSuccess()) {
// Oh noes, there was a problem.
Log.d(TAG, "Problem setting up In-app Billing: " + result);
}
}
});

调用购买并设置回调,设置变量仅能同时存在一个购买界面否则会崩溃,因为是Manager类型一次消耗道具所以在购买成功后直接进行consumeAsync使用消耗品。

    //购买
public static void buy(int idx)
{
if(isInBuyed)
{
return;
}
if (!mGoogleApiClient.isConnected())
{
mGoogleApiClient.connect();
return;
} /* TODO: for security, generate your payload here for verification. See the comments on
* verifyDeveloperPayload() for more info. Since this is a SAMPLE, we just use
* an empty string, but on a production app you should carefully generate this. */
String payload = "XXXXXXXXXXXII";//createDeveloperPayload();
mHelper.launchPurchaseFlow(_gameActivity, SKU_GAS+idx, RC_REQUEST,
new IabHelper.OnIabPurchaseFinishedListener() {
@Override
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
Log.d(TAG, "Purchase finished: " + result + ", purchase: " + purchase);
isInBuyed =false;
// if we were disposed of in the meantime, quit.
if (mHelper == null) return; if (result.isFailure()) {
Log.e(TAG,"Error purchasing: " + result);
return;
}
// if (!verifyDeveloperPayload(purchase)) {
// Log.e(TAG,"Error purchasing. Authenticity verification failed.");
// return;
// }
Log.d(TAG, "Purchase successful." + purchase.getSku());
mHelper.consumeAsync(purchase, mConsumeFinishedListener);
}
}, payload); isInBuyed = true;
}

这里必须对购买失败进行处理,否则重新点击购买也会导致崩溃。如下:

     @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data);
if (JaveJniHelper.mHelper == null) return; // Pass on the activity result to the helper for handling
if (!JaveJniHelper.mHelper.handleActivityResult(requestCode, resultCode, data)) {
// not handled, so handle it ourselves (here's where you'd
// perform any handling of activity results not related to in-app
// billing...
super.onActivityResult(requestCode, resultCode, data);
} }

至此,一个正常的购买流程已经可以正常完成了。

这里在提几个碰到问题及修复方案:

  1、点击购买出现 需要验证身份 您需要登录自己的google账户。

解决: 在Google Play商店中提交release签名一致,版本号一致的包,并进行alpha/beta发布。(发布后需要一段时间等Google Play后台显示的更新完成)

  2、提示   无法购买您要买的商品。

解决: 在beta测试中选择需要的测试方法并提交,选择后一定要点击右上角的 提交更新 按钮,稍等片刻刷新后确定可以看到已选中了。(封闭式测试帐号需要将测试测好加入测试列表)

GooglePlay - 排行榜及支付接入的更多相关文章

  1. Android支付接入(7):Google In-app-Billing

    今天跟大家一起看下Google的in-app Billing V3支付.    如果没有GooglePlay此处附上安装Google Play的一键安装器的链接(需要Root权限):http://ww ...

  2. C#开发微信门户及应用(32)--微信支付接入和API封装使用

    在微信的应用上,微信支付是一个比较有用的部分,但也是比较复杂的技术要点,在微商大行其道的年代,自己的商店没有增加微信支付好像也说不过去,微信支付旨在为广大微信用户及商户提供更优质的支付服务,微信的支付 ...

  3. Android支付接入(五):机锋网

    原地址:http://blog.csdn.net/simdanfeg/article/details/9012083 前边已经陆续跟大家走了一遍运营商和支付宝付费接入,今天跟大家一起看看机锋网的支付接 ...

  4. Android支付接入(七):Google In-app-Billing

    前段时间有事请耽搁了,今天跟大家一起看下Google的in-app Billing V3支付.    如果没有Google Play此处附上安装Google Play的一键安装器的链接(需要Root权 ...

  5. 微信小程序支付接入实战

    1. 微信小程序支付接入实战 1.1. 需求   最近接到一个小程序微信支付的需求,需要我写后台支持,本着能不自己写就不自己写的cv原则,在网上找到了些第三方程序,经过尝试后,最后决定了这不要脸作者的 ...

  6. APP支付宝支付接入

    1.app支付简介 买家可以在手机,掌上电脑等无线设备的应用程序内,通过支付宝(支付宝app或网页版支付宝)付款购买商品,且资金实行实时到账. 2.申请条件 1.申请前必须拥有经过实名认证的支付宝账户 ...

  7. 亲历H5移动端游戏微信支付接入及那些坑(四)——参考文档

    写完三篇后,我觉得微信支付的文档确实比较乱,所以在此做一个整理汇总 支付流程相关文档 一下文档已经按照接入顺序排列,请依次参考阅读 微信公众号网页授权两种access_token区别,获取用户open ...

  8. 亲历H5移动端游戏微信支付接入及那些坑(二)——获取Openid和授权

    第一篇中将一些坑说明,那么这篇开始正式进入接入步骤.具体的参数说明,我不会列出,毕竟微信官方文档都有,我想大家都看的懂,而且这接口也有可能微信会变动,所以不列出来,也是不想引起大家的误解,接入步骤只起 ...

  9. Android支付接入之Google In-app-Billing

    原文链接:http://www.mobile-open.com/2016/966337.html 因为公司需要接入Google的应用内支付(即Google的in-app Billing V3),接入过 ...

随机推荐

  1. 201521123084 《Java程序设计》第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1. 互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) ...

  2. 软工+C(2017第9期) 助教指南

    //上一篇:提问与回复 [备注]:请优先阅读 Handshake/点评/评分 三部分. 0x00 Handshake 了解<构建之法>作者参与软件工程改革的一些背景: http://www ...

  3. 团队作业8----第二次项目冲刺(Beta阶段) 第一天

    BETA阶段冲刺第一天 1.开了个小会议 2.每个人的工作 (1) 昨天已完成的工作: 今天是第一天,所以是新的开始. (2) 今天计划完成的工作: (3) 工作中遇到的困难: 由于有新的成员加入,默 ...

  4. 团队作业8——第二次项目冲刺(Beta阶段)日志集合处

    Beta版本冲刺 http://www.cnblogs.com/vviane1/p/6886049.html 第一天(2017.05.22) http://www.cnblogs.com/vviane ...

  5. java课程设计--WeTalk(201521123076)

    在线群聊系统 1,团队课程设计博客链接 http://www.cnblogs.com/slickghost/p/7018105.html 个人负责模块或任务说明 负责模块:总体设计及主要聊天功能实现 ...

  6. 201521123049 《JAVA程序设计》 第14周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 2. 书面作业 1. MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自 ...

  7. Java: server/client 心跳机制实现 示例

    心跳机制 心跳机制是定时发送一个自定义的结构体(心跳包),让对方知道自己还活着,以确保连接的有效性的机制. 大部分CS的应用需要心跳机制.心跳机制一般在Server和Client都要实现,两者实现原理 ...

  8. Eclipse rap 富客户端开发总结(14) :rap 图片、数据缓存处理

    一.概述 在进行了 rap 的基本学习之后,您对 rap 的理解是否进入了更高的一个层次呢,个人觉得,对学习 rap 的人来说,进行 rap 的学习是一个探索的过程,在编程中不断的对其进行理解和分析, ...

  9. 深入浅出数据结构C语言版(17)——希尔排序

    在上一篇博文中我们提到:要令排序算法的时间复杂度低于O(n2),必须令算法执行"远距离的元素交换",使得平均每次交换减少不止1逆序数. 而希尔排序就是"简单地" ...

  10. Android 字体修改,所有的细节都在这里 | 开篇

    版权声明: 本账号发布文章均来自公众号,承香墨影(cxmyDev),版权归承香墨影所有. 每周会统一更新到这里,如果喜欢,可关注公众号获取最新文章. 未经允许,不得转载. 序 在 Android 下使 ...