【问题标题】:From second time "In app purchase" throwing exception in Android从第二次“应用内购买”在 Android 中引发异常
【发布时间】:2014-02-21 11:01:40
【问题描述】:

我正在尝试包含在应用购买中,并且我已经成功地显示了可用的 SKU。现在我想进行虚假购买。所以我使用了 appId = "android.test.purchased"。它第一次完美运行,但从下一个它抛出异常如下。

尝试在空对象引用上调用虚拟方法 'android.content.IntentSender android.app.PendingIntent.getIntentSender()'

有人遇到过这种情况吗?

package com.inappbilling.poc;

import java.util.ArrayList;

import org.json.JSONObject;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

import com.android.vending.billing.IInAppBillingService;

public class TestInAppPurchase extends Activity {
    private final static String SERVICE_INTENT = "com.android.vending.billing.InAppBillingService.BIND";
    private static final String _TAG = "BILLING ACTIVITY";

    private final String _testSku = "android.test.purchased";
    //available skus
    static final String SKU_7DAYS = "7days";
    static final String SKU_30DAYS = "30days";

    private Button _7daysPurchase = null;
    private Button _30daysPurchase = null;
    private IInAppBillingService _service = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(_TAG, "created");

        _7daysPurchase = ( Button ) findViewById(R.id.sevendays_btn);
        _30daysPurchase = ( Button ) findViewById(R.id.thirtydays_btn);
        _7daysPurchase.setOnClickListener(_purchaseListener);
        _30daysPurchase.setOnClickListener(_purchaseListener);

    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    OnClickListener _purchaseListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            switch ( v.getId() ) {
            case R.id.sevendays_btn:
                doPurchase();
                break;
            case R.id.thirtydays_btn:
                break;
            }
        }
    };


    private ServiceConnection _serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {       
            _service = IInAppBillingService.Stub.asInterface( service );
            Log.d(_TAG, _service.toString());
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {     
            _service = null;
            Log.d(_TAG, "destroyed");
        }

    };

    private void doPurchase(){

        if ( _service == null) {
                Log.e( _TAG , "Billing failed: billing service is null ");
                return;
        }

        ArrayList testSku = new ArrayList( );
        testSku.add( _testSku );
        Bundle querySkus = new Bundle();
        querySkus.putStringArrayList("ITEM_ID_LIST", testSku);
        Bundle skuDetails ;
        try {
            skuDetails = _service.getSkuDetails(3, getPackageName(), "inapp", querySkus);
            int response = skuDetails.getInt("RESPONSE_CODE");
            if( response == 0 ){
                ArrayList<String> responseList = new ArrayList<String>( );
                responseList = skuDetails.getStringArrayList("DETAILS_LIST");
                for( String responseString : responseList ) {
                    JSONObject jobj = new JSONObject( responseString );
                    String sku = jobj.getString("productId");
                    if( sku.equals( _testSku )){
                         Bundle buyIntentBundle = _service.getBuyIntent(3, getPackageName(), sku ,"inapp","" );
                         PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");
                         startIntentSenderForResult(pendingIntent.getIntentSender(),
                                 1001, new Intent(), Integer.valueOf(0), Integer.valueOf(0),
                                 Integer.valueOf(0));
                    }
                }
            } else {
                Log.e( _TAG , "Failed " );
            }
        } catch (Exception e) {
            Log.e( _TAG, "Caught exception  !"+ e.getMessage() );
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == 1001 ){
            String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
            if( resultCode == RESULT_OK ){
                try{
                    JSONObject jobj = new JSONObject( purchaseData );
                    String sku = jobj.getString(_testSku);
                    String paid = jobj.getString("price");
                    Log.v("SKU DATA", sku +"============"+ paid);

                }catch( Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if( _serviceConnection != null ){
            unbindService( _serviceConnection );
        }
    }
}

【问题讨论】:

  • @Greg 更新问题

标签: android in-app-purchase in-app-billing


【解决方案1】:

您好,了解上述问题的解决方案。要摆脱这种情况,您应该清除您的 android 手机上的 Google Play 应用程序的缓存。当我们进行任何应用内购买时,详细信息由 Google Play 维护服务。因此,一旦购买了产品,就可以隔离特定的 sku,以避免重复购买。 注意 - 这实际上是出于测试目的。因为 Google Play 服务会维护所有应用程序内购买或 Oauth 或任何其他功能的应用程序的记录。 希望它会帮助一些面临这个问题的人。

【讨论】:

  • 但它发生在我的用户身上(虽然只有少数),而不是作为开发人员的我
【解决方案2】:

当我们尝试购买已经拥有的物品时,我们将在 Pending Intent 处获得空异常。

因此您需要检查产品是否已购买,然后仅在未购买产品时才开始购买。

可以使用该函数检索产品购买状态

boolean haspurchase = inventory.hasPurchase(sku_id);

它对我有用..!!

【讨论】:

  • 库存变量是什么?
  • 您能否提供更多详细信息如何实现该声明?什么是库存?谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-12
  • 2014-05-31
  • 1970-01-01
相关资源
最近更新 更多