GooglePlay - 排行榜及支付接入


前言

  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">10XXXXXXXXXX</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測試中選擇需要的測試方法並提交,選擇后一定要點擊右上角的 提交更新 按鈕,稍等片刻刷新后確定可以看到已選中了。(封閉式測試帳號需要將測試測好加入測試列表)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM