アプリにアプリ内課金APIを実装しようとしていますが、アプリを実行すると例外がスローされます。アプリ内課金APIを扱うのはこれが初めてです。これは私が得ている例外のログです:
Process: koemdzhiev.com.quickshoppinglist, PID: 10604
Java.lang.RuntimeException: Unable to start activity ComponentInfo{koemdzhiev.com.quickshoppinglist/koemdzhiev.com.quickshoppinglist.ui.MainActivity}: Java.lang.IllegalStateException: IAB helper is not set up. Can't perform operation: queryInventory
at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2329)
at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:2389)
at Android.app.ActivityThread.access$900(ActivityThread.Java:147)
at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1296)
at Android.os.Handler.dispatchMessage(Handler.Java:102)
at Android.os.Looper.loop(Looper.Java:135)
at Android.app.ActivityThread.main(ActivityThread.Java:5254)
at Java.lang.reflect.Method.invoke(Native Method)
at Java.lang.reflect.Method.invoke(Method.Java:372)
at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:898)
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:693)
Caused by: Java.lang.IllegalStateException: IAB helper is not set up. Can't perform operation: queryInventory
at koemdzhiev.com.quickshoppinglist.utils.IabHelper.checkSetupDone(IabHelper.Java:782)
at koemdzhiev.com.quickshoppinglist.utils.IabHelper.queryInventoryAsync(IabHelper.Java:610)
at koemdzhiev.com.quickshoppinglist.utils.IabHelper.queryInventoryAsync(IabHelper.Java:639)
at koemdzhiev.com.quickshoppinglist.ui.MainActivity.queryPurchasedItems(MainActivity.Java:187)
at koemdzhiev.com.quickshoppinglist.ui.MainActivity.onStart(MainActivity.Java:193)
at Android.app.Instrumentation.callActivityOnStart(Instrumentation.Java:1220)
メインアクティビティのコード:
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private Toolbar mToolbar;
private RecyclerView mRecyclerView;
private ArrayList<String> shoppingListItems;
private SharedPreferences mSharedPreferences;
private SharedPreferences.Editor mEditor;
private TextView mEmptyTextView;
private ShoppingListAdapter adapter;
private ActionButton actionButton;
private MaterialDialog addItemdialog = null;
private AdView mAdView;
private IabHelper mHelper;
private String SKU_REMOVE_ADDS = "remove_adds_sku";
private boolean mIsRemoveAdds = false;
private IabHelper.OnIabPurchaseFinishedListener mPurchasedFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
@Override
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
if (result.isFailure()) {
Log.d(TAG, "Error purchasing: " + result);
return;
}
else if (purchase.getSku().equals(SKU_REMOVE_ADDS)) {
// consume the gas and update the UI
mIsRemoveAdds = true;
mAdView.setVisibility(View.GONE);
Toast.makeText(MainActivity.this,"Purchase successful",Toast.LENGTH_LONG).show();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String publicKey = s1+s2+s3+s4+s5;
mHelper = new IabHelper(this,publicKey);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
@Override
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
//error
Log.d(TAG, "Proglem setting up in-app Billing: " + result);
}
//Horay, IAB is fully set up!
Log.d(TAG, "Horay, IAB is fully set up!");
queryPurchasedItems();
}
});
private void queryPurchasedItems() {
//check if user has bought "remove adds"
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
@Override
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
if (result.isFailure()) {
// handle error here
Toast.makeText(MainActivity.this,"error",Toast.LENGTH_LONG).show();
}
else{
// does the user have the premium upgrade?
mIsRemoveAdds = inventory.hasPurchase(SKU_REMOVE_ADDS);
if(!mIsRemoveAdds) {
Toast.makeText(MainActivity.this,"no premium",Toast.LENGTH_LONG).show();
mAdView = (AdView) findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);
}else{
mAdView.setVisibility(View.GONE);
Toast.makeText(MainActivity.this,"premium",Toast.LENGTH_LONG).show();
}
}
}
};
mHelper.queryInventoryAsync(mGotInventoryListener);
}
@Override
protected void onStart() {
super.onStart();
queryPurchasedItems();
isListEmpty();
}
@Override
protected void onResume() {
super.onResume();
queryPurchasedItems();
isListEmpty();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mHelper != null) mHelper.dispose();
mHelper = null;
mAdView.destroy();
}
最後に、すべてが機能し、この例外が発生しませんでした "IABヘルパーが設定されていません。操作を実行できません:queryInventory"または "非同期操作を開始できません(消費)別の非同期のため操作(消費)が進行中です。」.
最初に行う必要があるのは、IabHelper.Javaクラスに2つのメソッドを追加することです。
public boolean isAsyncInProgress(){
return mAsyncInProgress;
}
public boolean isSetupDone (){
return mSetupDone;
}
そしてあなたの主な活動より:
public class MainActivity extends AppCompatActivity {
private IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
@Override
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
if (result.isFailure()) {
// handle error here
Toast.makeText(MainActivity.this,"error",Toast.LENGTH_LONG).show();
}
else{
// does the user have the premium upgrade?
mIsRemoveAdds = inventory.hasPurchase(SKU_REMOVE_ADDS);
if(!mIsRemoveAdds) {
Toast.makeText(MainActivity.this,"no premium",Toast.LENGTH_LONG).show();
mAdView = (AdView) findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);
}else{
mAdView.setVisibility(View.GONE);
Toast.makeText(MainActivity.this,"premium",Toast.LENGTH_LONG).show();
}
}
}
};
private IabHelper.OnIabPurchaseFinishedListener mPurchasedFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
@Override
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
if (result.isFailure()) {
Log.d(TAG, "Error purchasing: " + result);
return;
}
else if (purchase.getSku().equals(SKU_REMOVE_ADDS)) {
// consume the gas and update the UI
mIsRemoveAdds = true;
mAdView.setVisibility(View.GONE);
Toast.makeText(MainActivity.this,"Purchase successful",Toast.LENGTH_LONG).show();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String publicKey = s1+s2+s3+s4+s5;
mHelper = new IabHelper(this,publicKey);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
@Override
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
//error
Log.d(TAG, "Proglem setting up in-app Billing: " + result);
}
if (result.isSuccess()) {
//Horay, IAB is fully set up!
Log.d(TAG, "Horay, IAB is fully set up!");
//queryPurchasedItems;
mHelper.queryInventoryAsync(mGotInventoryListener);
}
}
});
そして今、GoogleのAPIで推奨されている guide では、startメソッドまたはresumeメソッドでユーザーが購入したアイテムを確認する必要があります。ここでは、IabHelper.Javaクラスに追加した2つのメソッドが必要です。
private void queryPurchasedItems() {
//check if user has bought "remove adds"
if(mHelper.isSetupDone() && !mHelper.isAsyncInProgress()) {
mHelper.queryInventoryAsync(mGotInventoryListener);
}
}
@Override
protected void onStart() {
super.onStart();
queryPurchasedItems();
}
@Override
protected void onResume() {
super.onResume();
queryPurchasedItems();
isListEmpty();
}
OnIabSetupFinishedListenerは(!result.isSuccess())をチェックします
ただし、結果が成功しない場合は、ここに戻ったり中止したりしません。
あなたのmHelper.startSetupが失敗し、この失敗を処理していないと思います。