Finished huawei inapps
This commit is contained in:
parent
a9aa1e5776
commit
ec53a8fc12
10 changed files with 226 additions and 140 deletions
3
OsmAnd/.gitignore
vendored
3
OsmAnd/.gitignore
vendored
|
@ -13,10 +13,13 @@ libs/it.unibo.alice.tuprolog-tuprolog-3.2.1.jar
|
||||||
libs/commons-codec-commons-codec-1.11.jar
|
libs/commons-codec-commons-codec-1.11.jar
|
||||||
libs/OsmAndCore_android-0.1-SNAPSHOT.jar
|
libs/OsmAndCore_android-0.1-SNAPSHOT.jar
|
||||||
|
|
||||||
|
# Huawei
|
||||||
libs/huawei-*.jar
|
libs/huawei-*.jar
|
||||||
huaweidrmlib/
|
huaweidrmlib/
|
||||||
HwDRM_SDK_*
|
HwDRM_SDK_*
|
||||||
drm_strings.xml
|
drm_strings.xml
|
||||||
|
agconnect-services.json
|
||||||
|
OsmAndHms.jks
|
||||||
|
|
||||||
# copy_widget_icons.sh
|
# copy_widget_icons.sh
|
||||||
res/drawable-large/map_*
|
res/drawable-large/map_*
|
||||||
|
|
|
@ -28,10 +28,15 @@ android {
|
||||||
|
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
development {
|
development {
|
||||||
storeFile file("../keystores/debug.keystore")
|
storeFile file('OsmAndHms.jks')
|
||||||
storePassword "android"
|
keyAlias 'OsmAndHms'
|
||||||
keyAlias "androiddebugkey"
|
keyPassword 'targeting'
|
||||||
keyPassword "android"
|
storePassword 'targeting'
|
||||||
|
|
||||||
|
// storeFile file("../keystores/debug.keystore")
|
||||||
|
// storePassword "android"
|
||||||
|
// keyAlias "androiddebugkey"
|
||||||
|
// keyPassword "android"
|
||||||
}
|
}
|
||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
|
|
|
@ -226,6 +226,16 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void manageSubscription(@NonNull Context ctx, @Nullable String sku) {
|
||||||
|
String url = "https://play.google.com/store/account/subscriptions?package=" + ctx.getPackageName();
|
||||||
|
if (!Algorithms.isEmpty(sku)) {
|
||||||
|
url += "&sku=" + sku;
|
||||||
|
}
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||||
|
ctx.startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private SkuDetails getSkuDetails(@NonNull String sku) {
|
private SkuDetails getSkuDetails(@NonNull String sku) {
|
||||||
List<SkuDetails> skuDetailsList = this.skuDetailsList;
|
List<SkuDetails> skuDetailsList = this.skuDetailsList;
|
||||||
|
|
|
@ -37,7 +37,7 @@ import java.security.spec.X509EncodedKeySpec;
|
||||||
public class CipherUtil {
|
public class CipherUtil {
|
||||||
private static final String TAG = "CipherUtil";
|
private static final String TAG = "CipherUtil";
|
||||||
private static final String SIGN_ALGORITHMS = "SHA256WithRSA";
|
private static final String SIGN_ALGORITHMS = "SHA256WithRSA";
|
||||||
private static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAooen3X9jSWarxugznzzMSvp4zir1Pg6uPOm7fqlLOL0Ix52e5FpeotMx871pQ9hrCkiyFg2e6UxD8IXXjvK6QJQbjNJ2jIfKkCusm90yloSEfvyLeiq5y7zg4+DoPglHi8RxZ9y308YIqnRDoslfGm5DnWa8RKUvFRVRiu1p3FN4SYIa/FWLtS5yygemtqMJi8I14V7xqQ5wExCGeSA6j1/AAWXEwZncJwKn0BTXQSvwVBPBRM5ksgt4q+Sc484ZIbntATyxsUipnEBFxq1OXn5Zw5/vVxUC8RSyDMQ/kC2RaEcFtA1tlIIjIdurbpNg3tyViPfQUQndvOs4nDrFzwIDAQAB";
|
private static final String PUBLIC_KEY = "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAsB+oH8rYQncwpTqGa0kS/5E725HJrq2sW1ThAZtmorYVi52Yt9PmZvNDz7284ol9C2skrKQR34eIer8Tr7Qqq3mlNo+/LVUpq9sa++kB2glaG6jj5NNjM3w4nVYHFIYkd5AQhodJgmqFvnp2s7r7YmyQVXZSehei5bA1G70Bs+El9cSv9shNNGTCaU3ARUu2hy3Ltkc/ov7/ZYYpiwjbyD3cmoMh9jO1++zztXb2phjv1h9zeJOp1i6HsotZll+c9J4jjV3GhrF+ZJm5WrSzGLDLtwSldRpMZFxrSvAJJstjzhDz3LpUM+nPV3HZ5VQ/xosmwWYmiibo89E1gw8p73NTBXHzuQMJcTJ6vTjD8LeMskpXHZUAGhifmFLGN1LbNP9662ulCV12kIbXuzWCwwi/h0DWqmnjKmLvzc88e4BrGrp2zZUnHz7m15voPG+4cQ3z9+cwS4gEI3SUTiFyQGE539SO/11VkkQAJ8P7du1JFNqQw5ZEW3AoE1iUsp5XAgMBAAE=";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the method to check the signature for the data returned from the interface
|
* the method to check the signature for the data returned from the interface
|
||||||
|
@ -65,7 +65,7 @@ public class CipherUtil {
|
||||||
java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
|
java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
|
||||||
|
|
||||||
signature.initVerify(pubKey);
|
signature.initVerify(pubKey);
|
||||||
signature.update(content.getBytes("utf-8"));
|
signature.update(content.getBytes("UTF-8"));
|
||||||
|
|
||||||
boolean bverify = signature.verify(Base64.decode(sign, Base64.DEFAULT));
|
boolean bverify = signature.verify(Base64.decode(sign, Base64.DEFAULT));
|
||||||
return bverify;
|
return bverify;
|
||||||
|
|
|
@ -8,6 +8,9 @@ import android.text.TextUtils;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.huawei.hmf.tasks.OnFailureListener;
|
||||||
|
import com.huawei.hmf.tasks.OnSuccessListener;
|
||||||
|
import com.huawei.hmf.tasks.Task;
|
||||||
import com.huawei.hms.iap.Iap;
|
import com.huawei.hms.iap.Iap;
|
||||||
import com.huawei.hms.iap.IapClient;
|
import com.huawei.hms.iap.IapClient;
|
||||||
import com.huawei.hms.iap.entity.InAppPurchaseData;
|
import com.huawei.hms.iap.entity.InAppPurchaseData;
|
||||||
|
@ -18,12 +21,15 @@ import com.huawei.hms.iap.entity.ProductInfo;
|
||||||
import com.huawei.hms.iap.entity.ProductInfoResult;
|
import com.huawei.hms.iap.entity.ProductInfoResult;
|
||||||
import com.huawei.hms.iap.entity.PurchaseIntentResult;
|
import com.huawei.hms.iap.entity.PurchaseIntentResult;
|
||||||
import com.huawei.hms.iap.entity.PurchaseResultInfo;
|
import com.huawei.hms.iap.entity.PurchaseResultInfo;
|
||||||
|
import com.huawei.hms.iap.entity.StartIapActivityReq;
|
||||||
|
import com.huawei.hms.iap.entity.StartIapActivityResult;
|
||||||
|
|
||||||
import net.osmand.AndroidUtils;
|
import net.osmand.AndroidUtils;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.inapp.InAppPurchases.InAppPurchase;
|
import net.osmand.plus.inapp.InAppPurchases.InAppPurchase;
|
||||||
import net.osmand.plus.inapp.InAppPurchases.InAppSubscription;
|
import net.osmand.plus.inapp.InAppPurchases.InAppSubscription;
|
||||||
import net.osmand.plus.inapp.InAppPurchases.InAppSubscriptionIntroductoryInfo;
|
import net.osmand.plus.inapp.InAppPurchases.InAppSubscriptionIntroductoryInfo;
|
||||||
|
import net.osmand.plus.inapp.InAppPurchasesImpl.InAppPurchaseLiveUpdatesOldSubscription;
|
||||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||||
import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference;
|
import net.osmand.plus.settings.backend.OsmandSettings.OsmandPreference;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
@ -109,33 +115,37 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
||||||
public void run(InAppPurchaseHelper helper) {
|
public void run(InAppPurchaseHelper helper) {
|
||||||
try {
|
try {
|
||||||
ProductInfo productInfo = getProductInfo(productId);
|
ProductInfo productInfo = getProductInfo(productId);
|
||||||
IapRequestHelper.createPurchaseIntent(getIapClient(), productInfo.getProductId(),
|
if (productInfo != null) {
|
||||||
IapClient.PriceType.IN_APP_NONCONSUMABLE, new IapApiCallback<PurchaseIntentResult>() {
|
IapRequestHelper.createPurchaseIntent(getIapClient(), productInfo.getProductId(),
|
||||||
@Override
|
IapClient.PriceType.IN_APP_NONCONSUMABLE, new IapApiCallback<PurchaseIntentResult>() {
|
||||||
public void onSuccess(PurchaseIntentResult result) {
|
@Override
|
||||||
if (result == null) {
|
public void onSuccess(PurchaseIntentResult result) {
|
||||||
logError("result is null");
|
if (result == null) {
|
||||||
} else {
|
logError("result is null");
|
||||||
// you should pull up the page to complete the payment process
|
|
||||||
IapRequestHelper.startResolutionForResult(activity, result.getStatus(), Constants.REQ_CODE_BUY_INAPP);
|
|
||||||
}
|
|
||||||
commandDone();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFail(Exception e) {
|
|
||||||
int errorCode = ExceptionHandle.handle(activity, e);
|
|
||||||
if (errorCode != ExceptionHandle.SOLVED) {
|
|
||||||
logDebug("createPurchaseIntent, returnCode: " + errorCode);
|
|
||||||
if (OrderStatusCode.ORDER_PRODUCT_OWNED == errorCode) {
|
|
||||||
logError("already own this product");
|
|
||||||
} else {
|
} else {
|
||||||
logError("unknown error");
|
// you should pull up the page to complete the payment process
|
||||||
|
IapRequestHelper.startResolutionForResult(activity, result.getStatus(), Constants.REQ_CODE_BUY_INAPP);
|
||||||
}
|
}
|
||||||
|
commandDone();
|
||||||
}
|
}
|
||||||
commandDone();
|
|
||||||
}
|
@Override
|
||||||
});
|
public void onFail(Exception e) {
|
||||||
|
int errorCode = ExceptionHandle.handle(activity, e);
|
||||||
|
if (errorCode != ExceptionHandle.SOLVED) {
|
||||||
|
logDebug("createPurchaseIntent, returnCode: " + errorCode);
|
||||||
|
if (OrderStatusCode.ORDER_PRODUCT_OWNED == errorCode) {
|
||||||
|
logError("already own this product");
|
||||||
|
} else {
|
||||||
|
logError("unknown error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
commandDone();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
commandDone();
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
complain("Cannot launch full version purchase!");
|
complain("Cannot launch full version purchase!");
|
||||||
logError("purchaseFullVersion Error", e);
|
logError("purchaseFullVersion Error", e);
|
||||||
|
@ -148,13 +158,42 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
||||||
@Override
|
@Override
|
||||||
public void purchaseFullVersion(@NonNull final Activity activity) throws UnsupportedOperationException {
|
public void purchaseFullVersion(@NonNull final Activity activity) throws UnsupportedOperationException {
|
||||||
notifyShowProgress(InAppPurchaseTaskType.PURCHASE_FULL_VERSION);
|
notifyShowProgress(InAppPurchaseTaskType.PURCHASE_FULL_VERSION);
|
||||||
exec(InAppPurchaseTaskType.PURCHASE_FULL_VERSION, getPurchaseInAppCommand(activity, ""));
|
exec(InAppPurchaseTaskType.PURCHASE_FULL_VERSION, getPurchaseInAppCommand(activity, purchases.getFullVersion().getSku()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void purchaseDepthContours(@NonNull final Activity activity) throws UnsupportedOperationException {
|
public void purchaseDepthContours(@NonNull final Activity activity) throws UnsupportedOperationException {
|
||||||
notifyShowProgress(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS);
|
notifyShowProgress(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS);
|
||||||
exec(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS, getPurchaseInAppCommand(activity, ""));
|
exec(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS, getPurchaseInAppCommand(activity, purchases.getDepthContours().getSku()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void manageSubscription(@NonNull Context ctx, @Nullable String sku) {
|
||||||
|
if (uiActivity != null) {
|
||||||
|
StartIapActivityReq req = new StartIapActivityReq();
|
||||||
|
if (!Algorithms.isEmpty(sku)) {
|
||||||
|
req.setSubscribeProductId(sku);
|
||||||
|
req.setType(StartIapActivityReq.TYPE_SUBSCRIBE_EDIT_ACTIVITY);
|
||||||
|
} else {
|
||||||
|
req.setType(StartIapActivityReq.TYPE_SUBSCRIBE_MANAGER_ACTIVITY);
|
||||||
|
}
|
||||||
|
Task<StartIapActivityResult> task = getIapClient().startIapActivity(req);
|
||||||
|
task.addOnSuccessListener(new OnSuccessListener<StartIapActivityResult>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(StartIapActivityResult result) {
|
||||||
|
logDebug("startIapActivity: onSuccess");
|
||||||
|
Activity activity = (Activity) uiActivity;
|
||||||
|
if (result != null && AndroidUtils.isActivityNotDestroyed(activity)) {
|
||||||
|
result.startActivity(activity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).addOnFailureListener(new OnFailureListener() {
|
||||||
|
@Override
|
||||||
|
public void onFailure(Exception e) {
|
||||||
|
logDebug("startIapActivity: onFailure");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -285,16 +324,18 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
||||||
protected InAppCommand getRequestInventoryCommand() {
|
protected InAppCommand getRequestInventoryCommand() {
|
||||||
return new InAppCommand() {
|
return new InAppCommand() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void commandDone() {
|
||||||
|
super.commandDone();
|
||||||
|
inventoryRequested = false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(InAppPurchaseHelper helper) {
|
public void run(InAppPurchaseHelper helper) {
|
||||||
logDebug("Setup successful. Querying inventory.");
|
logDebug("Setup successful. Querying inventory.");
|
||||||
try {
|
try {
|
||||||
productInfos = new ArrayList<>();
|
productInfos = new ArrayList<>();
|
||||||
if (uiActivity != null) {
|
obtainOwnedSubscriptions();
|
||||||
obtainOwnedSubscriptions();
|
|
||||||
} else {
|
|
||||||
commandDone();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logError("queryInventoryAsync Error", e);
|
logError("queryInventoryAsync Error", e);
|
||||||
notifyDismissProgress(InAppPurchaseTaskType.REQUEST_INVENTORY);
|
notifyDismissProgress(InAppPurchaseTaskType.REQUEST_INVENTORY);
|
||||||
|
@ -326,92 +367,95 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void obtainOwnedInApps(final String continuationToken) {
|
private void obtainOwnedInApps(final String continuationToken) {
|
||||||
// Query users' purchased non-consumable products.
|
if (uiActivity != null) {
|
||||||
IapRequestHelper.obtainOwnedPurchases(getIapClient(), IapClient.PriceType.IN_APP_NONCONSUMABLE,
|
// Query users' purchased non-consumable products.
|
||||||
continuationToken, new IapApiCallback<OwnedPurchasesResult>() {
|
IapRequestHelper.obtainOwnedPurchases(getIapClient(), IapClient.PriceType.IN_APP_NONCONSUMABLE,
|
||||||
@Override
|
continuationToken, new IapApiCallback<OwnedPurchasesResult>() {
|
||||||
public void onSuccess(OwnedPurchasesResult result) {
|
@Override
|
||||||
ownedInApps.add(result);
|
public void onSuccess(OwnedPurchasesResult result) {
|
||||||
if (result != null && !TextUtils.isEmpty(result.getContinuationToken())) {
|
ownedInApps.add(result);
|
||||||
obtainOwnedInApps(result.getContinuationToken());
|
if (result != null && !TextUtils.isEmpty(result.getContinuationToken())) {
|
||||||
} else {
|
obtainOwnedInApps(result.getContinuationToken());
|
||||||
obtainSubscriptionsInfo();
|
} else {
|
||||||
|
obtainSubscriptionsInfo();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFail(Exception e) {
|
|
||||||
logError("obtainOwnedInApps exception", e);
|
|
||||||
ExceptionHandle.handle((Activity) uiActivity, e);
|
|
||||||
commandDone();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFail(Exception e) {
|
||||||
|
logError("obtainOwnedInApps exception", e);
|
||||||
|
ExceptionHandle.handle((Activity) uiActivity, e);
|
||||||
|
commandDone();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
commandDone();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void obtainSubscriptionsInfo() {
|
private void obtainSubscriptionsInfo() {
|
||||||
Set<String> productIds = new HashSet<>();
|
if (uiActivity != null) {
|
||||||
List<InAppSubscription> subscriptions = purchases.getLiveUpdates().getAllSubscriptions();
|
Set<String> productIds = new HashSet<>();
|
||||||
for (InAppSubscription s : subscriptions) {
|
List<InAppSubscription> subscriptions = purchases.getLiveUpdates().getAllSubscriptions();
|
||||||
productIds.add(s.getSku());
|
for (InAppSubscription s : subscriptions) {
|
||||||
}
|
productIds.add(s.getSku());
|
||||||
productIds.addAll(ownedSubscriptions.getItemList());
|
}
|
||||||
IapRequestHelper.obtainProductInfo(getIapClient(), new ArrayList<>(productIds),
|
productIds.addAll(ownedSubscriptions.getItemList());
|
||||||
IapClient.PriceType.IN_APP_SUBSCRIPTION, new IapApiCallback<ProductInfoResult>() {
|
IapRequestHelper.obtainProductInfo(getIapClient(), new ArrayList<>(productIds),
|
||||||
@Override
|
IapClient.PriceType.IN_APP_SUBSCRIPTION, new IapApiCallback<ProductInfoResult>() {
|
||||||
public void onSuccess(final ProductInfoResult result) {
|
@Override
|
||||||
if (result == null) {
|
public void onSuccess(final ProductInfoResult result) {
|
||||||
logError("obtainSubscriptionsInfo: ProductInfoResult is null");
|
if (result != null && result.getProductInfoList() != null) {
|
||||||
commandDone();
|
productInfos.addAll(result.getProductInfoList());
|
||||||
return;
|
}
|
||||||
|
obtainInAppsInfo();
|
||||||
}
|
}
|
||||||
productInfos.addAll(result.getProductInfoList());
|
|
||||||
obtainInAppsInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFail(Exception e) {
|
public void onFail(Exception e) {
|
||||||
int errorCode = ExceptionHandle.handle((Activity) uiActivity, e);
|
int errorCode = ExceptionHandle.handle((Activity) uiActivity, e);
|
||||||
if (ExceptionHandle.SOLVED != errorCode) {
|
if (ExceptionHandle.SOLVED != errorCode) {
|
||||||
LOG.error("Unknown error");
|
LOG.error("Unknown error");
|
||||||
|
}
|
||||||
|
commandDone();
|
||||||
}
|
}
|
||||||
commandDone();
|
});
|
||||||
}
|
} else {
|
||||||
});
|
commandDone();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void obtainInAppsInfo() {
|
private void obtainInAppsInfo() {
|
||||||
Set<String> productIds = new HashSet<>();
|
if (uiActivity != null) {
|
||||||
for (InAppPurchase purchase : getInAppPurchases().getAllInAppPurchases(false)) {
|
Set<String> productIds = new HashSet<>();
|
||||||
productIds.add(purchase.getSku());
|
for (InAppPurchase purchase : getInAppPurchases().getAllInAppPurchases(false)) {
|
||||||
}
|
productIds.add(purchase.getSku());
|
||||||
for (OwnedPurchasesResult result : ownedInApps) {
|
}
|
||||||
productIds.addAll(result.getItemList());
|
for (OwnedPurchasesResult result : ownedInApps) {
|
||||||
}
|
productIds.addAll(result.getItemList());
|
||||||
IapRequestHelper.obtainProductInfo(getIapClient(), new ArrayList<>(productIds),
|
}
|
||||||
IapClient.PriceType.IN_APP_NONCONSUMABLE, new IapApiCallback<ProductInfoResult>() {
|
IapRequestHelper.obtainProductInfo(getIapClient(), new ArrayList<>(productIds),
|
||||||
@Override
|
IapClient.PriceType.IN_APP_NONCONSUMABLE, new IapApiCallback<ProductInfoResult>() {
|
||||||
public void onSuccess(ProductInfoResult result) {
|
@Override
|
||||||
if (result == null || result.getProductInfoList() == null) {
|
public void onSuccess(ProductInfoResult result) {
|
||||||
logError("obtainInAppsInfo: ProductInfoResult is null");
|
if (result != null && result.getProductInfoList() != null) {
|
||||||
|
productInfos.addAll(result.getProductInfoList());
|
||||||
|
}
|
||||||
|
processInventory();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFail(Exception e) {
|
||||||
|
int errorCode = ExceptionHandle.handle((Activity) uiActivity, e);
|
||||||
|
if (ExceptionHandle.SOLVED != errorCode) {
|
||||||
|
LOG.error("Unknown error");
|
||||||
|
}
|
||||||
commandDone();
|
commandDone();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
productInfos.addAll(result.getProductInfoList());
|
});
|
||||||
|
} else {
|
||||||
processInventory();
|
commandDone();
|
||||||
commandDone();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFail(Exception e) {
|
|
||||||
int errorCode = ExceptionHandle.handle((Activity) uiActivity, e);
|
|
||||||
if (ExceptionHandle.SOLVED != errorCode) {
|
|
||||||
LOG.error("Unknown error");
|
|
||||||
}
|
|
||||||
commandDone();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processInventory() {
|
private void processInventory() {
|
||||||
|
@ -579,17 +623,31 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
||||||
if (resultCode == Activity.RESULT_OK) {
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
PurchaseResultInfo result = SubscriptionUtils.getPurchaseResult(activity, data);
|
PurchaseResultInfo result = SubscriptionUtils.getPurchaseResult(activity, data);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
if (OrderStatusCode.ORDER_STATE_SUCCESS == result.getReturnCode()) {
|
switch (result.getReturnCode()) {
|
||||||
InAppPurchaseData purchaseData = SubscriptionUtils.getInAppPurchaseData(null,
|
case OrderStatusCode.ORDER_STATE_CANCEL:
|
||||||
result.getInAppPurchaseData(), result.getInAppDataSignature());
|
logDebug("Purchase cancelled");
|
||||||
if (purchaseData != null) {
|
break;
|
||||||
onPurchaseFinished(purchaseData);
|
case OrderStatusCode.ORDER_STATE_FAILED:
|
||||||
succeed = true;
|
inventoryRequestPending = true;
|
||||||
} else {
|
|
||||||
logDebug("Purchase failed");
|
logDebug("Purchase failed");
|
||||||
}
|
break;
|
||||||
} else if (OrderStatusCode.ORDER_STATE_CANCEL == result.getReturnCode()) {
|
case OrderStatusCode.ORDER_PRODUCT_OWNED:
|
||||||
logDebug("Purchase cancelled");
|
inventoryRequestPending = true;
|
||||||
|
logDebug("Product already owned");
|
||||||
|
break;
|
||||||
|
case OrderStatusCode.ORDER_STATE_SUCCESS:
|
||||||
|
inventoryRequestPending = true;
|
||||||
|
InAppPurchaseData purchaseData = SubscriptionUtils.getInAppPurchaseData(null,
|
||||||
|
result.getInAppPurchaseData(), result.getInAppDataSignature());
|
||||||
|
if (purchaseData != null) {
|
||||||
|
onPurchaseFinished(purchaseData);
|
||||||
|
succeed = true;
|
||||||
|
} else {
|
||||||
|
logDebug("Purchase failed");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logDebug("Purchase failed");
|
logDebug("Purchase failed");
|
||||||
|
@ -611,7 +669,12 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
||||||
case OrderStatusCode.ORDER_STATE_CANCEL:
|
case OrderStatusCode.ORDER_STATE_CANCEL:
|
||||||
logDebug("Order has been canceled");
|
logDebug("Order has been canceled");
|
||||||
break;
|
break;
|
||||||
|
case OrderStatusCode.ORDER_STATE_FAILED:
|
||||||
|
inventoryRequestPending = true;
|
||||||
|
logDebug("Order has been failed");
|
||||||
|
break;
|
||||||
case OrderStatusCode.ORDER_PRODUCT_OWNED:
|
case OrderStatusCode.ORDER_PRODUCT_OWNED:
|
||||||
|
inventoryRequestPending = true;
|
||||||
logDebug("Product already owned");
|
logDebug("Product already owned");
|
||||||
break;
|
break;
|
||||||
case OrderStatusCode.ORDER_STATE_SUCCESS:
|
case OrderStatusCode.ORDER_STATE_SUCCESS:
|
||||||
|
|
|
@ -5,6 +5,8 @@ import android.content.Context;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.huawei.hms.iap.entity.ProductInfo;
|
||||||
|
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
|
|
||||||
|
@ -26,8 +28,18 @@ public class InAppPurchasesImpl extends InAppPurchases {
|
||||||
fullVersion = FULL_VERSION;
|
fullVersion = FULL_VERSION;
|
||||||
depthContours = DEPTH_CONTOURS_FREE;
|
depthContours = DEPTH_CONTOURS_FREE;
|
||||||
contourLines = CONTOUR_LINES_FREE;
|
contourLines = CONTOUR_LINES_FREE;
|
||||||
liveUpdates = new LiveUpdatesInAppPurchasesFree();
|
|
||||||
inAppPurchases = new InAppPurchase[] { fullVersion, depthContours, contourLines };
|
inAppPurchases = new InAppPurchase[] { fullVersion, depthContours, contourLines };
|
||||||
|
|
||||||
|
liveUpdates = new LiveUpdatesInAppPurchasesFree();
|
||||||
|
for (InAppSubscription s : liveUpdates.getAllSubscriptions()) {
|
||||||
|
if (s instanceof InAppPurchaseLiveUpdatesMonthly) {
|
||||||
|
if (s.isDiscounted()) {
|
||||||
|
discountedMonthlyLiveUpdates = s;
|
||||||
|
} else {
|
||||||
|
monthlyLiveUpdates = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -57,7 +69,7 @@ public class InAppPurchasesImpl extends InAppPurchases {
|
||||||
|
|
||||||
private static class InAppPurchaseFullVersion extends InAppPurchase {
|
private static class InAppPurchaseFullVersion extends InAppPurchase {
|
||||||
|
|
||||||
private static final String SKU_FULL_VERSION_PRICE = "osmand_full_version_price";
|
private static final String SKU_FULL_VERSION_PRICE = "net.osmand.huawei.full";
|
||||||
|
|
||||||
InAppPurchaseFullVersion() {
|
InAppPurchaseFullVersion() {
|
||||||
super(SKU_FULL_VERSION_PRICE);
|
super(SKU_FULL_VERSION_PRICE);
|
||||||
|
@ -71,7 +83,7 @@ public class InAppPurchasesImpl extends InAppPurchases {
|
||||||
|
|
||||||
private static class InAppPurchaseDepthContoursFree extends InAppPurchaseDepthContours {
|
private static class InAppPurchaseDepthContoursFree extends InAppPurchaseDepthContours {
|
||||||
|
|
||||||
private static final String SKU_DEPTH_CONTOURS_FREE = "net.osmand.seadepth";
|
private static final String SKU_DEPTH_CONTOURS_FREE = "net.osmand.huawei.seadepth";
|
||||||
|
|
||||||
InAppPurchaseDepthContoursFree() {
|
InAppPurchaseDepthContoursFree() {
|
||||||
super(SKU_DEPTH_CONTOURS_FREE);
|
super(SKU_DEPTH_CONTOURS_FREE);
|
||||||
|
@ -80,7 +92,7 @@ public class InAppPurchasesImpl extends InAppPurchases {
|
||||||
|
|
||||||
private static class InAppPurchaseContourLinesFree extends InAppPurchaseContourLines {
|
private static class InAppPurchaseContourLinesFree extends InAppPurchaseContourLines {
|
||||||
|
|
||||||
private static final String SKU_CONTOUR_LINES_FREE = "net.osmand.contourlines";
|
private static final String SKU_CONTOUR_LINES_FREE = "net.osmand.huawei.contourlines";
|
||||||
|
|
||||||
InAppPurchaseContourLinesFree() {
|
InAppPurchaseContourLinesFree() {
|
||||||
super(SKU_CONTOUR_LINES_FREE);
|
super(SKU_CONTOUR_LINES_FREE);
|
||||||
|
@ -89,7 +101,7 @@ public class InAppPurchasesImpl extends InAppPurchases {
|
||||||
|
|
||||||
private static class InAppPurchaseLiveUpdatesMonthlyFree extends InAppPurchaseLiveUpdatesMonthly {
|
private static class InAppPurchaseLiveUpdatesMonthlyFree extends InAppPurchaseLiveUpdatesMonthly {
|
||||||
|
|
||||||
private static final String SKU_LIVE_UPDATES_MONTHLY_HW_FREE = "net.osmand.test.monthly";
|
private static final String SKU_LIVE_UPDATES_MONTHLY_HW_FREE = "net.osmand.huawei.monthly";
|
||||||
|
|
||||||
InAppPurchaseLiveUpdatesMonthlyFree() {
|
InAppPurchaseLiveUpdatesMonthlyFree() {
|
||||||
super(SKU_LIVE_UPDATES_MONTHLY_HW_FREE, 1);
|
super(SKU_LIVE_UPDATES_MONTHLY_HW_FREE, 1);
|
||||||
|
@ -108,7 +120,7 @@ public class InAppPurchasesImpl extends InAppPurchases {
|
||||||
|
|
||||||
private static class InAppPurchaseLiveUpdates3MonthsFree extends InAppPurchaseLiveUpdates3Months {
|
private static class InAppPurchaseLiveUpdates3MonthsFree extends InAppPurchaseLiveUpdates3Months {
|
||||||
|
|
||||||
private static final String SKU_LIVE_UPDATES_3_MONTHS_HW_FREE = "net.osmand.test.3months";
|
private static final String SKU_LIVE_UPDATES_3_MONTHS_HW_FREE = "net.osmand.huawei.3months";
|
||||||
|
|
||||||
InAppPurchaseLiveUpdates3MonthsFree() {
|
InAppPurchaseLiveUpdates3MonthsFree() {
|
||||||
super(SKU_LIVE_UPDATES_3_MONTHS_HW_FREE, 1);
|
super(SKU_LIVE_UPDATES_3_MONTHS_HW_FREE, 1);
|
||||||
|
@ -127,7 +139,7 @@ public class InAppPurchasesImpl extends InAppPurchases {
|
||||||
|
|
||||||
private static class InAppPurchaseLiveUpdatesAnnualFree extends InAppPurchaseLiveUpdatesAnnual {
|
private static class InAppPurchaseLiveUpdatesAnnualFree extends InAppPurchaseLiveUpdatesAnnual {
|
||||||
|
|
||||||
private static final String SKU_LIVE_UPDATES_ANNUAL_HW_FREE = "net.osmand.test.annual";
|
private static final String SKU_LIVE_UPDATES_ANNUAL_HW_FREE = "net.osmand.huawei.annual";
|
||||||
|
|
||||||
InAppPurchaseLiveUpdatesAnnualFree() {
|
InAppPurchaseLiveUpdatesAnnualFree() {
|
||||||
super(SKU_LIVE_UPDATES_ANNUAL_HW_FREE, 1);
|
super(SKU_LIVE_UPDATES_ANNUAL_HW_FREE, 1);
|
||||||
|
|
|
@ -120,9 +120,8 @@ public class SubscriptionUtils {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "check the data signature fail");
|
Log.e(TAG, "check the data signature fail");
|
||||||
|
return getFailedPurchaseResultInfo();
|
||||||
}
|
}
|
||||||
return getFailedPurchaseResultInfo();
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Log.e(TAG, "returnCode: " + returnCode + " , errMsg: " + errMsg);
|
Log.e(TAG, "returnCode: " + returnCode + " , errMsg: " + errMsg);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -428,7 +428,7 @@ public abstract class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment
|
||||||
buttonCancelView.setOnClickListener(new OnClickListener() {
|
buttonCancelView.setOnClickListener(new OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
manageSubscription(ctx, s.getSku());
|
purchaseHelper.manageSubscription(ctx, s.getSku());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
div.setVisibility(View.VISIBLE);
|
div.setVisibility(View.VISIBLE);
|
||||||
|
@ -538,15 +538,6 @@ public abstract class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void manageSubscription(@NonNull Context ctx, @Nullable String sku) {
|
|
||||||
String url = "https://play.google.com/store/account/subscriptions?package=" + ctx.getPackageName();
|
|
||||||
if (!Algorithms.isEmpty(sku)) {
|
|
||||||
url += "&sku=" + sku;
|
|
||||||
}
|
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ViewGroup buildPlanTypeCard(@NonNull Context ctx, ViewGroup container) {
|
private ViewGroup buildPlanTypeCard(@NonNull Context ctx, ViewGroup container) {
|
||||||
if (getPlanTypeFeatures().length == 0) {
|
if (getPlanTypeFeatures().length == 0) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -2,6 +2,7 @@ package net.osmand.plus.inapp;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
@ -265,6 +266,8 @@ public abstract class InAppPurchaseHelper {
|
||||||
|
|
||||||
public abstract void purchaseDepthContours(@NonNull final Activity activity) throws UnsupportedOperationException;
|
public abstract void purchaseDepthContours(@NonNull final Activity activity) throws UnsupportedOperationException;
|
||||||
|
|
||||||
|
public abstract void manageSubscription(@NonNull Context ctx, @Nullable String sku);
|
||||||
|
|
||||||
@SuppressLint("StaticFieldLeak")
|
@SuppressLint("StaticFieldLeak")
|
||||||
private class LiveUpdatesPurchaseTask extends AsyncTask<Void, Void, String> {
|
private class LiveUpdatesPurchaseTask extends AsyncTask<Void, Void, String> {
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ public abstract class InAppPurchases {
|
||||||
public InAppSubscription getPurchasedMonthlyLiveUpdates() {
|
public InAppSubscription getPurchasedMonthlyLiveUpdates() {
|
||||||
if (monthlyLiveUpdates.isAnyPurchased()) {
|
if (monthlyLiveUpdates.isAnyPurchased()) {
|
||||||
return monthlyLiveUpdates;
|
return monthlyLiveUpdates;
|
||||||
} else if (discountedMonthlyLiveUpdates.isAnyPurchased()) {
|
} else if (discountedMonthlyLiveUpdates != null && discountedMonthlyLiveUpdates.isAnyPurchased()) {
|
||||||
return discountedMonthlyLiveUpdates;
|
return discountedMonthlyLiveUpdates;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
Loading…
Reference in a new issue