The reason this was not working was because onServiceConnected()
isn't guaranteed to be called until onCreate()
completes. So I moved the try/catch code into onServiceConnected()
. I'm not sure if this is best practice, but it seems to have fixed my issue. Here is the resulting code for anyone finding themselves with this same error. This is exuding button and purchasing logic. I recommend this tutorial for that code.
public class MainActivity extends Activity
{
IabHelper mHelper;
IInAppBillingService mService;
static final String ITEM_SKU = "android.test.purchased";
private Button buyButton;
AdView adView;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
adView = (AdView)this.findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
adView.loadAd(adRequest);
buyButton = (Button)findViewById(R.id.buyButton);
bindService(new Intent("com.android.vending.billing.InAppBillingService.BIND"), mServiceConn, Context.BIND_AUTO_CREATE);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
ServiceConnection mServiceConn = new ServiceConnection()
{
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
mService = IInAppBillingService.Stub.asInterface(service);
Log.d("TEST", "mService ready to go!");
checkOwnedItems();
}
@Override
public void onServiceDisconnected(ComponentName name)
{
mService = null;
}
};
private void checkownedItems()
{
try
{
Bundle ownedItems = mService.getPurchases(3, getPackageName(), "inapp", null);
if(ownedItems.getInt("RESPONSE_CODE") == 0)
{
ArrayList<String> ownedSkus = ownedItems.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
ArrayList<String> purchaseDataList = ownedItems.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
ArrayList<String> signatureList = ownedItems.getStringArrayList("INAPP_DATA_SIGNATURE");
String continuationToken = ownedItems.getString("INAPP_CONTINUATION_TOKEN");
if(purchaseDataList.size() > 0)
{
//Item(s) owned
for(int i=0; i<purchaseDataList.size(); ++i)
{
String purchaseData = purchaseDataList.get(i);
String signature = signatureList.get(i); //Note signatures do not appear to work with android.test.purchased (silly google)
String sku = ownedSkus.get(i);
}
}
else
{
//Item(s) not owned
String base64EncodedPublicKey = "public_key";
mHelper = new IabHelper(this, base64EncodedPublicKey);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener()
{
@Override
public void onIabSetupFinished(IabResult result)
{
if(!result.isSuccess())
{
Log.d("TEST", "In-app Billing setup failed: " + result);
}
else
{
Log.d("TEST", "In-app Billing is set up OK");
}
}
});
}
}
else
{
//Error checking owned items
}
}
catch(RemoteException e)
{
e.printStackTrace();
}
}
@Override
public void onDestroy()
{
super.onDestroy();
if(mServiceConn != null)
{
unbindService(mServiceConn);
}
}
}