Created
December 12, 2016 21:46
-
-
Save shannah/f998545f0b17f0c412af54ea2db61e35 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.codename1.demos.iapdemosubscribe; | |
import com.codename1.components.SpanLabel; | |
import com.codename1.components.ToastBar; | |
import com.codename1.ui.Display; | |
import com.codename1.ui.Form; | |
import com.codename1.ui.Dialog; | |
import com.codename1.ui.Label; | |
import com.codename1.ui.plaf.UIManager; | |
import com.codename1.ui.util.Resources; | |
import com.codename1.io.Log; | |
import com.codename1.io.Storage; | |
import com.codename1.payment.Purchase; | |
import com.codename1.payment.PurchaseCallback; | |
import com.codename1.payment.Receipt; | |
import com.codename1.payment.ReceiptStore; | |
import com.codename1.ui.Button; | |
import com.codename1.ui.FontImage; | |
import com.codename1.ui.Toolbar; | |
import com.codename1.ui.layouts.BoxLayout; | |
import com.codename1.util.SuccessCallback; | |
import java.io.IOException; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.Calendar; | |
import java.util.Date; | |
import java.util.List; | |
/** | |
* This file was generated by <a href="https://www.codenameone.com/">Codename One</a> for the purpose | |
* of building native mobile applications using Java. | |
*/ | |
public class HelloWorldIAPSubscribe implements PurchaseCallback { | |
private static final String RECEIPTS_KEY = "RECEIPTS.dat"; | |
public static final String SKU_WORLD_1_MONTH = "com.codename1.world.subscribe.1month"; | |
public static final String SKU_WORLD_1_YEAR = "com.codename1.world.subscribe.1year"; | |
public static final String[] PRODUCTS = { | |
SKU_WORLD_1_MONTH, | |
SKU_WORLD_1_YEAR | |
}; | |
private Form current; | |
private Resources theme; | |
public void init(Object context) { | |
theme = UIManager.initFirstTheme("/theme"); | |
// Enable Toolbar on all Forms by default | |
Toolbar.setGlobalToolbar(true); | |
// Pro only feature, uncomment if you have a pro subscription | |
// Log.bindCrashProtection(true); | |
/** | |
* Subscriptions are implemented via a ReceiptStore. | |
* Need to tell CN1 how to "fetch" receipts", and how to submit | |
* a new receipt to the store. | |
*/ | |
Purchase.getInAppPurchase().setReceiptStore(new ReceiptStore() { | |
@Override | |
public void fetchReceipts(SuccessCallback<Receipt[]> callback) { | |
Storage s = Storage.getInstance(); | |
Receipt[] found; | |
synchronized(RECEIPTS_KEY) { | |
if (s.exists(RECEIPTS_KEY)) { | |
List<Receipt> receipts = (List<Receipt>)s.readObject(RECEIPTS_KEY); | |
found = receipts.toArray(new Receipt[receipts.size()]); | |
} else { | |
found = new Receipt[0]; | |
} | |
} | |
// Make sure this is outside the synchronized block | |
callback.onSucess(found); | |
} | |
@Override | |
public void submitReceipt(Receipt receipt, SuccessCallback<Boolean> callback) { | |
Storage s = Storage.getInstance(); | |
synchronized(RECEIPTS_KEY) { | |
List<Receipt> receipts; | |
if (s.exists(RECEIPTS_KEY)) { | |
receipts = (List<Receipt>)s.readObject(RECEIPTS_KEY); | |
} else { | |
receipts = new ArrayList<Receipt>(); | |
} | |
// Check to see if this receipt already exists | |
for (Receipt r : receipts) { | |
if (r.getStoreCode().equals(receipt.getStoreCode()) && | |
r.getTransactionId().equals(receipt.getTransactionId())) { | |
// If we've already got this receipt, we'll just this submission. | |
return; | |
} | |
} | |
// Now try to find the current expiry date | |
Date currExpiry = new Date(); | |
List<String> lProducts = Arrays.asList(PRODUCTS); | |
for (Receipt r : receipts) { | |
if (!lProducts.contains(receipt.getSku())) { | |
continue; | |
} | |
if (r.getCancellationDate() != null) { | |
continue; | |
} | |
if (r.getExpiryDate() == null) { | |
continue; | |
} | |
if (r.getExpiryDate().getTime() > currExpiry.getTime()) { | |
currExpiry = r.getExpiryDate(); | |
} | |
} | |
// Now set the appropriate expiry date by adding time onto | |
// the end of the current expiry date | |
Calendar cal = Calendar.getInstance(); | |
cal.setTime(currExpiry); | |
switch (receipt.getSku()) { | |
case SKU_WORLD_1_MONTH: | |
cal.add(Calendar.MONTH, 1); | |
break; | |
case SKU_WORLD_1_YEAR: | |
cal.add(Calendar.YEAR, 1); | |
} | |
Date newExpiry = cal.getTime(); | |
receipt.setExpiryDate(newExpiry); | |
receipts.add(receipt); | |
s.writeObject(RECEIPTS_KEY, receipts); | |
} | |
// Make sure this is outside the synchronized block | |
callback.onSucess(Boolean.TRUE); | |
} | |
}); | |
} | |
public void start() { | |
if(current != null){ | |
current.show(); | |
return; | |
} | |
Purchase iap = Purchase.getInAppPurchase(); | |
Form hi = new Form("Hi World", new BoxLayout(BoxLayout.Y_AXIS)); | |
Button rentWorld1M = new Button("Rent World 1 Month"); | |
rentWorld1M.addActionListener(e->{ | |
String msg = null; | |
if (iap.isSubscribed(PRODUCTS)) { | |
msg = "You are already renting the world until "+iap.getExpiryDate(PRODUCTS)+". Extend it for one more month?"; | |
} else { | |
msg = "Rent the world for 1 month?"; | |
} | |
if (Dialog.show("Confirm", msg, "Yes", "No")) { | |
Purchase.getInAppPurchase().purchase(SKU_WORLD_1_MONTH); | |
} | |
}); | |
Button rentWorld1Y = new Button("Rent World 1 Year"); | |
rentWorld1Y.addActionListener(e->{ | |
String msg = null; | |
if (iap.isSubscribed(PRODUCTS)) { | |
msg = "You are already renting the world until "+iap.getExpiryDate(PRODUCTS)+". Extend it for one more year?"; | |
} else { | |
msg = "Rent the world for 1 year?"; | |
} | |
if (Dialog.show("Confirm", msg, "Yes", "No")) { | |
Purchase.getInAppPurchase().purchase(SKU_WORLD_1_YEAR); | |
} | |
}); | |
SpanLabel rentalStatus = new SpanLabel("Loading rental details..."); | |
Button syncReceipts = new Button("Synchronize Receipts"); | |
syncReceipts.addActionListener(e->{ | |
iap.synchronizeReceipts(0, res->{ | |
if (iap.isSubscribed(PRODUCTS)) { | |
rentalStatus.setText("World rental expires "+iap.getExpiryDate(PRODUCTS)); | |
} else { | |
rentalStatus.setText("You don't currently have a subscription to the world"); | |
} | |
hi.revalidate(); | |
}); | |
}); | |
hi.add(rentWorld1M).add(rentWorld1Y).add(rentalStatus).add(syncReceipts); | |
hi.show(); | |
// Now synchronize the receipts | |
iap.synchronizeReceipts(0, res->{ | |
if (iap.isSubscribed(PRODUCTS)) { | |
rentalStatus.setText("World rental expires "+iap.getExpiryDate(PRODUCTS)); | |
} else { | |
rentalStatus.setText("You don't currently have a subscription to the world"); | |
} | |
hi.revalidate(); | |
}); | |
} | |
public void stop() { | |
current = Display.getInstance().getCurrent(); | |
if(current instanceof Dialog) { | |
((Dialog)current).dispose(); | |
current = Display.getInstance().getCurrent(); | |
} | |
} | |
public void destroy() { | |
} | |
@Override | |
public void itemPurchased(String sku) { | |
Display.getInstance().callSerially(()->{ | |
Purchase iap = Purchase.getInAppPurchase(); | |
// Force us to reload the receipts from the store. | |
iap.synchronizeReceiptsSync(0); | |
ToastBar.showMessage("Your subscription has been extended to "+iap.getExpiryDate(PRODUCTS), FontImage.MATERIAL_THUMB_UP); | |
}); | |
} | |
@Override | |
public void itemPurchaseError(String sku, String errorMessage) { | |
Display.getInstance().callSerially(()->{ | |
ToastBar.showErrorMessage("Failure occurred: "+errorMessage); | |
}); | |
} | |
@Override | |
public void itemRefunded(String sku) { | |
} | |
@Override | |
public void subscriptionStarted(String sku) { | |
} | |
@Override | |
public void subscriptionCanceled(String sku) { | |
} | |
@Override | |
public void paymentFailed(String paymentCode, String failureReason) { | |
} | |
@Override | |
public void paymentSucceeded(String paymentCode, double amount, String currency) { | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment