package jp.mixi.training.inapppurchase;
import jp.mixi.training.inapppurchase.helper.DummySku;
import jp.mixi.training.inapppurchase.helper.StartPurchaseHelper;
import jp.mixi.training.inapppurchase.helper.StartPurchaseHelper.BillingActionResponse;
import jp.mixi.training.inapppurchase.helper.StartPurchaseHelper.PurchaseData;
import android.app.Activity;
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.os.RemoteException;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import com.android.vending.billing.IInAppBillingService;
import com.google.common.base.Optional;
// DISCLAIMER: this activity is a mere way to test calls to the Google in-app purchase service ;
// it doesn't provide a proper "buy something" user experience
// nor should it be referred to as a model for an activity providing such a UX
public class MainActivity extends FragmentActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private static final int REQUEST_CODE_PURCHASE = 100;
private volatile IInAppBillingService mBillingService = null;
private ServiceConnection mBillingServiceConnection = null;
private final StartPurchaseHelper mPurchaseHelper = new StartPurchaseHelper();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
disableActionViews();
//アプリ内課金サービスに接続する
mBillingServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mBillingService = IInAppBillingService.Stub.asInterface(service);
enableActionViews();
}
@Override
public void onServiceDisconnected(ComponentName name) {
mBillingService = null;
}
};
bindService(new Intent("com.android.vending.billing.InAppBillingService.BIND"), mBillingServiceConnection, Context.BIND_AUTO_CREATE);
}
private void disableActionViews () {
findViewById(R.id.action_start_accepted_purchase).setEnabled(false);
findViewById(R.id.action_consume_purchase).setEnabled(false);
findViewById(R.id.action_start_canceled_purchase).setEnabled(false);
}
private void enableActionViews () {
findViewById(R.id.action_start_accepted_purchase).setEnabled(true);
findViewById(R.id.action_consume_purchase).setEnabled(true);
findViewById(R.id.action_start_canceled_purchase).setEnabled(true);
}
private void showResult (final boolean resultOk, final String text) {
final TextView resultView = (TextView)findViewById(R.id.print_purchase_result);
if (resultView != null) {
resultView.setBackgroundColor(getResources().getColor(resultOk ? R.color.result_ok_bg : R.color.result_ko_bg));
resultView.setText(text != null ? text : "");
} else {
Log.w(TAG, "Can't find result view ; nothing done");
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mBillingServiceConnection != null) unbindService(mBillingServiceConnection);
}
protected String getDummyPurchaseToken () {
return DummySku.PURCHASED.getPurchaseToken(true, getPackageName());
}
private void startPurchase (final DummySku skuToPurchase) {
if (mBillingService == null) {
Log.w(TAG, "Purchase attempted while billing service not yet initiated");
return;
}
try {
final BillingActionResponse startPurchaseResult = mPurchaseHelper.startPurchaseAction(this, REQUEST_CODE_PURCHASE, mBillingService, skuToPurchase);
switch (startPurchaseResult) { //エラーが起きた場合はここでフィードバックし、成功した場合はonActivityResultが呼ばれるまで待つ
case CANCELED:
showResult(false, getResources().getString(R.string.error_user_canceled));
break;
case ITEM_UNAVAILABLE:
showResult(false, getResources().getString(R.string.error_item_unavailable));
break;
case ITEM_OWNERSHIP_ERROR:
showResult(false, getResources().getString(R.string.error_item_already_owned));
break;
case INTERNAL_ERROR:
case SERVICE_VERSION_ERROR:
showResult(false, getResources().getString(R.string.error_internal));
break;
default:
//no error, nothing to do until we are called back
break;
}
} catch (final RemoteException remoteException) {
Log.w(TAG, "remote exception while purchase attempt", remoteException);
showResult(false, getResources().getString(R.string.error_internal));
}
}
@Override
protected void onActivityResult (final int requestCode, final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_CODE_PURCHASE:
switch (resultCode) {
case Activity.RESULT_OK :
final Optional<PurchaseData> purchaseResultData = mPurchaseHelper.extractPurchaseActionData(data.getExtras());
final int messageId = purchaseResultData.isPresent() ? R.string.result_purchase_accepted : R.string.error_internal;
showResult(true, getResources().getString(messageId));
if (purchaseResultData.isPresent()) Log.v(TAG, purchaseResultData.get().toString());
break;
case Activity.RESULT_CANCELED:
showResult(false, getResources().getString(R.string.error_user_canceled));
break;
default:
showResult(false, getResources().getString(R.string.error_internal));
break;
}
}
}
public void onStartAcceptedPurchaseClick (final View view) {
startPurchase(DummySku.PURCHASED);
}
public void onStartCanceledPurchaseClick (final View view) {
startPurchase(DummySku.CANCELED);
}
public void onConsumeLastPurchaseClick (final View view) {
final String lastPurchaseToken = getDummyPurchaseToken();
if (lastPurchaseToken != null) {
try {
final BillingActionResponse consumePurchaseResult = mPurchaseHelper.consumePurchase(this, mBillingService, lastPurchaseToken);
final boolean purchaseConsumed = (consumePurchaseResult == BillingActionResponse.DONE);
final int messageId;
if (purchaseConsumed) messageId = R.string.result_purchase_consumed;
else if (consumePurchaseResult == BillingActionResponse.ITEM_OWNERSHIP_ERROR) messageId = R.string.error_item_already_owned;
else messageId = R.string.result_purchase_not_consumed;
showResult(purchaseConsumed, getResources().getString(messageId));
} catch (final RemoteException remoteException) {
Log.w(TAG, "remote exception while consumption attempt", remoteException);
showResult(false, getResources().getString(R.string.error_internal));
}
} else {
showResult(false, getResources().getString(R.string.error_no_purchase_to_consume));
}
}
}