Merge branch 'master' into fix-alignment
# Conflicts: # OsmAnd/src/net/osmand/plus/widgets/FlowLayout.java
This commit is contained in:
commit
802d063142
11 changed files with 105 additions and 84 deletions
|
@ -186,32 +186,22 @@ public class RouteResultPreparation {
|
||||||
|
|
||||||
public RouteSegmentResult filterMinorStops(RouteSegmentResult seg) {
|
public RouteSegmentResult filterMinorStops(RouteSegmentResult seg) {
|
||||||
List<Integer> stops = null;
|
List<Integer> stops = null;
|
||||||
int startPoint = seg.getStartPointIndex();
|
boolean plus = seg.getStartPointIndex() < seg.getEndPointIndex();
|
||||||
int endPoint = seg.getEndPointIndex();
|
int next;
|
||||||
int start;
|
|
||||||
int end;
|
|
||||||
|
|
||||||
if (startPoint < endPoint) {
|
for (int i = seg.getStartPointIndex(); i != seg.getEndPointIndex(); i = next) {
|
||||||
start = startPoint;
|
next = plus ? i + 1 : i - 1;
|
||||||
end = endPoint;
|
int[] pointTypes = seg.getObject().getPointTypes(i);
|
||||||
} else {
|
|
||||||
start = endPoint;
|
|
||||||
end = startPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (start <= end) {
|
|
||||||
int[] pointTypes = seg.getObject().getPointTypes(start);
|
|
||||||
if (pointTypes != null) {
|
if (pointTypes != null) {
|
||||||
for (int j = 0; j < pointTypes.length; j++) {
|
for (int j = 0; j < pointTypes.length; j++) {
|
||||||
if (pointTypes[j] == seg.getObject().region.stopMinor) {
|
if (pointTypes[j] == seg.getObject().region.stopMinor) {
|
||||||
if (stops == null) {
|
if (stops == null) {
|
||||||
stops = new ArrayList<>();
|
stops = new ArrayList<>();
|
||||||
}
|
}
|
||||||
stops.add(start);
|
stops.add(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
start++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stops != null) {
|
if (stops != null) {
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.VIBRATE" />
|
<uses-permission android:name="android.permission.VIBRATE" />
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
<uses-permission android:name="com.android.vending.BILLING" />
|
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||||
|
|
|
@ -348,7 +348,7 @@ dependencies {
|
||||||
implementation 'org.immutables:gson:2.5.0'
|
implementation 'org.immutables:gson:2.5.0'
|
||||||
implementation 'com.vividsolutions:jts-core:1.14.0'
|
implementation 'com.vividsolutions:jts-core:1.14.0'
|
||||||
implementation 'com.google.openlocationcode:openlocationcode:1.0.4'
|
implementation 'com.google.openlocationcode:openlocationcode:1.0.4'
|
||||||
implementation 'com.android.billingclient:billing:2.0.3'
|
implementation 'com.android.billingclient:billing:3.0.2'
|
||||||
// turn off for now
|
// turn off for now
|
||||||
//implementation 'com.atilika.kuromoji:kuromoji-ipadic:0.9.0'
|
//implementation 'com.atilika.kuromoji:kuromoji-ipadic:0.9.0'
|
||||||
implementation 'com.squareup.picasso:picasso:2.71828'
|
implementation 'com.squareup.picasso:picasso:2.71828'
|
||||||
|
|
|
@ -6,9 +6,7 @@ import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import com.android.billingclient.api.AccountIdentifiers;
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.android.billingclient.api.BillingClient;
|
import com.android.billingclient.api.BillingClient;
|
||||||
import com.android.billingclient.api.BillingResult;
|
import com.android.billingclient.api.BillingResult;
|
||||||
import com.android.billingclient.api.Purchase;
|
import com.android.billingclient.api.Purchase;
|
||||||
|
@ -25,7 +23,6 @@ import net.osmand.plus.inapp.InAppPurchases.InAppSubscription.SubscriptionState;
|
||||||
import net.osmand.plus.inapp.InAppPurchasesImpl.InAppPurchaseLiveUpdatesOldSubscription;
|
import net.osmand.plus.inapp.InAppPurchasesImpl.InAppPurchaseLiveUpdatesOldSubscription;
|
||||||
import net.osmand.plus.inapp.util.BillingManager;
|
import net.osmand.plus.inapp.util.BillingManager;
|
||||||
import net.osmand.plus.settings.backend.CommonPreference;
|
import net.osmand.plus.settings.backend.CommonPreference;
|
||||||
import net.osmand.plus.settings.backend.OsmandPreference;
|
|
||||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||||
import net.osmand.plus.srtmplugin.SRTMPlugin;
|
import net.osmand.plus.srtmplugin.SRTMPlugin;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
@ -37,6 +34,9 @@ import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
||||||
|
|
||||||
// The helper object
|
// The helper object
|
||||||
|
@ -77,6 +77,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
||||||
return billingManager;
|
return billingManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected void execImpl(@NonNull final InAppPurchaseTaskType taskType, @NonNull final InAppCommand runnable) {
|
protected void execImpl(@NonNull final InAppPurchaseTaskType taskType, @NonNull final InAppCommand runnable) {
|
||||||
billingManager = new BillingManager(ctx, BASE64_ENCODED_PUBLIC_KEY, new BillingManager.BillingUpdatesListener() {
|
billingManager = new BillingManager(ctx, BASE64_ENCODED_PUBLIC_KEY, new BillingManager.BillingUpdatesListener() {
|
||||||
|
|
||||||
|
@ -126,7 +127,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
||||||
}
|
}
|
||||||
billingManager.querySkuDetailsAsync(BillingClient.SkuType.INAPP, skuInApps, new SkuDetailsResponseListener() {
|
billingManager.querySkuDetailsAsync(BillingClient.SkuType.INAPP, skuInApps, new SkuDetailsResponseListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onSkuDetailsResponse(BillingResult billingResult, final List<SkuDetails> skuDetailsListInApps) {
|
public void onSkuDetailsResponse(@NonNull BillingResult billingResult, final List<SkuDetails> skuDetailsListInApps) {
|
||||||
// Is it a failure?
|
// Is it a failure?
|
||||||
if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) {
|
if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) {
|
||||||
logError("Failed to query inapps sku details: " + billingResult.getResponseCode());
|
logError("Failed to query inapps sku details: " + billingResult.getResponseCode());
|
||||||
|
@ -153,7 +154,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
||||||
|
|
||||||
billingManager.querySkuDetailsAsync(BillingClient.SkuType.SUBS, skuSubscriptions, new SkuDetailsResponseListener() {
|
billingManager.querySkuDetailsAsync(BillingClient.SkuType.SUBS, skuSubscriptions, new SkuDetailsResponseListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onSkuDetailsResponse(BillingResult billingResult, final List<SkuDetails> skuDetailsListSubscriptions) {
|
public void onSkuDetailsResponse(@NonNull BillingResult billingResult, final List<SkuDetails> skuDetailsListSubscriptions) {
|
||||||
// Is it a failure?
|
// Is it a failure?
|
||||||
if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) {
|
if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) {
|
||||||
logError("Failed to query subscriptipons sku details: " + billingResult.getResponseCode());
|
logError("Failed to query subscriptipons sku details: " + billingResult.getResponseCode());
|
||||||
|
@ -197,6 +198,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
||||||
if (skuDetails == null) {
|
if (skuDetails == null) {
|
||||||
throw new IllegalArgumentException("Cannot find sku details");
|
throw new IllegalArgumentException("Cannot find sku details");
|
||||||
}
|
}
|
||||||
|
|
||||||
BillingManager billingManager = getBillingManager();
|
BillingManager billingManager = getBillingManager();
|
||||||
if (billingManager != null) {
|
if (billingManager != null) {
|
||||||
billingManager.initiatePurchaseFlow(activity, skuDetails);
|
billingManager.initiatePurchaseFlow(activity, skuDetails);
|
||||||
|
@ -321,7 +323,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) {
|
public void onSkuDetailsResponse(@NonNull BillingResult billingResult, List<SkuDetails> skuDetailsList) {
|
||||||
|
|
||||||
logDebug("Query sku details finished.");
|
logDebug("Query sku details finished.");
|
||||||
|
|
||||||
|
@ -442,19 +444,8 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
||||||
if (liveUpdatesPurchases.size() > 0) {
|
if (liveUpdatesPurchases.size() > 0) {
|
||||||
List<String> tokensSent = Arrays.asList(settings.BILLING_PURCHASE_TOKENS_SENT.get().split(";"));
|
List<String> tokensSent = Arrays.asList(settings.BILLING_PURCHASE_TOKENS_SENT.get().split(";"));
|
||||||
for (Purchase purchase : liveUpdatesPurchases) {
|
for (Purchase purchase : liveUpdatesPurchases) {
|
||||||
if ((Algorithms.isEmpty(settings.BILLING_USER_ID.get()) || Algorithms.isEmpty(settings.BILLING_USER_TOKEN.get()))
|
if (needRestoreUserInfo()) {
|
||||||
&& !Algorithms.isEmpty(purchase.getDeveloperPayload())) {
|
restoreUserInfo(purchase);
|
||||||
String payload = purchase.getDeveloperPayload();
|
|
||||||
if (!Algorithms.isEmpty(payload)) {
|
|
||||||
String[] arr = payload.split(" ");
|
|
||||||
if (arr.length > 0) {
|
|
||||||
settings.BILLING_USER_ID.set(arr[0]);
|
|
||||||
}
|
|
||||||
if (arr.length > 1) {
|
|
||||||
token = arr[1];
|
|
||||||
settings.BILLING_USER_TOKEN.set(token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!tokensSent.contains(purchase.getSku())) {
|
if (!tokensSent.contains(purchase.getSku())) {
|
||||||
tokensToSend.add(purchase);
|
tokensToSend.add(purchase);
|
||||||
|
@ -469,6 +460,37 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private void restoreUserInfo(Purchase purchase) {
|
||||||
|
boolean restored = restoreUserInfoFromString(purchase.getDeveloperPayload());
|
||||||
|
if (!restored) {
|
||||||
|
AccountIdentifiers accountIdentifiers = purchase.getAccountIdentifiers();
|
||||||
|
if (accountIdentifiers != null) {
|
||||||
|
restoreUserInfoFromString(accountIdentifiers.getObfuscatedAccountId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean restoreUserInfoFromString(String userInfo) {
|
||||||
|
if (Algorithms.isEmpty(userInfo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
OsmandSettings settings = ctx.getSettings();
|
||||||
|
String[] arr = userInfo.split(" ");
|
||||||
|
if (arr.length > 0) {
|
||||||
|
settings.BILLING_USER_ID.set(arr[0]);
|
||||||
|
}
|
||||||
|
if (arr.length > 1) {
|
||||||
|
token = arr[1];
|
||||||
|
settings.BILLING_USER_TOKEN.set(token);
|
||||||
|
}
|
||||||
|
return needRestoreUserInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean needRestoreUserInfo() {
|
||||||
|
OsmandSettings settings = ctx.getSettings();
|
||||||
|
return Algorithms.isEmpty(settings.BILLING_USER_ID.get()) || Algorithms.isEmpty(settings.BILLING_USER_TOKEN.get());
|
||||||
|
}
|
||||||
|
|
||||||
private PurchaseInfo getPurchaseInfo(Purchase purchase) {
|
private PurchaseInfo getPurchaseInfo(Purchase purchase) {
|
||||||
return new PurchaseInfo(purchase.getSku(), purchase.getOrderId(), purchase.getPurchaseToken());
|
return new PurchaseInfo(purchase.getSku(), purchase.getOrderId(), purchase.getPurchaseToken());
|
||||||
}
|
}
|
||||||
|
@ -511,7 +533,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
||||||
|
|
||||||
String introductoryPrice = skuDetails.getIntroductoryPrice();
|
String introductoryPrice = skuDetails.getIntroductoryPrice();
|
||||||
String introductoryPricePeriod = skuDetails.getIntroductoryPricePeriod();
|
String introductoryPricePeriod = skuDetails.getIntroductoryPricePeriod();
|
||||||
String introductoryPriceCycles = skuDetails.getIntroductoryPriceCycles();
|
int introductoryPriceCycles = skuDetails.getIntroductoryPriceCycles();
|
||||||
long introductoryPriceAmountMicros = skuDetails.getIntroductoryPriceAmountMicros();
|
long introductoryPriceAmountMicros = skuDetails.getIntroductoryPriceAmountMicros();
|
||||||
if (!Algorithms.isEmpty(introductoryPrice)) {
|
if (!Algorithms.isEmpty(introductoryPrice)) {
|
||||||
try {
|
try {
|
||||||
|
@ -524,7 +546,8 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InAppCommand getPurchaseLiveUpdatesCommand(final WeakReference<Activity> activity, final String sku, final String payload) {
|
@Override
|
||||||
|
protected InAppCommand getPurchaseLiveUpdatesCommand(final WeakReference<Activity> activity, final String sku, final String userInfo) {
|
||||||
return new InAppCommand() {
|
return new InAppCommand() {
|
||||||
@Override
|
@Override
|
||||||
public void run(InAppPurchaseHelper helper) {
|
public void run(InAppPurchaseHelper helper) {
|
||||||
|
@ -534,7 +557,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
||||||
if (AndroidUtils.isActivityNotDestroyed(a) && skuDetails != null) {
|
if (AndroidUtils.isActivityNotDestroyed(a) && skuDetails != null) {
|
||||||
BillingManager billingManager = getBillingManager();
|
BillingManager billingManager = getBillingManager();
|
||||||
if (billingManager != null) {
|
if (billingManager != null) {
|
||||||
billingManager.setPayload(payload);
|
billingManager.setObfuscatedAccountId(userInfo);
|
||||||
billingManager.initiatePurchaseFlow(a, skuDetails);
|
billingManager.initiatePurchaseFlow(a, skuDetails);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("BillingManager disposed");
|
throw new IllegalStateException("BillingManager disposed");
|
||||||
|
@ -551,6 +574,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected InAppCommand getRequestInventoryCommand() {
|
protected InAppCommand getRequestInventoryCommand() {
|
||||||
return new InAppCommand() {
|
return new InAppCommand() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -276,7 +276,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InAppCommand getPurchaseLiveUpdatesCommand(final WeakReference<Activity> activity, final String sku, final String payload) {
|
protected InAppCommand getPurchaseLiveUpdatesCommand(final WeakReference<Activity> activity, final String sku, final String userInfo) {
|
||||||
return new InAppCommand() {
|
return new InAppCommand() {
|
||||||
@Override
|
@Override
|
||||||
public void run(InAppPurchaseHelper helper) {
|
public void run(InAppPurchaseHelper helper) {
|
||||||
|
@ -285,7 +285,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
|
||||||
ProductInfo productInfo = getProductInfo(sku);
|
ProductInfo productInfo = getProductInfo(sku);
|
||||||
if (AndroidUtils.isActivityNotDestroyed(a) && productInfo != null) {
|
if (AndroidUtils.isActivityNotDestroyed(a) && productInfo != null) {
|
||||||
IapRequestHelper.createPurchaseIntent(getIapClient(), sku,
|
IapRequestHelper.createPurchaseIntent(getIapClient(), sku,
|
||||||
IapClient.PriceType.IN_APP_SUBSCRIPTION, payload, new IapApiCallback<PurchaseIntentResult>() {
|
IapClient.PriceType.IN_APP_SUBSCRIPTION, userInfo, new IapApiCallback<PurchaseIntentResult>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(PurchaseIntentResult result) {
|
public void onSuccess(PurchaseIntentResult result) {
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
|
|
|
@ -364,8 +364,8 @@ public abstract class InAppPurchaseHelper {
|
||||||
notifyDismissProgress(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES);
|
notifyDismissProgress(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES);
|
||||||
if (!Algorithms.isEmpty(userId) && !Algorithms.isEmpty(token)) {
|
if (!Algorithms.isEmpty(userId) && !Algorithms.isEmpty(token)) {
|
||||||
logDebug("Launching purchase flow for live updates subscription for userId=" + userId);
|
logDebug("Launching purchase flow for live updates subscription for userId=" + userId);
|
||||||
final String payload = userId + " " + token;
|
final String userInfo = userId + " " + token;
|
||||||
exec(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES, getPurchaseLiveUpdatesCommand(activity, sku, payload));
|
exec(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES, getPurchaseLiveUpdatesCommand(activity, sku, userInfo));
|
||||||
} else {
|
} else {
|
||||||
notifyError(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES, "Empty userId");
|
notifyError(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES, "Empty userId");
|
||||||
stop(true);
|
stop(true);
|
||||||
|
@ -374,7 +374,7 @@ public abstract class InAppPurchaseHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract InAppCommand getPurchaseLiveUpdatesCommand(final WeakReference<Activity> activity,
|
protected abstract InAppCommand getPurchaseLiveUpdatesCommand(final WeakReference<Activity> activity,
|
||||||
final String sku, final String payload) throws UnsupportedOperationException;
|
final String sku, final String userInfo) throws UnsupportedOperationException;
|
||||||
|
|
||||||
@SuppressLint("StaticFieldLeak")
|
@SuppressLint("StaticFieldLeak")
|
||||||
private class RequestInventoryTask extends AsyncTask<Void, Void, String[]> {
|
private class RequestInventoryTask extends AsyncTask<Void, Void, String[]> {
|
||||||
|
|
|
@ -405,16 +405,12 @@ public abstract class InAppPurchases {
|
||||||
String introductoryPrice,
|
String introductoryPrice,
|
||||||
long introductoryPriceAmountMicros,
|
long introductoryPriceAmountMicros,
|
||||||
String introductoryPeriodString,
|
String introductoryPeriodString,
|
||||||
String introductoryCycles) throws ParseException {
|
int introductoryCycles) throws ParseException {
|
||||||
this.subscription = subscription;
|
this.subscription = subscription;
|
||||||
this.introductoryPrice = introductoryPrice;
|
this.introductoryPrice = introductoryPrice;
|
||||||
this.introductoryPriceAmountMicros = introductoryPriceAmountMicros;
|
this.introductoryPriceAmountMicros = introductoryPriceAmountMicros;
|
||||||
this.introductoryPeriodString = introductoryPeriodString;
|
this.introductoryPeriodString = introductoryPeriodString;
|
||||||
try {
|
this.introductoryCycles = introductoryCycles;
|
||||||
this.introductoryCycles = Integer.parseInt(introductoryCycles);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
throw new ParseException("Cannot parse introductoryCycles = " + introductoryCycles, 0);
|
|
||||||
}
|
|
||||||
introductoryPriceValue = introductoryPriceAmountMicros / 1000000d;
|
introductoryPriceValue = introductoryPriceAmountMicros / 1000000d;
|
||||||
introductoryPeriod = Period.parse(introductoryPeriodString);
|
introductoryPeriod = Period.parse(introductoryPeriodString);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,7 @@ package net.osmand.plus.inapp.util;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.android.billingclient.api.AcknowledgePurchaseParams;
|
import com.android.billingclient.api.AcknowledgePurchaseParams;
|
||||||
import com.android.billingclient.api.AcknowledgePurchaseResponseListener;
|
import com.android.billingclient.api.AcknowledgePurchaseResponseListener;
|
||||||
|
@ -25,7 +23,6 @@ import com.android.billingclient.api.SkuDetailsParams;
|
||||||
import com.android.billingclient.api.SkuDetailsResponseListener;
|
import com.android.billingclient.api.SkuDetailsResponseListener;
|
||||||
|
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
import net.osmand.util.Algorithms;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -33,6 +30,9 @@ import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles all the interactions with Play Store (via Billing library), maintains connection to
|
* Handles all the interactions with Play Store (via Billing library), maintains connection to
|
||||||
* it through BillingClient and caches temporary states/data if needed
|
* it through BillingClient and caches temporary states/data if needed
|
||||||
|
@ -58,7 +58,9 @@ public class BillingManager implements PurchasesUpdatedListener {
|
||||||
|
|
||||||
// Public key for verifying signature, in base64 encoding
|
// Public key for verifying signature, in base64 encoding
|
||||||
private String mSignatureBase64;
|
private String mSignatureBase64;
|
||||||
private String mPayload;
|
|
||||||
|
private String mObfuscatedAccountId;
|
||||||
|
private String mObfuscatedProfileId;
|
||||||
|
|
||||||
private final BillingUpdatesListener mBillingUpdatesListener;
|
private final BillingUpdatesListener mBillingUpdatesListener;
|
||||||
private final List<Purchase> mPurchases = new ArrayList<>();
|
private final List<Purchase> mPurchases = new ArrayList<>();
|
||||||
|
@ -135,18 +137,29 @@ public class BillingManager implements PurchasesUpdatedListener {
|
||||||
* Start a purchase flow
|
* Start a purchase flow
|
||||||
*/
|
*/
|
||||||
public void initiatePurchaseFlow(final Activity activity, final SkuDetails skuDetails) {
|
public void initiatePurchaseFlow(final Activity activity, final SkuDetails skuDetails) {
|
||||||
initiatePurchaseFlow(activity, skuDetails, null);
|
initiatePurchaseFlow(activity, skuDetails, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start a purchase or subscription replace flow
|
* Start a purchase or subscription replace flow
|
||||||
*/
|
*/
|
||||||
public void initiatePurchaseFlow(final Activity activity, final SkuDetails skuDetails, final String oldSku) {
|
public void initiatePurchaseFlow(final Activity activity, final SkuDetails skuDetails, final String oldSku, final String purchaseToken) {
|
||||||
Runnable purchaseFlowRequest = new Runnable() {
|
Runnable purchaseFlowRequest = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
LOG.debug("Launching in-app purchase flow. Replace old SKU? " + (oldSku != null));
|
LOG.debug("Launching in-app purchase flow. Replace old SKU? " + (oldSku != null && purchaseToken != null));
|
||||||
BillingFlowParams purchaseParams = BillingFlowParams.newBuilder().setSkuDetails(skuDetails).setOldSku(oldSku).build();
|
BillingFlowParams.Builder paramsBuilder = BillingFlowParams.newBuilder()
|
||||||
|
.setSkuDetails(skuDetails);
|
||||||
|
if (!TextUtils.isEmpty(mObfuscatedAccountId)) {
|
||||||
|
paramsBuilder.setObfuscatedAccountId(mObfuscatedAccountId);
|
||||||
|
}
|
||||||
|
if (!TextUtils.isEmpty(mObfuscatedProfileId)) {
|
||||||
|
paramsBuilder.setObfuscatedProfileId(mObfuscatedProfileId);
|
||||||
|
}
|
||||||
|
if (oldSku != null && purchaseToken != null) {
|
||||||
|
paramsBuilder.setOldSku(oldSku, purchaseToken);
|
||||||
|
}
|
||||||
|
BillingFlowParams purchaseParams = paramsBuilder.build();
|
||||||
mBillingClient.launchBillingFlow(activity, purchaseParams);
|
mBillingClient.launchBillingFlow(activity, purchaseParams);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -177,9 +190,11 @@ public class BillingManager implements PurchasesUpdatedListener {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// Query the purchase async
|
// Query the purchase async
|
||||||
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
|
SkuDetailsParams params = SkuDetailsParams.newBuilder()
|
||||||
params.setSkusList(skuList).setType(itemType);
|
.setSkusList(skuList)
|
||||||
mBillingClient.querySkuDetailsAsync(params.build(),
|
.setType(itemType)
|
||||||
|
.build();
|
||||||
|
mBillingClient.querySkuDetailsAsync(params,
|
||||||
new SkuDetailsResponseListener() {
|
new SkuDetailsResponseListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) {
|
public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) {
|
||||||
|
@ -247,15 +262,6 @@ public class BillingManager implements PurchasesUpdatedListener {
|
||||||
return Collections.unmodifiableList(mPurchases);
|
return Collections.unmodifiableList(mPurchases);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getPayload() {
|
|
||||||
return mPayload;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPayload(String payload) {
|
|
||||||
this.mPayload = payload;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the purchase
|
* Handles the purchase
|
||||||
* <p>Note: Notice that for each purchase, we check if signature is valid on the client.
|
* <p>Note: Notice that for each purchase, we check if signature is valid on the client.
|
||||||
|
@ -274,13 +280,9 @@ public class BillingManager implements PurchasesUpdatedListener {
|
||||||
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
|
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
|
||||||
// Acknowledge the purchase if it hasn't already been acknowledged.
|
// Acknowledge the purchase if it hasn't already been acknowledged.
|
||||||
if (!purchase.isAcknowledged()) {
|
if (!purchase.isAcknowledged()) {
|
||||||
AcknowledgePurchaseParams.Builder builder =
|
AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder()
|
||||||
AcknowledgePurchaseParams.newBuilder()
|
.setPurchaseToken(purchase.getPurchaseToken())
|
||||||
.setPurchaseToken(purchase.getPurchaseToken());
|
.build();
|
||||||
if (!Algorithms.isEmpty(mPayload)) {
|
|
||||||
builder.setDeveloperPayload(mPayload);
|
|
||||||
}
|
|
||||||
AcknowledgePurchaseParams acknowledgePurchaseParams = builder.build();
|
|
||||||
mBillingClient.acknowledgePurchase(acknowledgePurchaseParams, new AcknowledgePurchaseResponseListener() {
|
mBillingClient.acknowledgePurchase(acknowledgePurchaseParams, new AcknowledgePurchaseResponseListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onAcknowledgePurchaseResponse(BillingResult billingResult) {
|
public void onAcknowledgePurchaseResponse(BillingResult billingResult) {
|
||||||
|
@ -404,6 +406,14 @@ public class BillingManager implements PurchasesUpdatedListener {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setObfuscatedAccountId(String obfuscatedAccountId) {
|
||||||
|
mObfuscatedAccountId = obfuscatedAccountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setObfuscatedProfileId(String obfuscatedProfileId) {
|
||||||
|
mObfuscatedProfileId = obfuscatedProfileId;
|
||||||
|
}
|
||||||
|
|
||||||
private void executeServiceRequest(Runnable runnable) {
|
private void executeServiceRequest(Runnable runnable) {
|
||||||
if (mIsServiceConnected) {
|
if (mIsServiceConnected) {
|
||||||
runnable.run();
|
runnable.run();
|
||||||
|
|
|
@ -41,6 +41,8 @@ public abstract class OnlineRoutingEngine implements Cloneable {
|
||||||
private final Set<EngineParameter> allowedParameters = new HashSet<>();
|
private final Set<EngineParameter> allowedParameters = new HashSet<>();
|
||||||
|
|
||||||
public OnlineRoutingEngine(@Nullable Map<String, String> params) {
|
public OnlineRoutingEngine(@Nullable Map<String, String> params) {
|
||||||
|
// Params represents the entire state of an engine object.
|
||||||
|
// An engine object with null params used only to provide information about the engine type
|
||||||
if (!isEmpty(params)) {
|
if (!isEmpty(params)) {
|
||||||
this.params.putAll(params);
|
this.params.putAll(params);
|
||||||
}
|
}
|
||||||
|
|
|
@ -310,7 +310,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O
|
||||||
outState.putString(PROFILE_STRINGKEY_KEY, changedProfile.stringKey);
|
outState.putString(PROFILE_STRINGKEY_KEY, changedProfile.stringKey);
|
||||||
outState.putInt(PROFILE_ICON_RES_KEY, changedProfile.iconRes);
|
outState.putInt(PROFILE_ICON_RES_KEY, changedProfile.iconRes);
|
||||||
outState.putSerializable(PROFILE_COLOR_KEY, changedProfile.color);
|
outState.putSerializable(PROFILE_COLOR_KEY, changedProfile.color);
|
||||||
outState.putInt(PROFILE_CUSTOM_COLOR_KEY, changedProfile.customColor);
|
outState.putSerializable(PROFILE_CUSTOM_COLOR_KEY, changedProfile.customColor);
|
||||||
if (changedProfile.parent != null) {
|
if (changedProfile.parent != null) {
|
||||||
outState.putString(PROFILE_PARENT_KEY, changedProfile.parent.getStringKey());
|
outState.putString(PROFILE_PARENT_KEY, changedProfile.parent.getStringKey());
|
||||||
}
|
}
|
||||||
|
@ -325,7 +325,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O
|
||||||
changedProfile.stringKey = savedInstanceState.getString(PROFILE_STRINGKEY_KEY);
|
changedProfile.stringKey = savedInstanceState.getString(PROFILE_STRINGKEY_KEY);
|
||||||
changedProfile.iconRes = savedInstanceState.getInt(PROFILE_ICON_RES_KEY);
|
changedProfile.iconRes = savedInstanceState.getInt(PROFILE_ICON_RES_KEY);
|
||||||
changedProfile.color = (ProfileIconColors) savedInstanceState.getSerializable(PROFILE_COLOR_KEY);
|
changedProfile.color = (ProfileIconColors) savedInstanceState.getSerializable(PROFILE_COLOR_KEY);
|
||||||
changedProfile.customColor = savedInstanceState.getInt(PROFILE_CUSTOM_COLOR_KEY);
|
changedProfile.customColor = (Integer) savedInstanceState.getSerializable(PROFILE_CUSTOM_COLOR_KEY);
|
||||||
String parentStringKey = savedInstanceState.getString(PROFILE_PARENT_KEY);
|
String parentStringKey = savedInstanceState.getString(PROFILE_PARENT_KEY);
|
||||||
changedProfile.parent = ApplicationMode.valueOfStringKey(parentStringKey, null);
|
changedProfile.parent = ApplicationMode.valueOfStringKey(parentStringKey, null);
|
||||||
isBaseProfileImported = savedInstanceState.getBoolean(IS_BASE_PROFILE_IMPORTED);
|
isBaseProfileImported = savedInstanceState.getBoolean(IS_BASE_PROFILE_IMPORTED);
|
||||||
|
|
|
@ -114,7 +114,6 @@ public class FlowLayout extends ViewGroup {
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getFreeSizeSpacing(int width, LayoutParams lp, int childWidth) {
|
private int getFreeSizeSpacing(int width, LayoutParams lp, int childWidth) {
|
||||||
int freeSizeSpacing;
|
|
||||||
int itemsCount = width / (childWidth + lp.horizontalSpacing);
|
int itemsCount = width / (childWidth + lp.horizontalSpacing);
|
||||||
if (itemsCount > 1 && horizontalAutoSpacing) {
|
if (itemsCount > 1 && horizontalAutoSpacing) {
|
||||||
freeSizeSpacing = (width - childWidth) / (itemsCount-1);
|
freeSizeSpacing = (width - childWidth) / (itemsCount-1);
|
||||||
|
@ -122,8 +121,9 @@ public class FlowLayout extends ViewGroup {
|
||||||
freeSizeSpacing = childWidth + lp.horizontalSpacing;
|
freeSizeSpacing = childWidth + lp.horizontalSpacing;
|
||||||
} else {
|
} else {
|
||||||
freeSizeSpacing = (width % childWidth / itemsCount);
|
freeSizeSpacing = (width % childWidth / itemsCount);
|
||||||
|
return (width % childWidth / (itemsCount - 1)) + lp.horizontalSpacing;
|
||||||
}
|
}
|
||||||
return freeSizeSpacing;
|
return lp.horizontalSpacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class LayoutParams extends ViewGroup.LayoutParams {
|
public static class LayoutParams extends ViewGroup.LayoutParams {
|
||||||
|
|
Loading…
Reference in a new issue