2015-08-15 217 views
7

這是我第一次在Android應用帳單工作。我的目標是爲應用程序創建可購買的產品,就像專業版解鎖一樣。Android在應用帳單:購買不斷獲得-1005響應用戶取消

我的問題是,它一直給我這些錯誤。

enter image description here

enter image description here

請大家注意,許可證密鑰是正確的,我的谷歌帳戶已經被添加作爲在控制檯中測試儀,產品SKU已經存在並且APK的阿爾法版本是已經上傳到控制檯。

這裏是我的代碼,

public class ProVersionActivity extends AppCompatActivity { 

    public static final String TAG = "ProVersionActivity"; 
    public static final String SKU_PRO_VERSION = "vollversion"; 
    private boolean mProVersionPurchased = false; 
    private String mPayload = ""; 

    //(arbitrary) request code for the purchase flow 
    public static final int RC_REQUEST = 10001; 

    private Button mInAppPurchaseButton = null; 
    private WebView mWebView = null; 
    private IabHelper mHelper = null; 

    private ProgressDialog mProgressDialog = null; 

    private static final String LICENSE_KEY = "LICENSE_KEY"; 

    //Listener that's called when we finish querying the items and subscriptions we own 
    private IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() { 
     public void onQueryInventoryFinished(IabResult result, Inventory inventory) { 
      Log.d(TAG, "Query inventory finished."); 

      // Have we been disposed of in the meantime? If so, quit. 
      if (mHelper == null) return; 

      // Is it a failure? 
      if (result.isFailure()) { 
       complain("Failed to query inventory: " + result); 
       return; 
      } 

      Log.d(TAG, "Query inventory was successful."); 

      /* 
      * Check for items we own. Notice that for each purchase, we check 
      * the developer payload to see if it's correct! See 
      * verifyDeveloperPayload(). 
      */ 

      // Do we have the infinite gas plan 
      Purchase proVersionPurchase = inventory.getPurchase(SKU_PRO_VERSION); 
      mProVersionPurchased = (proVersionPurchase != null && verifyDeveloperPayload(proVersionPurchase)); 
      Log.d(TAG, "User " + (mProVersionPurchased ? "HAS" : "DOES NOT HAVE") + " proversion"); 

      if(mProVersionPurchased){ 
       //this means user already purchased the full version 
       setProversionPurchased(mProVersionPurchased); 
      } 

      Log.d(TAG, "Initial inventory query finished"); 
     } 
    }; 

