+ * In-app product support does not imply subscription support. To check if + * subscriptions are supported, use + * {@link BillingController#checkSubscriptionSupported(Context)}. + *
* * @param context - * @return the current billing status (unknown, supported or unsupported). + * @return the current in-app product billing support status (unknown, + * supported or unsupported). If it is unsupported, subscriptions + * are also unsupported. * @see IBillingObserver#onBillingChecked(boolean) + * @see BillingController#checkSubscriptionSupported(Context) */ public static BillingStatus checkBillingSupported(Context context) { - if (status == BillingStatus.UNKNOWN) { + if (billingStatus == BillingStatus.UNKNOWN) { BillingService.checkBillingSupported(context); } else { - boolean supported = status == BillingStatus.SUPPORTED; + boolean supported = billingStatus == BillingStatus.SUPPORTED; onBillingChecked(supported); } - return status; + return billingStatus; + } + + /** + *+ * Returns the subscription billing support status, and checks it + * asynchronously if it is currently unknown. Observers will receive a + * {@link IBillingObserver#onSubscriptionChecked(boolean)} notification in + * either case. + *
+ *+ * No support for subscriptions does not imply that in-app products are also + * unsupported. To check if in-app products are supported, use + * {@link BillingController#checkBillingSupported(Context)}. + *
+ * + * @param context + * @return the current subscription billing status (unknown, supported or + * unsupported). If it is supported, in-app products are also + * supported. + * @see IBillingObserver#onSubscriptionChecked(boolean) + * @see BillingController#checkBillingSupported(Context) + */ + public static BillingStatus checkSubscriptionSupported(Context context) { + if (subscriptionStatus == BillingStatus.UNKNOWN) { + BillingService.checkSubscriptionSupported(context); + } else { + boolean supported = subscriptionStatus == BillingStatus.SUPPORTED; + onSubscriptionChecked(supported); + } + return subscriptionStatus; } /** @@ -167,7 +206,7 @@ public static int countPurchases(Context context, String itemId) { itemId = salt != null ? Security.obfuscate(context, salt, itemId) : itemId; return TransactionManager.countPurchases(context, itemId); } - + protected static void debug(String message) { if (debug) { Log.d(LOG_TAG, message); @@ -235,9 +274,8 @@ public static List+ * For subscriptions, use {@link #requestSubscription(Context, String)} + * instead. + *
* * @param context * @param itemId * id of the item to be purchased. - * @see #requestPurchase(Context, String, boolean) + * @see #requestPurchase(Context, String, boolean, String) */ public static void requestPurchase(Context context, String itemId) { - requestPurchase(context, itemId, false); + requestPurchase(context, itemId, false, null); } /** + ** Requests the purchase of the specified item with optional automatic * confirmation. + *
+ *+ * For subscriptions, use + * {@link #requestSubscription(Context, String, boolean, String)} instead. + *
+ * + * @param context + * @param itemId + * id of the item to be purchased. + * @param confirm + * if true, the transaction will be confirmed automatically. If + * false, the transaction will have to be confirmed with a call + * to {@link #confirmNotifications(Context, String)}. + * @param developerPayload + * a developer-specified string that contains supplemental + * information about the order. + * @see IBillingObserver#onPurchaseIntent(String, PendingIntent) + */ + public static void requestPurchase(Context context, String itemId, boolean confirm, String developerPayload) { + if (confirm) { + automaticConfirmations.add(itemId); + } + BillingService.requestPurchase(context, itemId, developerPayload); + } + + /** + * Requests the purchase of the specified subscription item. The transaction + * will not be confirmed automatically. + * + * @param context + * @param itemId + * id of the item to be purchased. + * @see #requestSubscription(Context, String, boolean, String) + */ + public static void requestSubscription(Context context, String itemId) { + requestSubscription(context, itemId, false, null); + } + + /** + * Requests the purchase of the specified subscription item with optional + * automatic confirmation. * * @param context * @param itemId @@ -499,13 +606,16 @@ public static void requestPurchase(Context context, String itemId) { * if true, the transaction will be confirmed automatically. If * false, the transaction will have to be confirmed with a call * to {@link #confirmNotifications(Context, String)}. + * @param developerPayload + * a developer-specified string that contains supplemental + * information about the order. * @see IBillingObserver#onPurchaseIntent(String, PendingIntent) */ - public static void requestPurchase(Context context, String itemId, boolean confirm) { + public static void requestSubscription(Context context, String itemId, boolean confirm, String developerPayload) { if (confirm) { automaticConfirmations.add(itemId); } - BillingService.requestPurchase(context, itemId, null); + BillingService.requestSubscription(context, itemId, developerPayload); } /** diff --git a/AndroidBillingLibrary/src/net/robotmedia/billing/BillingRequest.java b/AndroidBillingLibrary/src/net/robotmedia/billing/BillingRequest.java index de69c2d..8362559 100644 --- a/AndroidBillingLibrary/src/net/robotmedia/billing/BillingRequest.java +++ b/AndroidBillingLibrary/src/net/robotmedia/billing/BillingRequest.java @@ -23,7 +23,7 @@ import com.android.vending.billing.IMarketBillingService; public abstract class BillingRequest { - + public static class CheckBillingSupported extends BillingRequest { public CheckBillingSupported(String packageName, int startId) { @@ -32,7 +32,7 @@ public CheckBillingSupported(String packageName, int startId) { @Override public String getRequestType() { - return "CHECK_BILLING_SUPPORTED"; + return REQUEST_TYPE_CHECK_BILLING_SUPPORTED; } @Override @@ -42,6 +42,36 @@ protected void processOkResponse(Bundle response) { } } + + public static class CheckSubscriptionSupported extends BillingRequest { + + public CheckSubscriptionSupported(String packageName, int startId) { + super(packageName, startId); + } + + @Override + protected int getAPIVersion() { + return 2; + }; + + @Override + public String getRequestType() { + return REQUEST_TYPE_CHECK_BILLING_SUPPORTED; + } + + @Override + protected void processOkResponse(Bundle response) { + final boolean supported = this.isSuccess(); + BillingController.onSubscriptionChecked(supported); + } + + @Override + protected void addParams(Bundle request) { + request.putString(KEY_ITEM_TYPE, ITEM_TYPE_SUBSCRIPTION); + } + + } + public static class ConfirmNotifications extends BillingRequest { private String[] notifyIds; @@ -88,6 +118,7 @@ public String getRequestType() { @Override public boolean hasNonce() { return true; } } + public static class RequestPurchase extends BillingRequest { private String itemId; @@ -127,9 +158,27 @@ protected void processOkResponse(Bundle response) { final PendingIntent purchaseIntent = response.getParcelable(KEY_PURCHASE_INTENT); BillingController.onPurchaseIntent(itemId, purchaseIntent); } + + } + + public static class RequestSubscription extends RequestPurchase { + public RequestSubscription(String packageName, int startId, String itemId, String developerPayload) { + super(packageName, startId, itemId, developerPayload); + } + + @Override + protected void addParams(Bundle request) { + super.addParams(request); + request.putString(KEY_ITEM_TYPE, ITEM_TYPE_SUBSCRIPTION); + } + @Override + protected int getAPIVersion() { + return 2; + } } + public static enum ResponseCode { RESULT_OK, // 0 RESULT_USER_CANCELED, // 1 @@ -174,15 +223,16 @@ public void onResponseCode(ResponseCode response) { } } + + public static final String ITEM_TYPE_SUBSCRIPTION = "subs"; + private static final String KEY_API_VERSION = "API_VERSION"; private static final String KEY_BILLING_REQUEST = "BILLING_REQUEST"; - - private static final String KEY_API_VERSION = "API_VERSION"; - private static final String KEY_PACKAGE_NAME = "PACKAGE_NAME"; - private static final String KEY_RESPONSE_CODE = "RESPONSE_CODE"; - - protected static final String KEY_REQUEST_ID = "REQUEST_ID"; - + private static final String KEY_ITEM_TYPE = "ITEM_TYPE"; private static final String KEY_NONCE = "NONCE"; + private static final String KEY_PACKAGE_NAME = "PACKAGE_NAME"; + protected static final String KEY_REQUEST_ID = "REQUEST_ID"; + private static final String KEY_RESPONSE_CODE = "RESPONSE_CODE"; + private static final String REQUEST_TYPE_CHECK_BILLING_SUPPORTED = "CHECK_BILLING_SUPPORTED"; public static final long IGNORE_REQUEST_ID = -1; private String packageName; @@ -198,6 +248,10 @@ public BillingRequest(String packageName,int startId) { protected void addParams(Bundle request) { // Do nothing by default } + + protected int getAPIVersion() { + return 1; + } public long getNonce() { return nonce; @@ -216,7 +270,7 @@ public boolean isSuccess() { protected Bundle makeRequestBundle() { final Bundle request = new Bundle(); request.putString(KEY_BILLING_REQUEST, getRequestType()); - request.putInt(KEY_API_VERSION, 1); + request.putInt(KEY_API_VERSION, getAPIVersion()); request.putString(KEY_PACKAGE_NAME, packageName); if (hasNonce()) { request.putLong(KEY_NONCE, nonce); diff --git a/AndroidBillingLibrary/src/net/robotmedia/billing/BillingService.java b/AndroidBillingLibrary/src/net/robotmedia/billing/BillingService.java index 348e429..a37a1ae 100644 --- a/AndroidBillingLibrary/src/net/robotmedia/billing/BillingService.java +++ b/AndroidBillingLibrary/src/net/robotmedia/billing/BillingService.java @@ -35,12 +35,11 @@ public class BillingService extends Service implements ServiceConnection { private static enum Action { - CHECK_BILLING_SUPPORTED, CONFIRM_NOTIFICATIONS, GET_PURCHASE_INFORMATION, REQUEST_PURCHASE, RESTORE_TRANSACTIONS, + CHECK_BILLING_SUPPORTED, CHECK_SUBSCRIPTION_SUPPORTED, CONFIRM_NOTIFICATIONS, GET_PURCHASE_INFORMATION, REQUEST_PURCHASE, REQUEST_SUBSCRIPTION, RESTORE_TRANSACTIONS } private static final String ACTION_MARKET_BILLING_SERVICE = "com.android.vending.billing.MarketBillingService.BIND"; private static final String EXTRA_DEVELOPER_PAYLOAD = "DEVELOPER_PAYLOAD"; - private static final String EXTRA_ITEM_ID = "ITEM_ID"; private static final String EXTRA_NONCE = "EXTRA_NONCE"; private static final String EXTRA_NOTIFY_IDS = "NOTIFY_IDS"; @@ -53,6 +52,11 @@ public static void checkBillingSupported(Context context) { context.startService(intent); } + public static void checkSubscriptionSupported(Context context) { + final Intent intent = createIntent(context, Action.CHECK_SUBSCRIPTION_SUPPORTED); + context.startService(intent); + } + public static void confirmNotifications(Context context, String[] notifyIds) { final Intent intent = createIntent(context, Action.CONFIRM_NOTIFICATIONS); intent.putExtra(EXTRA_NOTIFY_IDS, notifyIds); @@ -83,6 +87,13 @@ public static void requestPurchase(Context context, String itemId, String develo intent.putExtra(EXTRA_DEVELOPER_PAYLOAD, developerPayload); context.startService(intent); } + + public static void requestSubscription(Context context, String itemId, String developerPayload) { + final Intent intent = createIntent(context, Action.REQUEST_SUBSCRIPTION); + intent.putExtra(EXTRA_ITEM_ID, itemId); + intent.putExtra(EXTRA_DEVELOPER_PAYLOAD, developerPayload); + context.startService(intent); + } public static void restoreTransations(Context context, long nonce) { final Intent intent = createIntent(context, Action.RESTORE_TRANSACTIONS); @@ -107,6 +118,12 @@ private void checkBillingSupported(int startId) { final CheckBillingSupported request = new CheckBillingSupported(packageName, startId); runRequestOrQueue(request); } + + private void checkSubscriptionSupported(int startId) { + final String packageName = getPackageName(); + final CheckSubscriptionSupported request = new CheckSubscriptionSupported(packageName, startId); + runRequestOrQueue(request); + } private void confirmNotifications(Intent intent, int startId) { final String packageName = getPackageName(); @@ -141,13 +158,11 @@ public IBinder onBind(Intent intent) { return null; } - @Override public void onServiceConnected(ComponentName name, IBinder service) { mService = IMarketBillingService.Stub.asInterface(service); runPendingRequests(); } - @Override public void onServiceDisconnected(ComponentName name) { mService = null; } @@ -175,9 +190,15 @@ private void handleCommand(Intent intent, int startId) { case CHECK_BILLING_SUPPORTED: checkBillingSupported(startId); break; + case CHECK_SUBSCRIPTION_SUPPORTED: + checkSubscriptionSupported(startId); + break; case REQUEST_PURCHASE: requestPurchase(intent, startId); break; + case REQUEST_SUBSCRIPTION: + requestSubscription(intent, startId); + break; case GET_PURCHASE_INFORMATION: getPurchaseInformation(intent, startId); break; @@ -196,6 +217,14 @@ private void requestPurchase(Intent intent, int startId) { final RequestPurchase request = new RequestPurchase(packageName, startId, itemId, developerPayload); runRequestOrQueue(request); } + + private void requestSubscription(Intent intent, int startId) { + final String packageName = getPackageName(); + final String itemId = intent.getStringExtra(EXTRA_ITEM_ID); + final String developerPayload = intent.getStringExtra(EXTRA_DEVELOPER_PAYLOAD); + final RequestPurchase request = new RequestSubscription(packageName, startId, itemId, developerPayload); + runRequestOrQueue(request); + } private void restoreTransactions(Intent intent, int startId) { final String packageName = getPackageName(); diff --git a/AndroidBillingLibrary/src/net/robotmedia/billing/IBillingObserver.java b/AndroidBillingLibrary/src/net/robotmedia/billing/IBillingObserver.java index c1c3ae9..59f3ab4 100644 --- a/AndroidBillingLibrary/src/net/robotmedia/billing/IBillingObserver.java +++ b/AndroidBillingLibrary/src/net/robotmedia/billing/IBillingObserver.java @@ -22,14 +22,26 @@ public interface IBillingObserver { /** - * Called only once after determining if in-app billing is supported or not. + * Called after checking if in-app product billing is supported or not. * * @param supported - * if true, in-app billing is supported. Otherwise, it isn't. + * if true, in-app product billing is supported. If false, in-app + * product billing is not supported, and neither is subscription + * billing. * @see BillingController#checkBillingSupported(android.content.Context) */ public void onBillingChecked(boolean supported); + /** + * Called after checking if subscription billing is supported or not. + * + * @param supported + * if true, subscription billing is supported, and also is in-app + * product billing. Otherwise, subscription billing is not + * supported. + */ + public void onSubscriptionChecked(boolean supported); + /** * Called after requesting the purchase of the specified item. * diff --git a/AndroidBillingLibrary/src/net/robotmedia/billing/helper/AbstractBillingActivity.java b/AndroidBillingLibrary/src/net/robotmedia/billing/helper/AbstractBillingActivity.java index c8e978c..4415c05 100644 --- a/AndroidBillingLibrary/src/net/robotmedia/billing/helper/AbstractBillingActivity.java +++ b/AndroidBillingLibrary/src/net/robotmedia/billing/helper/AbstractBillingActivity.java @@ -26,19 +26,54 @@ public abstract class AbstractBillingActivity extends Activity implements Billin protected AbstractBillingObserver mBillingObserver; /** - * Returns the billing status. If it's currently unknown, requests to check - * if billing is supported and - * {@link AbstractBillingActivity#onBillingChecked(boolean)} should be - * called later with the result. + *+ * Returns the in-app product billing support status, and checks it + * asynchronously if it is currently unknown. + * {@link AbstractBillingActivity#onBillingChecked(boolean)} will be called + * eventually with the result. + *
+ *+ * In-app product support does not imply subscription support. To check if + * subscriptions are supported, use + * {@link AbstractBillingActivity#checkSubscriptionSupported()}. + *
* - * @return the current billing status (unknown, supported or unsupported). + * @return the current in-app product billing support status (unknown, + * supported or unsupported). If it is unsupported, subscriptions + * are also unsupported. * @see AbstractBillingActivity#onBillingChecked(boolean) + * @see AbstractBillingActivity#checkSubscriptionSupported() */ public BillingStatus checkBillingSupported() { return BillingController.checkBillingSupported(this); } + /** + *+ * Returns the subscription billing support status, and checks it + * asynchronously if it is currently unknown. + * {@link AbstractBillingActivity#onSubscriptionChecked(boolean)} will be + * called eventually with the result. + *
+ *+ * No support for subscriptions does not imply that in-app products are also + * unsupported. To check if subscriptions are supported, use + * {@link AbstractBillingActivity#checkSubscriptionSupported()}. + *
+ * + * @return the current in-app product billing support status (unknown, + * supported or unsupported). If it is unsupported, subscriptions + * are also unsupported. + * @see AbstractBillingActivity#onBillingChecked(boolean) + * @see AbstractBillingActivity#checkSubscriptionSupported() + */ + public BillingStatus checkSubscriptionSupported() { + return BillingController.checkSubscriptionSupported(this); + } + public abstract void onBillingChecked(boolean supported); + + public abstract void onSubscriptionChecked(boolean supported); @Override protected void onCreate(android.os.Bundle savedInstanceState) { @@ -46,17 +81,18 @@ protected void onCreate(android.os.Bundle savedInstanceState) { mBillingObserver = new AbstractBillingObserver(this) { - @Override public void onBillingChecked(boolean supported) { AbstractBillingActivity.this.onBillingChecked(supported); } + + public void onSubscriptionChecked(boolean supported) { + AbstractBillingActivity.this.onSubscriptionChecked(supported); + } - @Override public void onPurchaseStateChanged(String itemId, PurchaseState state) { AbstractBillingActivity.this.onPurchaseStateChanged(itemId, state); } - @Override public void onRequestPurchaseResponse(String itemId, ResponseCode response) { AbstractBillingActivity.this.onRequestPurchaseResponse(itemId, response); } @@ -99,6 +135,21 @@ public void requestPurchase(String itemId) { BillingController.requestPurchase(this, itemId); } + /** + * Requests the purchase of the specified subscription item. The transaction + * will not be confirmed automatically; such confirmation could be handled + * in {@link AbstractBillingActivity#onPurchaseExecuted(String)}. If + * automatic confirmation is preferred use + * {@link BillingController#requestPurchase(android.content.Context, String, boolean)} + * instead. + * + * @param itemId + * id of the item to be purchased. + */ + public void requestSubscription(String itemId) { + BillingController.requestSubscription(this, itemId); + } + /** * Requests to restore all transactions. */ diff --git a/AndroidBillingLibrary/src/net/robotmedia/billing/helper/AbstractBillingFragment.java b/AndroidBillingLibrary/src/net/robotmedia/billing/helper/AbstractBillingFragment.java new file mode 100644 index 0000000..01644d2 --- /dev/null +++ b/AndroidBillingLibrary/src/net/robotmedia/billing/helper/AbstractBillingFragment.java @@ -0,0 +1,147 @@ +package net.robotmedia.billing.helper; + +import net.robotmedia.billing.BillingController; +import net.robotmedia.billing.BillingController.BillingStatus; +import net.robotmedia.billing.BillingRequest.ResponseCode; +import net.robotmedia.billing.model.Transaction.PurchaseState; +import android.annotation.TargetApi; +import android.app.Fragment; + +@TargetApi(11) +public abstract class AbstractBillingFragment extends Fragment implements BillingController.IConfiguration { + + protected AbstractBillingObserver mBillingObserver; + + /** + *+ * Returns the in-app product billing support status, and checks it + * asynchronously if it is currently unknown. + * {@link AbstractBillingActivity#onBillingChecked(boolean)} will be called + * eventually with the result. + *
+ *+ * In-app product support does not imply subscription support. To check if + * subscriptions are supported, use + * {@link AbstractBillingActivity#checkSubscriptionSupported()}. + *
+ * + * @return the current in-app product billing support status (unknown, + * supported or unsupported). If it is unsupported, subscriptions + * are also unsupported. + * @see AbstractBillingActivity#onBillingChecked(boolean) + * @see AbstractBillingActivity#checkSubscriptionSupported() + */ + public BillingStatus checkBillingSupported() { + return BillingController.checkBillingSupported(getActivity()); + } + + /** + *+ * Returns the subscription billing support status, and checks it + * asynchronously if it is currently unknown. + * {@link AbstractBillingActivity#onSubscriptionChecked(boolean)} will be + * called eventually with the result. + *
+ *+ * No support for subscriptions does not imply that in-app products are also + * unsupported. To check if subscriptions are supported, use + * {@link AbstractBillingActivity#checkSubscriptionSupported()}. + *
+ * + * @return the current in-app product billing support status (unknown, + * supported or unsupported). If it is unsupported, subscriptions + * are also unsupported. + * @see AbstractBillingActivity#onBillingChecked(boolean) + * @see AbstractBillingActivity#checkSubscriptionSupported() + */ + public BillingStatus checkSubscriptionSupported() { + return BillingController.checkSubscriptionSupported(getActivity()); + } + + public abstract void onBillingChecked(boolean supported); + + public abstract void onSubscriptionChecked(boolean supported); + + @Override + public void onCreate(android.os.Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mBillingObserver = new AbstractBillingObserver(getActivity()) { + + public void onBillingChecked(boolean supported) { + AbstractBillingFragment.this.onBillingChecked(supported); + } + + public void onSubscriptionChecked(boolean supported) { + AbstractBillingFragment.this.onSubscriptionChecked(supported); + } + + public void onPurchaseStateChanged(String itemId, PurchaseState state) { + AbstractBillingFragment.this.onPurchaseStateChanged(itemId, state); + } + + public void onRequestPurchaseResponse(String itemId, ResponseCode response) { + AbstractBillingFragment.this.onRequestPurchaseResponse(itemId, response); + } + }; + BillingController.registerObserver(mBillingObserver); + BillingController.setConfiguration(this); // This fragment will provide + // the public key and salt + this.checkBillingSupported(); + if (!mBillingObserver.isTransactionsRestored()) { + BillingController.restoreTransactions(getActivity()); + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + BillingController.unregisterObserver(mBillingObserver); // Avoid + // receiving + // notifications + // after destroy + BillingController.setConfiguration(null); + } + + public abstract void onPurchaseStateChanged(String itemId, PurchaseState state);; + + public abstract void onRequestPurchaseResponse(String itemId, ResponseCode response); + + /** + * Requests the purchase of the specified item. The transaction will not be + * confirmed automatically; such confirmation could be handled in + * {@link AbstractBillingActivity#onPurchaseExecuted(String)}. If automatic + * confirmation is preferred use + * {@link BillingController#requestPurchase(android.content.Context, String, boolean)} + * instead. + * + * @param itemId + * id of the item to be purchased. + */ + public void requestPurchase(String itemId) { + BillingController.requestPurchase(getActivity(), itemId); + } + + /** + * Requests the purchase of the specified subscription item. The transaction + * will not be confirmed automatically; such confirmation could be handled + * in {@link AbstractBillingActivity#onPurchaseExecuted(String)}. If + * automatic confirmation is preferred use + * {@link BillingController#requestPurchase(android.content.Context, String, boolean)} + * instead. + * + * @param itemId + * id of the item to be purchased. + */ + public void requestSubscription(String itemId) { + BillingController.requestSubscription(getActivity(), itemId); + } + + /** + * Requests to restore all transactions. + */ + public void restoreTransactions() { + BillingController.restoreTransactions(getActivity()); + } + +} diff --git a/AndroidBillingLibrary/src/net/robotmedia/billing/helper/AbstractBillingObserver.java b/AndroidBillingLibrary/src/net/robotmedia/billing/helper/AbstractBillingObserver.java index fdea04d..f982d43 100644 --- a/AndroidBillingLibrary/src/net/robotmedia/billing/helper/AbstractBillingObserver.java +++ b/AndroidBillingLibrary/src/net/robotmedia/billing/helper/AbstractBillingObserver.java @@ -53,12 +53,10 @@ public boolean isTransactionsRestored() { * @param purchaseIntent * a purchase pending intent for the specified item. */ - @Override public void onPurchaseIntent(String itemId, PendingIntent purchaseIntent) { BillingController.startPurchaseIntent(activity, purchaseIntent, null); } - @Override public void onTransactionsRestored() { final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity); final Editor editor = preferences.edit(); diff --git a/AndroidBillingLibrary/src/net/robotmedia/billing/model/Transaction.java b/AndroidBillingLibrary/src/net/robotmedia/billing/model/Transaction.java index 297baf8..b3b01e8 100644 --- a/AndroidBillingLibrary/src/net/robotmedia/billing/model/Transaction.java +++ b/AndroidBillingLibrary/src/net/robotmedia/billing/model/Transaction.java @@ -21,10 +21,14 @@ public class Transaction { public enum PurchaseState { - // Responses to requestPurchase or restoreTransactions. - PURCHASED, // 0: User was charged for the order. - CANCELLED, // 1: The charge failed on the server. - REFUNDED; // 2: User received a refund for the order. + // Responses to requestPurchase or restoreTransactions. + PURCHASED, // 0: User was charged for the order. + CANCELLED, // 1: The charge failed on the server. + REFUNDED, // 2: User received a refund for the order. + EXPIRED; // 3: Sent at the end of a billing cycle to indicate that the + // subscription expired without renewal because of + // non-payment or user-cancellation. Your app does not need + // to grant continued access to the subscription content. // Converts from an ordinal value to the PurchaseState public static PurchaseState valueOf(int index) { diff --git a/AndroidBillingLibrary/src/net/robotmedia/billing/security/DefaultSignatureValidator.java b/AndroidBillingLibrary/src/net/robotmedia/billing/security/DefaultSignatureValidator.java index 207b44f..fb9e5db 100644 --- a/AndroidBillingLibrary/src/net/robotmedia/billing/security/DefaultSignatureValidator.java +++ b/AndroidBillingLibrary/src/net/robotmedia/billing/security/DefaultSignatureValidator.java @@ -89,7 +89,6 @@ protected boolean validate(PublicKey publicKey, String signedData, String signat return false; } - @Override public boolean validate(String signedData, String signature) { final String publicKey; if (configuration == null || TextUtils.isEmpty(publicKey = configuration.getPublicKey())) { diff --git a/AndroidBillingLibraryTest/.settings/org.eclipse.jdt.core.prefs b/AndroidBillingLibraryTest/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..f77b31c --- /dev/null +++ b/AndroidBillingLibraryTest/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/AndroidBillingLibraryTest/AndroidManifest.xml b/AndroidBillingLibraryTest/AndroidManifest.xml index 3ced93f..76cda86 100644 --- a/AndroidBillingLibraryTest/AndroidManifest.xml +++ b/AndroidBillingLibraryTest/AndroidManifest.xml @@ -3,7 +3,7 @@ package="net.robotmedia.billing.test" android:versionCode="1" android:versionName="1.0"> -