    // Callback for when a purchase is finished 
    private IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() { 
     public void onIabPurchaseFinished(IabResult result, Purchase purchase) { 

      Log.d(TAG, "Purchase finished: " + result + ", purchase: " + purchase); 

      // if we were disposed of in the meantime, quit. 
      if (mHelper == null) return; 

      if (result.isFailure()) { 
       Log.d(TAG, "Error purchasing: " + result); 
       complain("Error purchasing: " + result); 
       //setWaitScreen(false); 
       dismissProgressDialog(); 
       return; 
      } 
      if (!verifyDeveloperPayload(purchase)) { 
       Log.d(TAG, "Error purchasing. Authenticity verification failed."); 
       complain("Error purchasing. Authenticity verification failed."); 
       //setWaitScreen(false); 
       dismissProgressDialog(); 
       return; 
      } 

      Log.d(TAG, "Purchase successful."); 

      if (purchase.getSku().equals(SKU_PRO_VERSION)) { 

       // bought the infinite gas subscription 
       Log.d(TAG, "Proversion purchased."); 
       alert("Thank you for purchasing the Proversion!"); 
       mProVersionPurchased = true; 
       setProversionPurchased(mProVersionPurchased); 
       //setWaitScreen(false); 
       dismissProgressDialog(); 

       ProVersionActivity.this.finish(); 
      } 
     } 
    }; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.activity_pro_version); 
     getSupportActionBar().setTitle(R.string.vollversion); 

     //for the progress dialog 
     mProgressDialog = new ProgressDialog(this); 
     mProgressDialog.setCancelable(false); 
     mProgressDialog.setCanceledOnTouchOutside(false); 
     mProgressDialog.setMessage("Processing..."); 
     mProgressDialog.setIndeterminate(true); 

     String lang = getString(R.string.lang); 

     mWebView = (WebView) findViewById(R.id.webView); 
     mWebView.getSettings().setJavaScriptEnabled(true); 
     mWebView.loadUrl("file:///android_asset/html/" + lang + "_iap.htm"); 

     /** 
     * preparing in app billing 
     * */ 
     String base64EncodedPublicKey = LICENSE_KEY; 
     // compute your public key and store it in base64EncodedPublicKey 
     mHelper = new IabHelper(this, base64EncodedPublicKey); 
     // enable debug logging (for a production application, you should set this to false). 
     mHelper.enableDebugLogging(true); 

     mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() { 
      public void onIabSetupFinished(IabResult result) { 

       if (!result.isSuccess()) { 
        Log.d(TAG, "Problem setting up In-app Billing: " + result); 
       } 

       // Have we been disposed of in the meantime? If so, quit. 
       if (mHelper == null) 
        return; 

       // IAB is fully set up. Now, let's get an inventory of stuff we own. 
       Log.d(TAG, "Setup successful. Querying inventory."); 
       mHelper.queryInventoryAsync(mGotInventoryListener); 
      } 
     }); 

     mInAppPurchaseButton = (Button) findViewById(R.id.in_app_purchase_button); 
     mInAppPurchaseButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 

       if (!mHelper.subscriptionsSupported()) { 
        Log.d(TAG, "Subscriptions not supported on your device yet. Sorry!"); 
        complain("Subscriptions not supported on your device yet. Sorry!"); 
        return; 
       } 

       //setWaitScreen(true); 
       showProgressDialog(); 
       Log.d(TAG, "Launching purchase flow for pro version purchase."); 
       mHelper.launchPurchaseFlow(
         ProVersionActivity.this, 
         SKU_PRO_VERSION, 
         //IabHelper.ITEM_TYPE_SUBS, 
         RC_REQUEST, 
         mPurchaseFinishedListener, 
         mPayload); 
      } 
     }); 
    } 

    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 

     Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data); 

     if (mHelper == null) 
      return; 

     // Pass on the activity result to the helper for handling 
     if (!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); 
     } 
     else { 
      Log.d(TAG, "onActivityResult handled by IABUtil."); 
     } 
    } 

    private void setProversionPurchased(boolean value){ 

     //temporarily allow the purchase immediately for development purposes. 
     SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(ProVersionActivity.this); 
     SharedPreferences.Editor editor = sharedPref.edit(); 
     editor.putBoolean(SettingsActivity.PREF_KEY_PRO_VERSION, value); 
     editor.apply(); 

     Toast.makeText(this,"Pro version purchased!",Toast.LENGTH_LONG).show(); 
    } 

    private void complain(String message) { 
     Log.e(TAG, "Error: " + message); 
     alert("Error: " + message); 
    } 

    private void alert(String message) { 
     AlertDialog.Builder bld = new AlertDialog.Builder(this); 
     bld.setMessage(message); 
     bld.setNeutralButton("OK", null); 
     Log.d(TAG, "Showing alert dialog: " + message); 
     bld.create().show(); 
    } 

    /** Verifies the developer payload of a purchase. */ 
    private boolean verifyDeveloperPayload(Purchase p) { 

     mPayload = p.getDeveloperPayload(); 
     Log.d(TAG, "payload: "+mPayload); 

     /* 
     * TODO: verify that the developer payload of the purchase is correct. It will be 
     * the same one that you sent when initiating the purchase. 
     * 
     * WARNING: Locally generating a random string when starting a purchase and 
     * verifying it here might seem like a good approach, but this will fail in the 
     * case where the user purchases an item on one device and then uses your app on 
     * a different device, because on the other device you will not have access to the 
     * random string you originally generated. 
     * 
     * So a good developer payload has these characteristics: 
     * 
     * 1. If two different users purchase an item, the payload is different between them, 
     * so that one user's purchase can't be replayed to another user. 
     * 
     * 2. The payload must be such that you can verify it even when the app wasn't the 
     * one who initiated the purchase flow (so that items purchased by the user on 
     * one device work on other devices owned by the user). 
     * 
     * Using your own server to store and verify developer payloads across app 
     * installations is recommended. 
     */ 

     return true; 
    } 

    /** 
    * Method to display registration progress dialog. 
    */ 
    private void showProgressDialog(){ 

     /* Dismiss existing dialog if any. */ 
     dismissProgressDialog(); 

     new DialogAsyncTask().execute(new String[]{}); 
    } 

    private void dismissProgressDialog(){ 
     /* 
     if(mProgressDialog != null && mProgressDialog.isShowing()){ 
      mProgressDialog.dismiss(); 
     } 
     */ 
     RUN_PROGRESS_DIALOG = false; 
    } 

    public static boolean RUN_PROGRESS_DIALOG = true; 

    private class DialogAsyncTask extends AsyncTask<String,String,String> { 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      mProgressDialog.show(); 
     } 

     @Override 
     protected String doInBackground(String... strings) { 

      while(RUN_PROGRESS_DIALOG){} 

      return null; 
     } 

     @Override 
     protected void onPostExecute(String s) { 
      super.onPostExecute(s); 
      mProgressDialog.dismiss(); 
     } 
    } 

    // We're being destroyed. It's important to dispose of the helper here! 
    @Override 
    public void onDestroy() { 
     super.onDestroy(); 

     // very important: 
     Log.d(TAG, "Destroying helper."); 
     if (mHelper != null) { 
      mHelper.dispose(); 
      mHelper = null; 
     } 
    } 
} 

代碼保持返回-1005迴應中,我無法找到Android開發者網站的任何引用。我已經花了無數天找到問題和谷歌搜索請幫助我。任何意見和答案將不勝感激。非常感謝!

+1

是你的應用在阿爾法發佈狀態?同時嘗試使用應用程序管理器清除Google Play商店應用中的數據。有時由於緩存而顯示消息。檢查此鏈接https://www.androidpit.com/how-to-fix-google-play-authentication-is-required-error – random

回答

1
+0

僅供參考有一篇文章討論你最近創建的[tag:koans]標籤[on meta here](http://meta.stackoverflow.com/questions/306253/a-moan-about-koans) – durron597

0

這個問題的原因是相當啞,上傳應用alpha通道後,它需要被髮布。我沒有發佈它,所以它仍然處於草稿模式。在我發佈應用程序後,它在一個小時內運行。

+0

抄襲:https://stackoverflow.com/questions/25762342/android-issue-with-in-應用計費 –

0

在我的情況下,測試用戶看到這個錯誤,因爲我忘記了將應用內產品設置爲「活動」。

將產品設置爲「有效」並等待1-2小時後,應用內購買開始生效。

(該應用程序僅在alpha通道中,已經發布,並且看到該錯誤的用戶在測試人員電子郵件的「封閉式alpha測試」列表中有他們的帳戶。唯一缺少的成分是,該產品還沒有被設置爲「活動」)

products showing 'active' status

設置產品爲主動:

  1. 登錄到谷歌開發者控制檯,並選擇您的應用
  2. 點擊應用內商品
  3. 點擊產品名稱看「管理產品詳細信息」
  4. 在右上角,從下拉列表中選擇「激活」
  5. 等待1-2hrs(你會得到一個彈出說產品激活)

product status dropdown