Fix choose plan UI. Refactored InAppHelper.

This commit is contained in:
Alexey Kulish 2018-04-24 18:21:05 +03:00
parent 4373e1db5e
commit 78cf001d32
21 changed files with 963 additions and 1128 deletions

View file

@ -1,10 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout <LinearLayout
android:id="@+id/freeVersionBanner"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:osmand="http://schemas.android.com/apk/res-auto" xmlns:osmand="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/freeVersionBanner"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/osmo_header_dark" android:background="@color/osmo_header_dark"
@ -17,11 +16,6 @@
android:paddingBottom="@dimen/list_header_padding" android:paddingBottom="@dimen/list_header_padding"
android:paddingTop="@dimen/list_header_padding"> android:paddingTop="@dimen/list_header_padding">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout <LinearLayout
android:id="@+id/bannerTopLayout" android:id="@+id/bannerTopLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -80,158 +74,6 @@
</LinearLayout> </LinearLayout>
<LinearLayout
android:id="@+id/priceInfoLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/list_content_padding"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/dashboard_divider_dark"
android:visibility="visible"/>
<LinearLayout
android:id="@+id/fullVersionLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/list_content_padding"
android:orientation="horizontal"
android:visibility="visible">
<android.support.v7.widget.AppCompatImageView
android:layout_width="54dp"
android:layout_height="32dp"
android:scaleType="center"
android:src="@drawable/ic_action_osmand_logo"
android:tint="@color/osmand_orange"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/list_content_padding"
android:orientation="vertical">
<TextView
android:id="@+id/fullVersionTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/osmand_unlimited"
android:textSize="@dimen/default_list_text_size_large"
android:textStyle="bold"/>
<TextView
android:id="@+id/fullVersionDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="@string/osmand_plus_banner_desc"/>
<ProgressBar
android:id="@+id/fullVersionProgress"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginTop="16dp"
android:indeterminate="true"
android:visibility="gone"/>
<android.support.v7.widget.AppCompatButton
android:id="@+id/fullVersionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:background="@drawable/blue_button_drawable"
android:paddingBottom="4dp"
android:paddingLeft="14dp"
android:paddingRight="14dp"
android:paddingTop="4dp"
android:textColor="@color/color_white"
android:visibility="visible"
tools:text="GET FOR 5 EUR"/>
</LinearLayout>
</LinearLayout>
<View
android:id="@+id/osmLiveLayoutTopDivider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="54dp"
android:layout_marginTop="@dimen/list_content_padding"
android:background="@color/dashboard_divider_dark"
android:visibility="visible"/>
<LinearLayout
android:id="@+id/osmLiveLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/list_content_padding"
android:layout_marginBottom="@dimen/list_content_padding"
android:orientation="horizontal">
<android.support.v7.widget.AppCompatImageView
android:layout_width="54dp"
android:layout_height="32dp"
android:scaleType="center"
android:src="@drawable/ic_action_osm_live"
android:tint="@color/osmand_orange"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/list_content_padding"
android:orientation="vertical">
<TextView
android:id="@+id/osmLiveTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/osm_live_subscription"
android:textSize="@dimen/default_list_text_size_large"
android:textStyle="bold"/>
<TextView
android:id="@+id/osmLiveDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="@string/osm_live_banner_desc"/>
<ProgressBar
android:id="@+id/osmLiveProgress"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginTop="16dp"
android:indeterminate="true"
android:visibility="gone"/>
<android.support.v7.widget.AppCompatButton
android:id="@+id/osmLiveButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:background="@drawable/blue_button_drawable"
android:paddingBottom="4dp"
android:paddingLeft="14dp"
android:paddingRight="14dp"
android:paddingTop="4dp"
android:textColor="@color/color_white"
tools:text="GET FOR 1,5 EUR PER MONTH"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView> </ScrollView>
</LinearLayout> </LinearLayout>

View file

@ -13,11 +13,19 @@
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/card_button_min_size" android:minHeight="@dimen/card_button_min_size"
android:orientation="vertical" android:orientation="vertical"
android:gravity="center"
android:paddingBottom="@dimen/list_header_padding" android:paddingBottom="@dimen/list_header_padding"
android:paddingLeft="@dimen/list_content_padding" android:paddingLeft="@dimen/list_content_padding"
android:paddingRight="@dimen/list_content_padding" android:paddingRight="@dimen/list_content_padding"
android:paddingTop="@dimen/list_header_padding"> android:paddingTop="@dimen/list_header_padding">
<ProgressBar
android:id="@+id/card_button_progress"
android:layout_width="@dimen/card_button_progress_size"
android:layout_height="@dimen/card_button_progress_size"
android:indeterminate="true"
android:visibility="gone"/>
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:id="@+id/card_button_title" android:id="@+id/card_button_title"
android:layout_width="match_parent" android:layout_width="match_parent"

View file

@ -21,7 +21,7 @@
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/action_bar_height" android:layout_height="wrap_content"
android:orientation="horizontal"> android:orientation="horizontal">
<android.support.v7.widget.AppCompatImageView <android.support.v7.widget.AppCompatImageView
@ -33,6 +33,17 @@
android:src="@drawable/ic_arrow_back" android:src="@drawable/ic_arrow_back"
android:tint="@color/icon_color"/> android:tint="@color/icon_color"/>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="@dimen/list_header_padding"
android:text="@string/purchase_dialog_title"
android:textColor="?attr/dialog_title_color"
android:textSize="@dimen/dialog_header_text_size"
osmand:typeface="@string/font_roboto_medium"/>
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
@ -43,16 +54,6 @@
android:layout_marginRight="@dimen/list_content_padding_large" android:layout_marginRight="@dimen/list_content_padding_large"
android:orientation="vertical"> android:orientation="vertical">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/title_padding"
android:text="@string/purchase_dialog_title"
android:textColor="?attr/dialog_title_color"
android:textSize="@dimen/title_text_size"
osmand:typeface="@string/font_roboto_medium"/>
<LinearLayout <LinearLayout
android:id="@+id/info_container" android:id="@+id/info_container"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -70,16 +71,6 @@
</LinearLayout> </LinearLayout>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/list_content_padding_large"
android:text="@string/purchase_dialog_subtitle"
android:textColor="?attr/dialog_description_color"
android:textSize="@dimen/default_list_text_size"
osmand:typeface="@string/font_roboto_medium"/>
</LinearLayout> </LinearLayout>

View file

@ -7,7 +7,8 @@
<dimen name="title_text_size">28sp</dimen> <dimen name="title_text_size">28sp</dimen>
<dimen name="card_title_row_min_height">64dp</dimen> <dimen name="card_title_row_min_height">64dp</dimen>
<dimen name="card_row_min_height">48dp</dimen> <dimen name="card_row_min_height">48dp</dimen>
<dimen name="card_button_min_size">52dp</dimen> <dimen name="card_button_min_size">58dp</dimen>
<dimen name="card_button_progress_size">32dp</dimen>
<dimen name="widget_turn_lane_size">36dp</dimen> <dimen name="widget_turn_lane_size">36dp</dimen>
<dimen name="widget_turn_lane_border">6dp</dimen> <dimen name="widget_turn_lane_border">6dp</dimen>

View file

@ -23,7 +23,7 @@
<string name="unlimited_downloads">Unlimited downloads</string> <string name="unlimited_downloads">Unlimited downloads</string>
<string name="wikipedia_offline">Wikipedia offline</string> <string name="wikipedia_offline">Wikipedia offline</string>
<string name="contour_lines_sea_depth">Contour lines + Sea depth</string> <string name="contour_lines_hillshade_maps">Contour lines &amp; Hillshade maps</string>
<string name="unlock_all_features">Unlock all OsmAnd features</string> <string name="unlock_all_features">Unlock all OsmAnd features</string>
<string name="purchase_dialog_title">Choose plan</string> <string name="purchase_dialog_title">Choose plan</string>

View file

@ -575,6 +575,10 @@
<item name="android:windowLightStatusBar">true</item> <item name="android:windowLightStatusBar">true</item>
</style> </style>
<style name="OsmandLightTheme.DarkActionbar.LightStatusBar">
<item name="android:windowLightStatusBar">true</item>
</style>
<style name="XmasDialogTheme" parent="Theme.AppCompat.Light.Dialog.Alert"> <style name="XmasDialogTheme" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="android:background">@color/xmas_blue</item> <item name="android:background">@color/xmas_blue</item>
</style> </style>

View file

@ -31,6 +31,7 @@ import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.download.ui.AbstractLoadLocalIndexTask; import net.osmand.plus.download.ui.AbstractLoadLocalIndexTask;
import net.osmand.plus.helpers.AvoidSpecificRoads; import net.osmand.plus.helpers.AvoidSpecificRoads;
import net.osmand.plus.helpers.WaypointHelper; import net.osmand.plus.helpers.WaypointHelper;
import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.plus.liveupdates.LiveUpdatesHelper; import net.osmand.plus.liveupdates.LiveUpdatesHelper;
import net.osmand.plus.mapmarkers.MapMarkersDbHelper; import net.osmand.plus.mapmarkers.MapMarkersDbHelper;
import net.osmand.plus.monitoring.LiveMonitoringHelper; import net.osmand.plus.monitoring.LiveMonitoringHelper;
@ -421,6 +422,7 @@ public class AppInitializer implements IProgress {
e.printStackTrace(); e.printStackTrace();
} }
app.applyTheme(app); app.applyTheme(app);
app.inAppPurchaseHelper = startupInit(new InAppPurchaseHelper(app), InAppPurchaseHelper.class);
app.poiTypes = startupInit(MapPoiTypes.getDefaultNoInit(), MapPoiTypes.class); app.poiTypes = startupInit(MapPoiTypes.getDefaultNoInit(), MapPoiTypes.class);
app.routingHelper = startupInit(new RoutingHelper(app), RoutingHelper.class); app.routingHelper = startupInit(new RoutingHelper(app), RoutingHelper.class);
app.resourceManager = startupInit(new ResourceManager(app), ResourceManager.class); app.resourceManager = startupInit(new ResourceManager(app), ResourceManager.class);

View file

@ -19,7 +19,6 @@ import android.support.multidex.MultiDex;
import android.support.multidex.MultiDexApplication; import android.support.multidex.MultiDexApplication;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.text.format.DateFormat; import android.text.format.DateFormat;
import android.util.Log;
import android.view.View; import android.view.View;
import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager;
import android.widget.ImageView; import android.widget.ImageView;
@ -46,7 +45,7 @@ import net.osmand.plus.dialogs.RateUsBottomSheetDialog;
import net.osmand.plus.download.DownloadIndexesThread; import net.osmand.plus.download.DownloadIndexesThread;
import net.osmand.plus.helpers.AvoidSpecificRoads; import net.osmand.plus.helpers.AvoidSpecificRoads;
import net.osmand.plus.helpers.WaypointHelper; import net.osmand.plus.helpers.WaypointHelper;
import net.osmand.plus.inapp.InAppHelper; import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.plus.mapcontextmenu.other.RoutePreferencesMenu; import net.osmand.plus.mapcontextmenu.other.RoutePreferencesMenu;
import net.osmand.plus.mapmarkers.MapMarkersDbHelper; import net.osmand.plus.mapmarkers.MapMarkersDbHelper;
import net.osmand.plus.monitoring.LiveMonitoringHelper; import net.osmand.plus.monitoring.LiveMonitoringHelper;
@ -120,6 +119,7 @@ public class OsmandApplication extends MultiDexApplication {
GeocodingLookupService geocodingLookupService; GeocodingLookupService geocodingLookupService;
QuickSearchHelper searchUICore; QuickSearchHelper searchUICore;
TravelDbHelper travelDbHelper; TravelDbHelper travelDbHelper;
InAppPurchaseHelper inAppPurchaseHelper;
RoutingConfiguration.Builder defaultRoutingConfig; RoutingConfiguration.Builder defaultRoutingConfig;
private Locale preferredLocale = null; private Locale preferredLocale = null;
@ -166,7 +166,6 @@ public class OsmandApplication extends MultiDexApplication {
// if(!osmandSettings.FOLLOW_THE_ROUTE.get()) { // if(!osmandSettings.FOLLOW_THE_ROUTE.get()) {
// targetPointsHelper.clearPointToNavigate(false); // targetPointsHelper.clearPointToNavigate(false);
// } // }
InAppHelper.initialize(this);
initExternalLibs(); initExternalLibs();
startApplication(); startApplication();
System.out.println("Time to start application " + (System.currentTimeMillis() - timeToStart) + " ms. Should be less < 800 ms"); System.out.println("Time to start application " + (System.currentTimeMillis() - timeToStart) + " ms. Should be less < 800 ms");
@ -396,6 +395,10 @@ public class OsmandApplication extends MultiDexApplication {
return travelDbHelper; return travelDbHelper;
} }
public InAppPurchaseHelper getInAppPurchaseHelper() {
return inAppPurchaseHelper;
}
public CommandPlayer getPlayer() { public CommandPlayer getPlayer() {
return player; return player;
} }

View file

@ -976,6 +976,8 @@ public class OsmandSettings {
public final OsmandPreference<Integer> DISCOUNT_TOTAL_SHOW = new IntPreference("discount_total_show", 0).makeGlobal(); public final OsmandPreference<Integer> DISCOUNT_TOTAL_SHOW = new IntPreference("discount_total_show", 0).makeGlobal();
public final OsmandPreference<Long> DISCOUNT_SHOW_DATETIME_MS = new LongPreference("show_discount_datetime_ms", 0).makeGlobal(); public final OsmandPreference<Long> DISCOUNT_SHOW_DATETIME_MS = new LongPreference("show_discount_datetime_ms", 0).makeGlobal();
public final OsmandPreference<Boolean> TRAVEL_ARTICLES_PURCHASED = new BooleanPreference("travel_articles_purchased", false).makeGlobal();
// this value string is synchronized with settings_pref.xml preference name // this value string is synchronized with settings_pref.xml preference name
public final OsmandPreference<String> USER_OSM_BUG_NAME = public final OsmandPreference<String> USER_OSM_BUG_NAME =
new StringPreference("user_osm_bug_name", "NoName/OsmAnd").makeGlobal(); new StringPreference("user_osm_bug_name", "NoName/OsmAnd").makeGlobal();

View file

@ -92,7 +92,8 @@ import net.osmand.plus.helpers.ExternalApiHelper;
import net.osmand.plus.helpers.ImportHelper; import net.osmand.plus.helpers.ImportHelper;
import net.osmand.plus.helpers.ImportHelper.ImportGpxBottomSheetDialogFragment; import net.osmand.plus.helpers.ImportHelper.ImportGpxBottomSheetDialogFragment;
import net.osmand.plus.helpers.WakeLockHelper; import net.osmand.plus.helpers.WakeLockHelper;
import net.osmand.plus.inapp.InAppHelper; import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseTaskType;
import net.osmand.plus.mapcontextmenu.AdditionalActionsBottomSheetDialogFragment; import net.osmand.plus.mapcontextmenu.AdditionalActionsBottomSheetDialogFragment;
import net.osmand.plus.mapcontextmenu.MapContextMenu; import net.osmand.plus.mapcontextmenu.MapContextMenu;
import net.osmand.plus.mapcontextmenu.MapContextMenuFragment; import net.osmand.plus.mapcontextmenu.MapContextMenuFragment;
@ -204,7 +205,7 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
private boolean permissionGranted; private boolean permissionGranted;
private boolean mIsDestroyed = false; private boolean mIsDestroyed = false;
private InAppHelper inAppHelper; private InAppPurchaseHelper inAppPurchaseHelper;
private Timer splashScreenTimer; private Timer splashScreenTimer;
private ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); private ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
@ -1214,8 +1215,8 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
if (atlasMapRendererView != null) { if (atlasMapRendererView != null) {
atlasMapRendererView.handleOnDestroy(); atlasMapRendererView.handleOnDestroy();
} }
if (inAppHelper != null) { if (inAppPurchaseHelper != null) {
inAppHelper.stop(); inAppPurchaseHelper.stop();
} }
mIsDestroyed = true; mIsDestroyed = true;
} }
@ -1513,7 +1514,7 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (inAppHelper != null && inAppHelper.onActivityResultHandled(requestCode, resultCode, data)) { if (inAppPurchaseHelper != null && inAppPurchaseHelper.onActivityResultHandled(requestCode, resultCode, data)) {
return; return;
} }
for (ActivityResultListener listener : activityResultListeners) { for (ActivityResultListener listener : activityResultListeners) {
@ -1920,43 +1921,4 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
DESTINATION_SELECTION, DESTINATION_SELECTION,
INTERMEDIATE_SELECTION INTERMEDIATE_SELECTION
} }
public InAppHelper execInAppTask(@NonNull InAppHelper.InAppRunnable runnable) {
if (inAppHelper != null) {
inAppHelper.stop();
}
if (Version.isGooglePlayEnabled(app)) {
inAppHelper = new InAppHelper(getMyApplication(), false);
inAppHelper.addListener(new InAppHelper.InAppListener() {
@Override
public void onError(String error) {
inAppHelper = null;
}
@Override
public void onGetItems() {
inAppHelper = null;
}
@Override
public void onItemPurchased(String sku) {
inAppHelper = null;
}
@Override
public void showProgress() {
}
@Override
public void dismissProgress() {
}
});
inAppHelper.exec(runnable);
return inAppHelper;
} else {
return null;
}
}
} }

View file

@ -1,5 +1,6 @@
package net.osmand.plus.activities; package net.osmand.plus.activities;
import android.annotation.SuppressLint;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
@ -11,7 +12,8 @@ import android.view.ViewGroup;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
public class OsmandActionBarActivity extends AppCompatActivity { @SuppressLint("Registered")
public class OsmandActionBarActivity extends OsmandInAppPurchaseActivity {
protected boolean haveHomeButton = true; protected boolean haveHomeButton = true;
@ -50,8 +52,4 @@ public class OsmandActionBarActivity extends AppCompatActivity {
setupHomeButton(); setupHomeButton();
} }
} }
public OsmandApplication getMyApplication() {
return (OsmandApplication) getApplication();
}
} }

View file

@ -0,0 +1,166 @@
package net.osmand.plus.activities;
import android.annotation.SuppressLint;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import net.osmand.PlatformUtil;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.Version;
import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseListener;
import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseTaskType;
import org.apache.commons.logging.Log;
import static net.osmand.plus.OsmandApplication.SHOW_PLUS_VERSION_INAPP_PARAM;
@SuppressLint("Registered")
public class OsmandInAppPurchaseActivity extends AppCompatActivity implements InAppPurchaseListener {
private static final Log LOG = PlatformUtil.getLog(OsmandInAppPurchaseActivity.class);
private InAppPurchaseHelper purchaseHelper;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (isInAppPurchaseAllowed() && isInAppPurchaseSupported()) {
purchaseHelper = getMyApplication().getInAppPurchaseHelper();
}
}
@Override
protected void onResume() {
super.onResume();
initInAppPurchaseHelper();
}
@Override
protected void onDestroy() {
super.onDestroy();
deinitInAppPurchaseHelper();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Pass on the activity result to the helper for handling
if (purchaseHelper == null || !purchaseHelper.onActivityResultHandled(requestCode, resultCode, data)) {
// not handled, so handle it ourselves (here's where you'd
// perform any handling of activity results not related to in-app
// billing...
super.onActivityResult(requestCode, resultCode, data);
}
}
private void initInAppPurchaseHelper() {
deinitInAppPurchaseHelper();
if (purchaseHelper != null) {
purchaseHelper.addListener(this);
if (purchaseHelper.needRequestInventory()) {
purchaseHelper.requestInventory();
}
}
}
private void deinitInAppPurchaseHelper() {
if (purchaseHelper != null) {
purchaseHelper.removeListener(this);
purchaseHelper.stop();
}
}
public void purchaseFullVersion() {
OsmandApplication app = getMyApplication();
if (Version.isFreeVersion(app)) {
if (app.getRemoteBoolean(SHOW_PLUS_VERSION_INAPP_PARAM, true)) {
if (purchaseHelper != null) {
app.logEvent(this, "in_app_purchase_redirect");
purchaseHelper.purchaseFullVersion(this);
}
} else {
app.logEvent(this, "paid_version_redirect");
Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse(Version.getUrlWithUtmRef(app, "net.osmand.plus")));
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
LOG.error("ActivityNotFoundException", e);
}
}
}
}
public void purchaseDepthContours() {
if (purchaseHelper != null) {
getMyApplication().logEvent(this, "depth_contours_purchase_redirect");
purchaseHelper.purchaseDepthContours(this);
}
}
public OsmandApplication getMyApplication() {
return (OsmandApplication) getApplication();
}
@Nullable
public InAppPurchaseHelper getPurchaseHelper() {
return purchaseHelper;
}
public boolean isInAppPurchaseAllowed() {
return false;
}
public boolean isInAppPurchaseSupported() {
return Version.isGooglePlayEnabled(getMyApplication());
}
@Override
public void onError(InAppPurchaseTaskType taskType, String error) {
onInAppPurchaseError(taskType, error);
}
@Override
public void onGetItems() {
onInAppPurchaseGetItems();
}
@Override
public void onItemPurchased(String sku) {
onInAppPurchaseItemPurchased(sku);
}
@Override
public void showProgress(InAppPurchaseTaskType taskType) {
showInAppPurchaseProgress(taskType);
}
@Override
public void dismissProgress(InAppPurchaseTaskType taskType) {
dismissInAppPurchaseProgress(taskType);
}
public void onInAppPurchaseError(InAppPurchaseTaskType taskType, String error) {
// not implemented
}
public void onInAppPurchaseGetItems() {
// not implemented
}
public void onInAppPurchaseItemPurchased(String sku) {
// not implemented
}
public void showInAppPurchaseProgress(InAppPurchaseTaskType taskType) {
// not implemented
}
public void dismissInAppPurchaseProgress(InAppPurchaseTaskType taskType) {
// not implemented
}
}

View file

@ -6,11 +6,14 @@ import android.content.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.ColorRes;
import android.support.annotation.LayoutRes; import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.ContextThemeWrapper; import android.view.ContextThemeWrapper;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -18,68 +21,117 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.Window; import android.view.Window;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.Version; import net.osmand.plus.Version;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.BaseOsmAndDialogFragment; import net.osmand.plus.base.BaseOsmAndDialogFragment;
import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.download.DownloadValidationManager; import net.osmand.plus.download.DownloadValidationManager;
import net.osmand.plus.inapp.InAppHelper; import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseListener;
import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseTaskType;
import net.osmand.plus.liveupdates.OsmLiveActivity; import net.osmand.plus.liveupdates.OsmLiveActivity;
import net.osmand.plus.srtmplugin.SRTMPlugin;
import net.osmand.plus.widgets.TextViewEx; import net.osmand.plus.widgets.TextViewEx;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import static net.osmand.plus.OsmandApplication.SHOW_PLUS_VERSION_INAPP_PARAM; import static net.osmand.plus.OsmandApplication.SHOW_PLUS_VERSION_INAPP_PARAM;
public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment { public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment implements InAppPurchaseListener {
public static final String TAG = ChoosePlanDialogFragment.class.getSimpleName(); public static final String TAG = ChoosePlanDialogFragment.class.getSimpleName();
private static final Log LOG = PlatformUtil.getLog(ChoosePlanDialogFragment.class); private static final Log LOG = PlatformUtil.getLog(ChoosePlanDialogFragment.class);
private static final String PLAN_TYPE_KEY = "plan_type"; private static final String PLAN_TYPE_KEY = "plan_type";
private OsmandApplication app;
private InAppPurchaseHelper purchaseHelper;
private boolean nightMode; private boolean nightMode;
private PlanType planType; private PlanType planType;
private OsmAndFeature[] osmandLiveFeatures = { private View osmLiveCardButton;
OsmAndFeature.UNLIMITED_DOWNLOADS, private View planTypeCardButton;
OsmAndFeature.DAILY_MAP_UPDATES,
OsmAndFeature.WIKIPEDIA_OFFLINE,
OsmAndFeature.WIKIVOYAGE_OFFLINE,
OsmAndFeature.CONTOUR_LINES_SEA_DEPTH,
OsmAndFeature.DONATION_TO_OSM,
// OsmAndFeature.UNLOCK_ALL_FEATURES,
};
private OsmAndFeature[] osmandUnlimitedFeatures = {
OsmAndFeature.UNLIMITED_DOWNLOADS,
OsmAndFeature.MONTHLY_MAP_UPDATES,
OsmAndFeature.WIKIPEDIA_OFFLINE,
OsmAndFeature.WIKIVOYAGE_OFFLINE,
};
public enum PlanType { public enum PlanType {
FREE_VERSION_BANNER(OsmAndFeature.UNLIMITED_DOWNLOADS, OsmAndFeature.UNLIMITED_DOWNLOADS); FREE_VERSION_BANNER(
new OsmAndFeature[]{
OsmAndFeature.DAILY_MAP_UPDATES,
OsmAndFeature.UNLIMITED_DOWNLOADS,
OsmAndFeature.WIKIPEDIA_OFFLINE,
OsmAndFeature.WIKIVOYAGE_OFFLINE,
OsmAndFeature.CONTOUR_LINES_HILLSHADE_MAPS,
OsmAndFeature.SEA_DEPTH_MAPS,
OsmAndFeature.UNLOCK_ALL_FEATURES,
OsmAndFeature.DONATION_TO_OSM,
},
new OsmAndFeature[]{
OsmAndFeature.DAILY_MAP_UPDATES,
OsmAndFeature.UNLIMITED_DOWNLOADS,
},
new OsmAndFeature[]{
OsmAndFeature.WIKIPEDIA_OFFLINE,
OsmAndFeature.WIKIVOYAGE_OFFLINE,
OsmAndFeature.UNLIMITED_DOWNLOADS,
OsmAndFeature.MONTHLY_MAP_UPDATES,
},
new OsmAndFeature[]{});
private final OsmAndFeature osmandLiveFeature; private final OsmAndFeature[] osmLiveFeatures;
private final OsmAndFeature osmandUnlimitedFeature; private final OsmAndFeature[] planTypeFeatures;
private final OsmAndFeature[] selectedOsmLiveFeatures;
private final OsmAndFeature[] selectedPlanTypeFeatures;
PlanType(OsmAndFeature osmandLiveFeature, OsmAndFeature osmandUnlimitedFeature) { PlanType(OsmAndFeature[] osmLiveFeatures, OsmAndFeature[] selectedOsmLiveFeatures,
this.osmandLiveFeature = osmandLiveFeature; OsmAndFeature[] planTypeFeatures, OsmAndFeature[] selectedPlanTypeFeatures) {
this.osmandUnlimitedFeature = osmandUnlimitedFeature; this.osmLiveFeatures = osmLiveFeatures;
this.planTypeFeatures = planTypeFeatures;
this.selectedOsmLiveFeatures = selectedOsmLiveFeatures;
this.selectedPlanTypeFeatures = selectedPlanTypeFeatures;
} }
public OsmAndFeature getOsmandLiveFeature() { public OsmAndFeature[] getOsmLiveFeatures() {
return osmandLiveFeature; return osmLiveFeatures;
} }
public OsmAndFeature getOsmandUnlimitedFeature() { public OsmAndFeature[] getPlanTypeFeatures() {
return osmandUnlimitedFeature; return planTypeFeatures;
}
public OsmAndFeature[] getSelectedOsmLiveFeatures() {
return selectedOsmLiveFeatures;
}
public OsmAndFeature[] getSelectedPlanTypeFeatures() {
return selectedPlanTypeFeatures;
}
public boolean hasSelectedOsmLiveFeature(OsmAndFeature feature) {
if (selectedOsmLiveFeatures != null) {
for (OsmAndFeature f : selectedOsmLiveFeatures) {
if (feature == f) {
return true;
}
}
}
return false;
}
public boolean hasSelectedPlanTypeFeature(OsmAndFeature feature) {
if (selectedPlanTypeFeatures != null) {
for (OsmAndFeature f : selectedPlanTypeFeatures) {
if (feature == f) {
return true;
}
}
}
return false;
} }
} }
@ -89,7 +141,8 @@ public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment {
MONTHLY_MAP_UPDATES(R.string.monthly_map_updates), MONTHLY_MAP_UPDATES(R.string.monthly_map_updates),
UNLIMITED_DOWNLOADS(R.string.unlimited_downloads), UNLIMITED_DOWNLOADS(R.string.unlimited_downloads),
WIKIPEDIA_OFFLINE(R.string.wikipedia_offline), WIKIPEDIA_OFFLINE(R.string.wikipedia_offline),
CONTOUR_LINES_SEA_DEPTH(R.string.contour_lines_sea_depth), CONTOUR_LINES_HILLSHADE_MAPS(R.string.contour_lines_hillshade_maps),
SEA_DEPTH_MAPS(R.string.index_item_depth_contours_osmand_ext),
UNLOCK_ALL_FEATURES(R.string.unlock_all_features), UNLOCK_ALL_FEATURES(R.string.unlock_all_features),
DONATION_TO_OSM(R.string.donation_to_osm); DONATION_TO_OSM(R.string.donation_to_osm);
@ -103,9 +156,27 @@ public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment {
return ctx.getString(key); return ctx.getString(key);
} }
public boolean isFeaturePurchased(OsmandApplication ctx) {
switch (this) {
case DAILY_MAP_UPDATES:
case MONTHLY_MAP_UPDATES:
case UNLIMITED_DOWNLOADS:
case WIKIPEDIA_OFFLINE:
case UNLOCK_ALL_FEATURES:
case DONATION_TO_OSM:
return false;
case WIKIVOYAGE_OFFLINE:
return ctx.getSettings().TRAVEL_ARTICLES_PURCHASED.get();
case CONTOUR_LINES_HILLSHADE_MAPS:
boolean srtmEnabled = OsmandPlugin.getEnabledPlugin(SRTMPlugin.class) != null;
return srtmEnabled && ctx.getSettings().DEPTH_CONTOURS_PURCHASED.get();
}
return false;
}
public static OsmAndFeature[] possibleValues() { public static OsmAndFeature[] possibleValues() {
return new OsmAndFeature[]{WIKIVOYAGE_OFFLINE, DAILY_MAP_UPDATES, MONTHLY_MAP_UPDATES, UNLIMITED_DOWNLOADS, return new OsmAndFeature[]{WIKIVOYAGE_OFFLINE, DAILY_MAP_UPDATES, MONTHLY_MAP_UPDATES, UNLIMITED_DOWNLOADS,
WIKIPEDIA_OFFLINE, CONTOUR_LINES_SEA_DEPTH, UNLOCK_ALL_FEATURES, DONATION_TO_OSM}; WIKIPEDIA_OFFLINE, CONTOUR_LINES_HILLSHADE_MAPS, UNLOCK_ALL_FEATURES, DONATION_TO_OSM};
} }
} }
@ -113,6 +184,9 @@ public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
app = getMyApplication();
purchaseHelper = app.getInAppPurchaseHelper();
Bundle args = getArguments(); Bundle args = getArguments();
if (args == null) { if (args == null) {
args = savedInstanceState; args = savedInstanceState;
@ -130,13 +204,16 @@ public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment {
@NonNull @NonNull
@Override @Override
public Dialog onCreateDialog(Bundle savedInstanceState) { public Dialog onCreateDialog(Bundle savedInstanceState) {
int themeId = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme; int themeId = nightMode ? R.style.OsmandDarkTheme_DarkActionbar : R.style.OsmandLightTheme_DarkActionbar_LightStatusBar;
Dialog dialog = new Dialog(getContext(), themeId); Dialog dialog = new Dialog(getContext(), themeId);
Window window = dialog.getWindow(); Window window = dialog.getWindow();
if (window != null) { if (window != null) {
if (!getSettings().DO_NOT_USE_ANIMATIONS.get()) { if (!getSettings().DO_NOT_USE_ANIMATIONS.get()) {
window.getAttributes().windowAnimations = R.style.Animations_Alpha; window.getAttributes().windowAnimations = R.style.Animations_Alpha;
} }
if (Build.VERSION.SDK_INT >= 21) {
window.setStatusBarColor(ContextCompat.getColor(getContext(), getStatusBarColor()));
}
} }
return dialog; return dialog;
} }
@ -169,68 +246,28 @@ public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment {
switch (planType) { switch (planType) {
case FREE_VERSION_BANNER: { case FREE_VERSION_BANNER: {
infoDescription.setText(ctx.getString(R.string.free_version_message, infoDescription.setText(getString(R.string.free_version_message,
DownloadValidationManager.MAXIMUM_AVAILABLE_FREE_DOWNLOADS)); DownloadValidationManager.MAXIMUM_AVAILABLE_FREE_DOWNLOADS));
//infoDescription.setVisibility(View.GONE);
//View freeVersionInfoView = inflate(R.layout.purchase_dialog_info_free_version, infoContainer);
//initFreeVersionInfoView(ctx, freeVersionInfoView);
//infoContainer.addView(freeVersionInfoView);
break; break;
} }
} }
cardsContainer.addView(buildOsmAndLiveCard(ctx, cardsContainer)); cardsContainer.addView(buildOsmLiveCard(ctx, cardsContainer));
cardsContainer.addView(buildOsmAndUnlimitedCard(ctx, cardsContainer)); cardsContainer.addView(buildPlanTypeCard(ctx, cardsContainer));
return view; return view;
} }
/* @ColorRes
private void initFreeVersionInfoView(Context ctx, View freeVersionInfoView) { protected int getStatusBarColor() {
TextView downloadsLeftTextView = (TextView) freeVersionInfoView.findViewById(R.id.downloadsLeftTextView); return nightMode ? R.color.status_bar_wikivoyage_dark : R.color.status_bar_wikivoyage_light;
ProgressBar downloadsLeftProgressBar = (ProgressBar) freeVersionInfoView.findViewById(R.id.downloadsLeftProgressBar);
TextView freeVersionDescriptionTextView = (TextView) freeVersionInfoView
.findViewById(R.id.freeVersionDescriptionTextView);
OsmandSettings settings = getMyApplication().getSettings();
final Integer mapsDownloaded = settings.NUMBER_OF_FREE_DOWNLOADS.get();
downloadsLeftProgressBar.setProgress(mapsDownloaded);
int downloadsLeft = DownloadValidationManager.MAXIMUM_AVAILABLE_FREE_DOWNLOADS - mapsDownloaded;
downloadsLeft = Math.max(downloadsLeft, 0);
downloadsLeftTextView.setText(ctx.getString(R.string.downloads_left_template, downloadsLeft));
downloadsLeftProgressBar.setMax(DownloadValidationManager.MAXIMUM_AVAILABLE_FREE_DOWNLOADS);
freeVersionDescriptionTextView.setText(ctx.getString(R.string.free_version_message,
DownloadValidationManager.MAXIMUM_AVAILABLE_FREE_DOWNLOADS));
LinearLayout marksLinearLayout = (LinearLayout) freeVersionInfoView.findViewById(R.id.marksLinearLayout);
Space spaceView = new Space(ctx);
LinearLayout.LayoutParams layoutParams =
new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, 1);
spaceView.setLayoutParams(layoutParams);
marksLinearLayout.addView(spaceView);
int markWidth = (int) (1 * ctx.getResources().getDisplayMetrics().density);
int colorBlack = ctx.getResources().getColor(nightMode ? R.color.wikivoyage_bg_dark : R.color.wikivoyage_bg_light);
for (int i = 1; i < DownloadValidationManager.MAXIMUM_AVAILABLE_FREE_DOWNLOADS; i++) {
View markView = new View(ctx);
layoutParams = new LinearLayout.LayoutParams(markWidth, ViewGroup.LayoutParams.MATCH_PARENT);
markView.setLayoutParams(layoutParams);
markView.setBackgroundColor(colorBlack);
marksLinearLayout.addView(markView);
spaceView = new Space(ctx);
layoutParams = new LinearLayout.LayoutParams(0,
ViewGroup.LayoutParams.MATCH_PARENT, 1);
spaceView.setLayoutParams(layoutParams);
marksLinearLayout.addView(spaceView);
} }
}
*/
private View inflate(@LayoutRes int layoutId, @Nullable ViewGroup container) { private View inflate(@LayoutRes int layoutId, @Nullable ViewGroup container) {
int themeRes = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme; int themeRes = nightMode ? R.style.OsmandDarkTheme_DarkActionbar : R.style.OsmandLightTheme_DarkActionbar_LightStatusBar;
return LayoutInflater.from(new ContextThemeWrapper(getContext(), themeRes)) return LayoutInflater.from(new ContextThemeWrapper(getContext(), themeRes))
.inflate(layoutId, container, false); .inflate(layoutId, container, false);
} }
private ViewGroup buildOsmAndLiveCard(@NonNull Context ctx, ViewGroup container) { private ViewGroup buildOsmLiveCard(@NonNull Context ctx, ViewGroup container) {
ViewGroup cardView = (ViewGroup) inflate(R.layout.purchase_dialog_active_card, container); ViewGroup cardView = (ViewGroup) inflate(R.layout.purchase_dialog_active_card, container);
TextView headerTitle = (TextView) cardView.findViewById(R.id.header_title); TextView headerTitle = (TextView) cardView.findViewById(R.id.header_title);
TextView headerDescr = (TextView) cardView.findViewById(R.id.header_descr); TextView headerDescr = (TextView) cardView.findViewById(R.id.header_descr);
@ -238,11 +275,10 @@ public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment {
headerDescr.setText(R.string.osm_live_subscription); headerDescr.setText(R.string.osm_live_subscription);
ViewGroup rowsContainer = (ViewGroup) cardView.findViewById(R.id.rows_container); ViewGroup rowsContainer = (ViewGroup) cardView.findViewById(R.id.rows_container);
View featureRowDiv = null; View featureRowDiv = null;
for (OsmAndFeature feature : osmandLiveFeatures) { for (OsmAndFeature feature : planType.getOsmLiveFeatures()) {
String featureName = feature.toHumanString(ctx); String featureName = feature.toHumanString(ctx);
// View featureRow = inflate(planType.osmandLiveFeature == feature View featureRow = inflate(planType.hasSelectedOsmLiveFeature(feature)
// ? R.layout.purchase_dialog_card_selected_row : R.layout.purchase_dialog_card_row, cardView); ? R.layout.purchase_dialog_card_selected_row : R.layout.purchase_dialog_card_row, cardView);
View featureRow = inflate(R.layout.purchase_dialog_card_row, cardView);
TextViewEx titleView = (TextViewEx) featureRow.findViewById(R.id.title); TextViewEx titleView = (TextViewEx) featureRow.findViewById(R.id.title);
titleView.setText(featureName); titleView.setText(featureName);
featureRowDiv = featureRow.findViewById(R.id.div); featureRowDiv = featureRow.findViewById(R.id.div);
@ -257,29 +293,49 @@ public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment {
TextViewEx cardDescription = (TextViewEx) cardView.findViewById(R.id.card_descr); TextViewEx cardDescription = (TextViewEx) cardView.findViewById(R.id.card_descr);
cardDescription.setText(R.string.osm_live_payment_desc); cardDescription.setText(R.string.osm_live_payment_desc);
View cardButton = cardView.findViewById(R.id.card_button); osmLiveCardButton = cardView.findViewById(R.id.card_button);
TextViewEx buttonTitle = (TextViewEx) cardButton.findViewById(R.id.card_button_title); InAppPurchaseHelper purchaseHelper = app.getInAppPurchaseHelper();
TextViewEx buttonSubtitle = (TextViewEx) cardButton.findViewById(R.id.card_button_subtitle); boolean requestingInventory = purchaseHelper != null && purchaseHelper.getActiveTask() == InAppPurchaseTaskType.REQUEST_INVENTORY;
if (!InAppHelper.hasPrices(getMyApplication())) { setupOsmLiveCardButton(requestingInventory);
buttonTitle.setText(ctx.getString(R.string.purchase_subscription_title, ctx.getString(R.string.osm_live_default_price)));
return cardView;
}
private void setupOsmLiveCardButton(boolean progress) {
if (osmLiveCardButton != null) {
ProgressBar progressBar = (ProgressBar) osmLiveCardButton.findViewById(R.id.card_button_progress);
TextViewEx buttonTitle = (TextViewEx) osmLiveCardButton.findViewById(R.id.card_button_title);
TextViewEx buttonSubtitle = (TextViewEx) osmLiveCardButton.findViewById(R.id.card_button_subtitle);
if (!purchaseHelper.hasPrices()) {
buttonTitle.setText(getString(R.string.purchase_subscription_title, getString(R.string.osm_live_default_price)));
} else { } else {
buttonTitle.setText(ctx.getString(R.string.purchase_subscription_title, InAppHelper.getLiveUpdatesPrice())); buttonTitle.setText(getString(R.string.purchase_subscription_title, purchaseHelper.getLiveUpdatesPrice()));
} }
buttonSubtitle.setText(R.string.osm_live_month_cost_desc); buttonSubtitle.setText(R.string.osm_live_month_cost_desc);
cardButton.setOnClickListener(new View.OnClickListener() { if (progress) {
buttonTitle.setVisibility(View.GONE);
buttonSubtitle.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE);
osmLiveCardButton.setOnClickListener(null);
} else {
buttonTitle.setVisibility(View.VISIBLE);
buttonSubtitle.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
osmLiveCardButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
subscript(); subscript();
dismiss(); dismiss();
} }
}); });
return cardView; }
}
} }
private void subscript() { private void subscript() {
Activity ctx = getActivity(); Activity ctx = getActivity();
if (ctx != null) { if (ctx != null) {
getMyApplication().logEvent(ctx, "click_subscribe_live_osm"); app.logEvent(ctx, "click_subscribe_live_osm");
Intent intent = new Intent(ctx, OsmLiveActivity.class); Intent intent = new Intent(ctx, OsmLiveActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
intent.putExtra(OsmLiveActivity.OPEN_SUBSCRIPTION_INTENT_PARAM, true); intent.putExtra(OsmLiveActivity.OPEN_SUBSCRIPTION_INTENT_PARAM, true);
@ -287,7 +343,7 @@ public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment {
} }
} }
private ViewGroup buildOsmAndUnlimitedCard(@NonNull Context ctx, ViewGroup container) { private ViewGroup buildPlanTypeCard(@NonNull Context ctx, ViewGroup container) {
ViewGroup cardView = (ViewGroup) inflate(R.layout.purchase_dialog_card, container); ViewGroup cardView = (ViewGroup) inflate(R.layout.purchase_dialog_card, container);
TextView headerTitle = (TextView) cardView.findViewById(R.id.header_title); TextView headerTitle = (TextView) cardView.findViewById(R.id.header_title);
TextView headerDescr = (TextView) cardView.findViewById(R.id.header_descr); TextView headerDescr = (TextView) cardView.findViewById(R.id.header_descr);
@ -295,9 +351,9 @@ public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment {
headerDescr.setText(R.string.in_app_purchase); headerDescr.setText(R.string.in_app_purchase);
ViewGroup rowsContainer = (ViewGroup) cardView.findViewById(R.id.rows_container); ViewGroup rowsContainer = (ViewGroup) cardView.findViewById(R.id.rows_container);
View featureRow = null; View featureRow = null;
for (OsmAndFeature feature : osmandUnlimitedFeatures) { for (OsmAndFeature feature : planType.getPlanTypeFeatures()) {
String featureName = feature.toHumanString(ctx); String featureName = feature.toHumanString(ctx);
featureRow = inflate(planType.osmandUnlimitedFeature == feature featureRow = inflate(planType.hasSelectedPlanTypeFeature(feature)
? R.layout.purchase_dialog_card_selected_row : R.layout.purchase_dialog_card_row, cardView); ? R.layout.purchase_dialog_card_selected_row : R.layout.purchase_dialog_card_row, cardView);
TextViewEx titleView = (TextViewEx) featureRow.findViewById(R.id.title); TextViewEx titleView = (TextViewEx) featureRow.findViewById(R.id.title);
titleView.setText(featureName); titleView.setText(featureName);
@ -309,28 +365,46 @@ public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment {
TextViewEx cardDescription = (TextViewEx) cardView.findViewById(R.id.card_descr); TextViewEx cardDescription = (TextViewEx) cardView.findViewById(R.id.card_descr);
cardDescription.setText(R.string.in_app_purchase_desc_ex); cardDescription.setText(R.string.in_app_purchase_desc_ex);
View cardButton = cardView.findViewById(R.id.card_button); planTypeCardButton = cardView.findViewById(R.id.card_button);
TextViewEx buttonTitle = (TextViewEx) cardButton.findViewById(R.id.card_button_title); InAppPurchaseHelper purchaseHelper = app.getInAppPurchaseHelper();
TextViewEx buttonSubtitle = (TextViewEx) cardButton.findViewById(R.id.card_button_subtitle); boolean requestingInventory = purchaseHelper != null && purchaseHelper.getActiveTask() == InAppPurchaseTaskType.REQUEST_INVENTORY;
if (!InAppHelper.hasPrices(getMyApplication())) { setupPlanTypeCardButton(requestingInventory);
buttonTitle.setText(ctx.getString(R.string.purchase_unlim_title, ctx.getString(R.string.full_version_price)));
return cardView;
}
private void setupPlanTypeCardButton(boolean progress) {
if (planTypeCardButton != null) {
ProgressBar progressBar = (ProgressBar) planTypeCardButton.findViewById(R.id.card_button_progress);
TextViewEx buttonTitle = (TextViewEx) planTypeCardButton.findViewById(R.id.card_button_title);
TextViewEx buttonSubtitle = (TextViewEx) planTypeCardButton.findViewById(R.id.card_button_subtitle);
if (!purchaseHelper.hasPrices()) {
buttonTitle.setText(getString(R.string.purchase_unlim_title, getString(R.string.full_version_price)));
} else { } else {
buttonTitle.setText(ctx.getString(R.string.purchase_unlim_title, InAppHelper.getFullVersionPrice())); buttonTitle.setText(getString(R.string.purchase_unlim_title, purchaseHelper.getFullVersionPrice()));
} }
buttonSubtitle.setText(R.string.in_app_purchase_desc); buttonSubtitle.setText(R.string.in_app_purchase_desc);
cardButton.setOnClickListener(new View.OnClickListener() { if (progress) {
buttonTitle.setVisibility(View.GONE);
buttonSubtitle.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE);
planTypeCardButton.setOnClickListener(null);
} else {
buttonTitle.setVisibility(View.VISIBLE);
buttonSubtitle.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
planTypeCardButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
purchaseFullVersion(); purchaseFullVersion();
dismiss(); dismiss();
} }
}); });
return cardView; }
}
} }
public void purchaseFullVersion() { public void purchaseFullVersion() {
/*
OsmandApplication app = getMyApplication();
if (app.getRemoteBoolean(SHOW_PLUS_VERSION_INAPP_PARAM, true)) { if (app.getRemoteBoolean(SHOW_PLUS_VERSION_INAPP_PARAM, true)) {
app.logEvent(getActivity(), "in_app_purchase_redirect_from_banner"); app.logEvent(getActivity(), "in_app_purchase_redirect_from_banner");
} else { } else {
@ -338,12 +412,13 @@ public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment {
} }
if (Version.isFreeVersion(app)) { if (Version.isFreeVersion(app)) {
if (app.getRemoteBoolean(SHOW_PLUS_VERSION_INAPP_PARAM, true)) { if (app.getRemoteBoolean(SHOW_PLUS_VERSION_INAPP_PARAM, true)) {
if (inAppHelper != null) { InAppPurchaseHelper purchaseHelper = app.getInAppPurchaseHelper();
app.logEvent(this, "in_app_purchase_redirect"); if (purchaseHelper != null) {
inAppHelper.purchaseFullVersion(this); app.logEvent(getActivity(), "in_app_purchase_redirect");
purchaseHelper.purchaseFullVersion(getActivity());
} }
} else { } else {
app.logEvent(this, "paid_version_redirect"); app.logEvent(getActivity(), "paid_version_redirect");
Intent intent = new Intent(Intent.ACTION_VIEW, Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse(Version.getUrlWithUtmRef(app, "net.osmand.plus"))); Uri.parse(Version.getUrlWithUtmRef(app, "net.osmand.plus")));
try { try {
@ -353,7 +428,6 @@ public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment {
} }
} }
} }
*/
} }
@Override @Override
@ -391,6 +465,38 @@ public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment {
} }
} }
@Override
public void onError(InAppPurchaseTaskType taskType, String error) {
if (taskType == InAppPurchaseTaskType.REQUEST_INVENTORY) {
setupOsmLiveCardButton(false);
setupPlanTypeCardButton(false);
}
}
@Override
public void onGetItems() {
}
@Override
public void onItemPurchased(String sku) {
}
@Override
public void showProgress(InAppPurchaseTaskType taskType) {
if (taskType == InAppPurchaseTaskType.REQUEST_INVENTORY) {
setupOsmLiveCardButton(true);
setupPlanTypeCardButton(true);
}
}
@Override
public void dismissProgress(InAppPurchaseTaskType taskType) {
if (taskType == InAppPurchaseTaskType.REQUEST_INVENTORY) {
setupOsmLiveCardButton(false);
setupPlanTypeCardButton(false);
}
}
public static void showFreeVersionInstance(@NonNull FragmentManager fm) { public static void showFreeVersionInstance(@NonNull FragmentManager fm) {
PlanType planType = PlanType.FREE_VERSION_BANNER; PlanType planType = PlanType.FREE_VERSION_BANNER;
showInstance(fm, planType); showInstance(fm, planType);

View file

@ -1,12 +1,11 @@
package net.osmand.plus.download; package net.osmand.plus.download;
import android.Manifest; import android.Manifest;
import android.content.ActivityNotFoundException; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.StatFs; import android.os.StatFs;
@ -21,7 +20,6 @@ import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
import android.support.v4.widget.Space; import android.support.v4.widget.Space;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.support.v7.widget.AppCompatButton;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem; import android.view.MenuItem;
@ -54,17 +52,15 @@ import net.osmand.plus.activities.TabActivity;
import net.osmand.plus.base.BasicProgressAsyncTask; import net.osmand.plus.base.BasicProgressAsyncTask;
import net.osmand.plus.base.BottomSheetDialogFragment; import net.osmand.plus.base.BottomSheetDialogFragment;
import net.osmand.plus.dialogs.ChoosePlanDialogFragment; import net.osmand.plus.dialogs.ChoosePlanDialogFragment;
import net.osmand.plus.dialogs.ChoosePlanDialogFragment.PlanType;
import net.osmand.plus.download.DownloadIndexesThread.DownloadEvents; import net.osmand.plus.download.DownloadIndexesThread.DownloadEvents;
import net.osmand.plus.download.ui.ActiveDownloadsDialogFragment; import net.osmand.plus.download.ui.ActiveDownloadsDialogFragment;
import net.osmand.plus.download.ui.DownloadResourceGroupFragment; import net.osmand.plus.download.ui.DownloadResourceGroupFragment;
import net.osmand.plus.download.ui.FreeVersionDialogFragment;
import net.osmand.plus.download.ui.LocalIndexesFragment; import net.osmand.plus.download.ui.LocalIndexesFragment;
import net.osmand.plus.download.ui.UpdatesIndexFragment; import net.osmand.plus.download.ui.UpdatesIndexFragment;
import net.osmand.plus.helpers.FileNameTranslationHelper; import net.osmand.plus.helpers.FileNameTranslationHelper;
import net.osmand.plus.inapp.InAppHelper; import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.plus.inapp.InAppHelper.InAppListener; import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseListener;
import net.osmand.plus.liveupdates.OsmLiveActivity; import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseTaskType;
import net.osmand.plus.openseamapsplugin.NauticalMapsPlugin; import net.osmand.plus.openseamapsplugin.NauticalMapsPlugin;
import net.osmand.plus.srtmplugin.SRTMPlugin; import net.osmand.plus.srtmplugin.SRTMPlugin;
import net.osmand.plus.views.controls.PagerSlidingTabStrip; import net.osmand.plus.views.controls.PagerSlidingTabStrip;
@ -83,10 +79,8 @@ import java.util.Set;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import static net.osmand.plus.OsmandApplication.SHOW_PLUS_VERSION_INAPP_PARAM;
public class DownloadActivity extends AbstractDownloadActivity implements DownloadEvents, public class DownloadActivity extends AbstractDownloadActivity implements DownloadEvents,
OnRequestPermissionsResultCallback, InAppListener { OnRequestPermissionsResultCallback {
private static final Log LOG = PlatformUtil.getLog(DownloadActivity.class); private static final Log LOG = PlatformUtil.getLog(DownloadActivity.class);
public static final int UPDATES_TAB_NUMBER = 2; public static final int UPDATES_TAB_NUMBER = 2;
@ -122,8 +116,6 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
protected WorldRegion downloadItem; protected WorldRegion downloadItem;
protected String downloadTargetFileName; protected String downloadTargetFileName;
private InAppHelper inAppHelper;
private boolean srtmDisabled; private boolean srtmDisabled;
private boolean srtmNeedsInstallation; private boolean srtmNeedsInstallation;
private boolean nauticalPluginDisabled; private boolean nauticalPluginDisabled;
@ -196,11 +188,9 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
visibleBanner = new BannerAndDownloadFreeVersion(findViewById(R.id.mainLayout), this, true); visibleBanner = new BannerAndDownloadFreeVersion(findViewById(R.id.mainLayout), this, true);
if (shouldShowFreeVersionBanner(getMyApplication())) { if (shouldShowFreeVersionBanner(getMyApplication())) {
visibleBanner.setUpdatingPrices(true); visibleBanner.updateFreeVersionBanner();
} }
startInAppHelper();
final Intent intent = getIntent(); final Intent intent = getIntent();
if (intent != null && intent.getExtras() != null) { if (intent != null && intent.getExtras() != null) {
filter = intent.getExtras().getString(FILTER_KEY); filter = intent.getExtras().getString(FILTER_KEY);
@ -209,65 +199,60 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
} }
} }
public boolean isInAppPurchaseAllowed() {
return true;
}
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { public void onInAppPurchaseError(InAppPurchaseTaskType taskType, String error) {
// Pass on the activity result to the helper for handling visibleBanner.updateFreeVersionBanner();
if (inAppHelper == null || !inAppHelper.onActivityResultHandled(requestCode, resultCode, data)) { for (WeakReference<Fragment> ref : fragSet) {
// not handled, so handle it ourselves (here's where you'd Fragment f = ref.get();
// perform any handling of activity results not related to in-app if (f instanceof InAppPurchaseListener && f.isAdded()) {
// billing... ((InAppPurchaseListener) f).onError(taskType, error);
super.onActivityResult(requestCode, resultCode, data); }
} }
} }
@Override @Override
public void onDestroy() { public void onInAppPurchaseGetItems() {
super.onDestroy(); visibleBanner.updateFreeVersionBanner();
stopInAppHelper(); for (WeakReference<Fragment> ref : fragSet) {
} Fragment f = ref.get();
if (f instanceof InAppPurchaseListener && f.isAdded()) {
public void startInAppHelper() { ((InAppPurchaseListener) f).onGetItems();
stopInAppHelper();
if (Version.isGooglePlayEnabled(getMyApplication())) {
inAppHelper = new InAppHelper(getMyApplication(), true);
inAppHelper.addListener(this);
inAppHelper.start(false);
}
}
public void stopInAppHelper() {
if (inAppHelper != null) {
inAppHelper.removeListener(this);
inAppHelper.stop();
}
}
public void purchaseFullVersion() {
OsmandApplication app = getMyApplication();
if (Version.isFreeVersion(app)) {
if (app.getRemoteBoolean(SHOW_PLUS_VERSION_INAPP_PARAM, true)) {
if (inAppHelper != null) {
app.logEvent(this, "in_app_purchase_redirect");
inAppHelper.purchaseFullVersion(this);
}
} else {
app.logEvent(this, "paid_version_redirect");
Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse(Version.getUrlWithUtmRef(app, "net.osmand.plus")));
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
LOG.error("ActivityNotFoundException", e);
}
} }
} }
} }
public void purchaseDepthContours() { @Override
if (inAppHelper != null) { public void onInAppPurchaseItemPurchased(String sku) {
getMyApplication().logEvent(this, "depth_contours_purchase_redirect"); visibleBanner.updateFreeVersionBanner();
inAppHelper.purchaseDepthContours(this); for (WeakReference<Fragment> ref : fragSet) {
Fragment f = ref.get();
if (f instanceof InAppPurchaseListener && f.isAdded()) {
((InAppPurchaseListener) f).onItemPurchased(sku);
}
}
}
@Override
public void showInAppPurchaseProgress(InAppPurchaseTaskType taskType) {
for (WeakReference<Fragment> ref : fragSet) {
Fragment f = ref.get();
if (f instanceof InAppPurchaseListener && f.isAdded()) {
((InAppPurchaseListener) f).showProgress(taskType);
}
}
}
@Override
public void dismissInAppPurchaseProgress(InAppPurchaseTaskType taskType) {
for (WeakReference<Fragment> ref : fragSet) {
Fragment f = ref.get();
if (f instanceof InAppPurchaseListener && f.isAdded()) {
((InAppPurchaseListener) f).dismissProgress(taskType);
}
} }
} }
@ -369,59 +354,6 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
} }
} }
@Override
public void onError(String error) {
visibleBanner.setUpdatingPrices(false);
for (WeakReference<Fragment> ref : fragSet) {
Fragment f = ref.get();
if (f instanceof InAppListener && f.isAdded()) {
((InAppListener) f).onError(error);
}
}
}
@Override
public void onGetItems() {
visibleBanner.setUpdatingPrices(false);
for (WeakReference<Fragment> ref : fragSet) {
Fragment f = ref.get();
if (f instanceof InAppListener && f.isAdded()) {
((InAppListener) f).onGetItems();
}
}
}
@Override
public void onItemPurchased(String sku) {
visibleBanner.setUpdatingPrices(false);
for (WeakReference<Fragment> ref : fragSet) {
Fragment f = ref.get();
if (f instanceof InAppListener && f.isAdded()) {
((InAppListener) f).onItemPurchased(sku);
}
}
}
@Override
public void showProgress() {
for (WeakReference<Fragment> ref : fragSet) {
Fragment f = ref.get();
if (f instanceof InAppListener && f.isAdded()) {
((InAppListener) f).showProgress();
}
}
}
@Override
public void dismissProgress() {
for (WeakReference<Fragment> ref : fragSet) {
Fragment f = ref.get();
if (f instanceof InAppListener && f.isAdded()) {
((InAppListener) f).dismissProgress();
}
}
}
@Override @Override
@UiThread @UiThread
public void downloadInProgress() { public void downloadInProgress() {
@ -478,25 +410,14 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
} }
public static class FreeVersionDialog { public static class FreeVersionBanner {
private final View freeVersionBanner; private final View freeVersionBanner;
private final View freeVersionBannerTitle; private final View freeVersionBannerTitle;
private boolean updatingPrices;
private final View priceInfoLayout;
private final TextView freeVersionDescriptionTextView; private final TextView freeVersionDescriptionTextView;
private final TextView downloadsLeftTextView; private final TextView downloadsLeftTextView;
private final ProgressBar downloadsLeftProgressBar; private final ProgressBar downloadsLeftProgressBar;
// private final View laterButton;
// private final View buttonsLinearLayout;
private final View fullVersionProgress;
private final AppCompatButton fullVersionButton;
private final View osmLiveProgress;
private final AppCompatButton osmLiveButton;
private DownloadActivity ctx; private DownloadActivity ctx;
private boolean dialog;
private OnClickListener onCollapseListener = new OnClickListener() { private OnClickListener onCollapseListener = new OnClickListener() {
@Override @Override
@ -511,45 +432,26 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
} }
}; };
public FreeVersionDialog(View view, final DownloadActivity ctx, boolean dialog) { public FreeVersionBanner(View view, final DownloadActivity ctx) {
this.ctx = ctx; this.ctx = ctx;
this.dialog = dialog;
freeVersionBanner = view.findViewById(R.id.freeVersionBanner); freeVersionBanner = view.findViewById(R.id.freeVersionBanner);
downloadsLeftTextView = (TextView) freeVersionBanner.findViewById(R.id.downloadsLeftTextView); downloadsLeftTextView = (TextView) freeVersionBanner.findViewById(R.id.downloadsLeftTextView);
downloadsLeftProgressBar = (ProgressBar) freeVersionBanner.findViewById(R.id.downloadsLeftProgressBar); downloadsLeftProgressBar = (ProgressBar) freeVersionBanner.findViewById(R.id.downloadsLeftProgressBar);
priceInfoLayout = freeVersionBanner.findViewById(R.id.priceInfoLayout);
freeVersionDescriptionTextView = (TextView) freeVersionBanner freeVersionDescriptionTextView = (TextView) freeVersionBanner
.findViewById(R.id.freeVersionDescriptionTextView); .findViewById(R.id.freeVersionDescriptionTextView);
freeVersionBannerTitle = freeVersionBanner.findViewById(R.id.freeVersionBannerTitle); freeVersionBannerTitle = freeVersionBanner.findViewById(R.id.freeVersionBannerTitle);
// laterButton = freeVersionBanner.findViewById(R.id.laterButton);
// buttonsLinearLayout = freeVersionBanner.findViewById(R.id.buttonsLinearLayout);
fullVersionProgress = freeVersionBanner.findViewById(R.id.fullVersionProgress);
fullVersionButton = (AppCompatButton) freeVersionBanner.findViewById(R.id.fullVersionButton);
osmLiveProgress = freeVersionBanner.findViewById(R.id.osmLiveProgress);
osmLiveButton = (AppCompatButton) freeVersionBanner.findViewById(R.id.osmLiveButton);
}
public void setUpdatingPrices(boolean updatingPrices) {
this.updatingPrices = updatingPrices;
updateFreeVersionBanner();
} }
private void collapseBanner() { private void collapseBanner() {
freeVersionDescriptionTextView.setVisibility(View.GONE); freeVersionDescriptionTextView.setVisibility(View.GONE);
// buttonsLinearLayout.setVisibility(View.GONE);
priceInfoLayout.setVisibility(View.GONE);
freeVersionBannerTitle.setVisibility(View.VISIBLE); freeVersionBannerTitle.setVisibility(View.VISIBLE);
} }
public void expandBanner() { public void expandBanner() {
freeVersionDescriptionTextView.setVisibility(View.VISIBLE); freeVersionDescriptionTextView.setVisibility(View.VISIBLE);
// buttonsLinearLayout.setVisibility(View.VISIBLE);
priceInfoLayout.setVisibility(View.VISIBLE);
freeVersionBannerTitle.setVisibility(View.VISIBLE); freeVersionBannerTitle.setVisibility(View.VISIBLE);
} }
public void initFreeVersionBanner() { public void initFreeVersionBanner() {
if (!shouldShowFreeVersionBanner(ctx.getMyApplication())) { if (!shouldShowFreeVersionBanner(ctx.getMyApplication())) {
freeVersionBanner.setVisibility(View.GONE); freeVersionBanner.setVisibility(View.GONE);
@ -559,33 +461,6 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
downloadsLeftProgressBar.setMax(DownloadValidationManager.MAXIMUM_AVAILABLE_FREE_DOWNLOADS); downloadsLeftProgressBar.setMax(DownloadValidationManager.MAXIMUM_AVAILABLE_FREE_DOWNLOADS);
freeVersionDescriptionTextView.setText(ctx.getString(R.string.free_version_message, freeVersionDescriptionTextView.setText(ctx.getString(R.string.free_version_message,
DownloadValidationManager.MAXIMUM_AVAILABLE_FREE_DOWNLOADS)); DownloadValidationManager.MAXIMUM_AVAILABLE_FREE_DOWNLOADS));
fullVersionButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
OsmandApplication app = ctx.getMyApplication();
if (app.getRemoteBoolean(SHOW_PLUS_VERSION_INAPP_PARAM, true)) {
app.logEvent(ctx, "in_app_purchase_redirect_from_banner");
} else {
app.logEvent(ctx, "paid_version_redirect_from_banner");
}
ctx.purchaseFullVersion();
DialogFragment f = (DialogFragment) ctx.getSupportFragmentManager()
.findFragmentByTag(FreeVersionDialogFragment.TAG);
if (f != null) {
f.dismiss();
}
}
});
osmLiveButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ctx.getMyApplication().logEvent(ctx, "click_subscribe_live_osm");
Intent intent = new Intent(ctx, OsmLiveActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
intent.putExtra(OsmLiveActivity.OPEN_SUBSCRIPTION_INTENT_PARAM, true);
ctx.startActivity(intent);
}
});
LinearLayout marksLinearLayout = (LinearLayout) freeVersionBanner.findViewById(R.id.marksLinearLayout); LinearLayout marksLinearLayout = (LinearLayout) freeVersionBanner.findViewById(R.id.marksLinearLayout);
Space spaceView = new Space(ctx); Space spaceView = new Space(ctx);
@ -609,12 +484,8 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
} }
updateFreeVersionBanner(); updateFreeVersionBanner();
if(dialog) {
expandBanner();
} else {
collapseBanner(); collapseBanner();
} }
}
public void updateFreeVersionBanner() { public void updateFreeVersionBanner() {
if (!shouldShowFreeVersionBanner(ctx.getMyApplication())) { if (!shouldShowFreeVersionBanner(ctx.getMyApplication())) {
@ -630,30 +501,9 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
int downloadsLeft = DownloadValidationManager.MAXIMUM_AVAILABLE_FREE_DOWNLOADS - mapsDownloaded; int downloadsLeft = DownloadValidationManager.MAXIMUM_AVAILABLE_FREE_DOWNLOADS - mapsDownloaded;
downloadsLeft = Math.max(downloadsLeft, 0); downloadsLeft = Math.max(downloadsLeft, 0);
downloadsLeftTextView.setText(ctx.getString(R.string.downloads_left_template, downloadsLeft)); downloadsLeftTextView.setText(ctx.getString(R.string.downloads_left_template, downloadsLeft));
if(!dialog) {
freeVersionBanner.findViewById(R.id.bannerTopLayout).setOnClickListener(onCollapseListener); freeVersionBanner.findViewById(R.id.bannerTopLayout).setOnClickListener(onCollapseListener);
} }
if (InAppHelper.hasPrices(ctx.getMyApplication()) || !updatingPrices) {
if (!InAppHelper.hasPrices(ctx.getMyApplication())) {
fullVersionButton.setText(ctx.getString(R.string.get_for, ctx.getString(R.string.full_version_price)));
osmLiveButton.setText(ctx.getString(R.string.get_for_month, ctx.getString(R.string.osm_live_default_price)));
} else {
fullVersionButton.setText(ctx.getString(R.string.get_for, InAppHelper.getFullVersionPrice()));
osmLiveButton.setText(ctx.getString(R.string.get_for_month, InAppHelper.getLiveUpdatesPrice()));
}
fullVersionProgress.setVisibility(View.GONE);
fullVersionButton.setVisibility(View.VISIBLE);
osmLiveProgress.setVisibility(View.GONE);
osmLiveButton.setVisibility(View.VISIBLE);
} else {
fullVersionProgress.setVisibility(View.VISIBLE);
fullVersionButton.setVisibility(View.GONE);
osmLiveProgress.setVisibility(View.VISIBLE);
osmLiveButton.setVisibility(View.GONE);
}
}
private void setMinimizedFreeVersionBanner(boolean minimize) { private void setMinimizedFreeVersionBanner(boolean minimize) {
if (minimize && isDownlodingPermitted(ctx.getMyApplication().getSettings())) { if (minimize && isDownlodingPermitted(ctx.getMyApplication().getSettings())) {
collapseBanner(); collapseBanner();
@ -668,7 +518,6 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
final Integer mapsDownloaded = settings.NUMBER_OF_FREE_DOWNLOADS.get() + activeTasks; final Integer mapsDownloaded = settings.NUMBER_OF_FREE_DOWNLOADS.get() + activeTasks;
downloadsLeftProgressBar.setProgress(mapsDownloaded); downloadsLeftProgressBar.setProgress(mapsDownloaded);
} }
} }
public static class BannerAndDownloadFreeVersion { public static class BannerAndDownloadFreeVersion {
@ -681,26 +530,24 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
private final DownloadActivity ctx; private final DownloadActivity ctx;
private boolean showSpace; private boolean showSpace;
private FreeVersionDialog freeVersionDialog; private FreeVersionBanner freeVersionBanner;
public BannerAndDownloadFreeVersion(View view, final DownloadActivity ctx, boolean showSpace) { public BannerAndDownloadFreeVersion(View view, final DownloadActivity ctx, boolean showSpace) {
this.ctx = ctx; this.ctx = ctx;
this.showSpace = showSpace; this.showSpace = showSpace;
freeVersionDialog = new FreeVersionDialog(view, ctx, false); freeVersionBanner = new FreeVersionBanner(view, ctx);
downloadProgressLayout = view.findViewById(R.id.downloadProgressLayout); downloadProgressLayout = view.findViewById(R.id.downloadProgressLayout);
progressBar = (ProgressBar) view.findViewById(R.id.progressBar); progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
leftTextView = (TextView) view.findViewById(R.id.leftTextView); leftTextView = (TextView) view.findViewById(R.id.leftTextView);
rightTextView = (TextView) view.findViewById(R.id.rightTextView); rightTextView = (TextView) view.findViewById(R.id.rightTextView);
freeVersionBanner.initFreeVersionBanner();
freeVersionDialog.initFreeVersionBanner();
updateBannerInProgress(); updateBannerInProgress();
} }
public void setUpdatingPrices(boolean updatingPrices) { public void updateFreeVersionBanner() {
freeVersionDialog.setUpdatingPrices(updatingPrices); freeVersionBanner.updateFreeVersionBanner();
} }
public void updateBannerInProgress() { public void updateBannerInProgress() {
@ -715,13 +562,13 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
} else { } else {
downloadProgressLayout.setVisibility(View.VISIBLE); downloadProgressLayout.setVisibility(View.VISIBLE);
} }
freeVersionDialog.updateFreeVersionBanner(); freeVersionBanner.updateFreeVersionBanner();
} else { } else {
boolean indeterminate = basicProgressAsyncTask.isIndeterminate(); boolean indeterminate = basicProgressAsyncTask.isIndeterminate();
String message = basicProgressAsyncTask.getDescription(); String message = basicProgressAsyncTask.getDescription();
int percent = basicProgressAsyncTask.getProgressPercentage(); int percent = basicProgressAsyncTask.getProgressPercentage();
freeVersionDialog.setMinimizedFreeVersionBanner(true); freeVersionBanner.setMinimizedFreeVersionBanner(true);
freeVersionDialog.updateAvailableDownloads(); freeVersionBanner.updateAvailableDownloads();
downloadProgressLayout.setVisibility(View.VISIBLE); downloadProgressLayout.setVisibility(View.VISIBLE);
downloadProgressLayout.setOnClickListener(new OnClickListener() { downloadProgressLayout.setOnClickListener(new OnClickListener() {
@Override @Override
@ -735,27 +582,14 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
rightTextView.setText(null); rightTextView.setText(null);
} else { } else {
progressBar.setProgress(percent); progressBar.setProgress(percent);
// final String format = ctx.getString(R.string.downloading_number_of_files);
leftTextView.setText(message); leftTextView.setText(message);
rightTextView.setText(percent + "%"); rightTextView.setText(percent + "%");
} }
} }
} }
public void hideDownloadProgressLayout() {
downloadProgressLayout.setVisibility(View.GONE);
}
public void showDownloadProgressLayout() {
downloadProgressLayout.setVisibility(View.VISIBLE);
}
} }
@SuppressLint("StaticFieldLeak")
public void reloadLocalIndexes() { public void reloadLocalIndexes() {
AsyncTask<Void, String, List<String>> task = new AsyncTask<Void, String, List<String>>() { AsyncTask<Void, String, List<String>> task = new AsyncTask<Void, String, List<String>>() {
@Override @Override

View file

@ -1,5 +1,6 @@
package net.osmand.plus.download.ui; package net.osmand.plus.download.ui;
import android.annotation.SuppressLint;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.res.Resources; import android.content.res.Resources;
@ -41,8 +42,9 @@ import net.osmand.plus.download.DownloadResourceGroup.DownloadResourceGroupType;
import net.osmand.plus.download.DownloadResources; import net.osmand.plus.download.DownloadResources;
import net.osmand.plus.download.DownloadValidationManager; import net.osmand.plus.download.DownloadValidationManager;
import net.osmand.plus.download.IndexItem; import net.osmand.plus.download.IndexItem;
import net.osmand.plus.inapp.InAppHelper; import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.plus.inapp.InAppHelper.InAppListener; import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseListener;
import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseTaskType;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import org.json.JSONException; import org.json.JSONException;
@ -55,7 +57,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
public class DownloadResourceGroupFragment extends DialogFragment implements DownloadEvents, public class DownloadResourceGroupFragment extends DialogFragment implements DownloadEvents,
InAppListener, OnChildClickListener { InAppPurchaseListener, OnChildClickListener {
public static final int RELOAD_ID = 0; public static final int RELOAD_ID = 0;
public static final int SEARCH_ID = 1; public static final int SEARCH_ID = 1;
public static final String TAG = "RegionDialogFragment"; public static final String TAG = "RegionDialogFragment";
@ -67,6 +69,7 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
protected DownloadResourceGroupAdapter listAdapter; protected DownloadResourceGroupAdapter listAdapter;
private DownloadResourceGroup group; private DownloadResourceGroup group;
private DownloadActivity activity; private DownloadActivity activity;
private InAppPurchaseHelper purchaseHelper;
private Toolbar toolbar; private Toolbar toolbar;
private View searchView; private View searchView;
private View restorePurchasesView; private View restorePurchasesView;
@ -75,6 +78,7 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
purchaseHelper = getDownloadActivity().getPurchaseHelper();
boolean isLightTheme = getMyApplication().getSettings().OSMAND_THEME.get() == OsmandSettings.OSMAND_LIGHT_THEME; boolean isLightTheme = getMyApplication().getSettings().OSMAND_THEME.get() == OsmandSettings.OSMAND_LIGHT_THEME;
int themeId = isLightTheme ? R.style.OsmandLightTheme : R.style.OsmandDarkTheme; int themeId = isLightTheme ? R.style.OsmandLightTheme : R.style.OsmandDarkTheme;
setStyle(STYLE_NO_FRAME, themeId); setStyle(STYLE_NO_FRAME, themeId);
@ -152,7 +156,7 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
} }
private void addRestorePurchasesRow() { private void addRestorePurchasesRow() {
if (!openAsDialog() && !InAppHelper.isInAppIntentoryRead()) { if (!openAsDialog() && purchaseHelper != null && !purchaseHelper.hasInventory()) {
restorePurchasesView = activity.getLayoutInflater().inflate(R.layout.restore_purchases_list_footer, null); restorePurchasesView = activity.getLayoutInflater().inflate(R.layout.restore_purchases_list_footer, null);
((ImageView) restorePurchasesView.findViewById(R.id.icon)).setImageDrawable( ((ImageView) restorePurchasesView.findViewById(R.id.icon)).setImageDrawable(
getMyApplication().getIconsCache().getThemedIcon(R.drawable.ic_action_reset_to_default_dark)); getMyApplication().getIconsCache().getThemedIcon(R.drawable.ic_action_reset_to_default_dark));
@ -160,7 +164,7 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
@Override @Override
public void onClick(View v) { public void onClick(View v) {
restorePurchasesView.findViewById(R.id.progressBar).setVisibility(View.VISIBLE); restorePurchasesView.findViewById(R.id.progressBar).setVisibility(View.VISIBLE);
activity.startInAppHelper(); purchaseHelper.requestInventory();
} }
}); });
listView.addFooterView(restorePurchasesView); listView.addFooterView(restorePurchasesView);
@ -205,7 +209,7 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
} }
} }
if (restorePurchasesView != null && restorePurchasesView.findViewById(R.id.container).getVisibility() == View.GONE if (restorePurchasesView != null && restorePurchasesView.findViewById(R.id.container).getVisibility() == View.GONE
&& !InAppHelper.isInAppIntentoryRead()) { && purchaseHelper != null && !purchaseHelper.hasInventory()) {
if (worldBaseMapItem != null && worldBaseMapItem.isDownloaded()) { if (worldBaseMapItem != null && worldBaseMapItem.isDownloaded()) {
restorePurchasesView.findViewById(R.id.container).setVisibility(View.VISIBLE); restorePurchasesView.findViewById(R.id.container).setVisibility(View.VISIBLE);
} }
@ -260,6 +264,7 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
alertDialog.show(); alertDialog.show();
} }
@SuppressLint("StaticFieldLeak")
private void doSubscribe(final String email) { private void doSubscribe(final String email) {
new AsyncTask<Void, Void, String>() { new AsyncTask<Void, Void, String>() {
@ -329,7 +334,7 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
} }
@Override @Override
public void onError(String error) { public void onError(InAppPurchaseTaskType taskType, String error) {
} }
@Override @Override
@ -346,11 +351,11 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
} }
@Override @Override
public void showProgress() { public void showProgress(InAppPurchaseTaskType taskType) {
} }
@Override @Override
public void dismissProgress() { public void dismissProgress(InAppPurchaseTaskType taskType) {
if (restorePurchasesView != null && restorePurchasesView.findViewById(R.id.container).getVisibility() == View.VISIBLE) { if (restorePurchasesView != null && restorePurchasesView.findViewById(R.id.container).getVisibility() == View.VISIBLE) {
restorePurchasesView.findViewById(R.id.progressBar).setVisibility(View.GONE); restorePurchasesView.findViewById(R.id.progressBar).setVisibility(View.GONE);
} }

View file

@ -1,44 +0,0 @@
package net.osmand.plus.download.ui;
import android.app.Dialog;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.view.ContextThemeWrapper;
import android.view.View;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.Version;
import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.download.DownloadActivity.FreeVersionDialog;
import static net.osmand.plus.OsmandApplication.SHOW_PLUS_VERSION_INAPP_PARAM;
public class FreeVersionDialogFragment extends DialogFragment {
public static final String TAG = "FreeVersionDialogFragment";
private FreeVersionDialog dialog;
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
OsmandApplication app = (OsmandApplication) getActivity().getApplication();
app.activateFetchedRemoteParams();
AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(getActivity(), R.style.OsmandDarkTheme));
builder.setNegativeButton(R.string.later, null);
View view = getActivity().getLayoutInflater().inflate(R.layout.free_version_banner, null);
builder.setView(view);
dialog = new DownloadActivity.FreeVersionDialog(view, getDownloadActivity(), true);
dialog.initFreeVersionBanner();
dialog.expandBanner();
return builder.create();
}
DownloadActivity getDownloadActivity() {
return (DownloadActivity) getActivity();
}
}

View file

@ -14,7 +14,7 @@ import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.Version; import net.osmand.plus.Version;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.inapp.InAppHelper; import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.plus.liveupdates.OsmLiveActivity; import net.osmand.plus.liveupdates.OsmLiveActivity;
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarController; import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarController;
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControllerType; import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControllerType;
@ -109,7 +109,8 @@ public class DiscountHelper {
if (url.startsWith(INAPP_PREFIX) && url.length() > INAPP_PREFIX.length()) { if (url.startsWith(INAPP_PREFIX) && url.length() > INAPP_PREFIX.length()) {
String inAppSku = url.substring(INAPP_PREFIX.length()); String inAppSku = url.substring(INAPP_PREFIX.length());
if (InAppHelper.isPurchased(app, inAppSku)) { InAppPurchaseHelper purchaseHelper = app.getInAppPurchaseHelper();
if (purchaseHelper != null && purchaseHelper.isPurchased(inAppSku)) {
return; return;
} }
} }
@ -210,15 +211,11 @@ public class DiscountHelper {
private static void openUrl(final MapActivity mapActivity, String url) { private static void openUrl(final MapActivity mapActivity, String url) {
if (url.startsWith(INAPP_PREFIX)) { if (url.startsWith(INAPP_PREFIX)) {
if (url.contains(InAppHelper.SKU_FULL_VERSION_PRICE)) { if (url.contains(InAppPurchaseHelper.SKU_FULL_VERSION_PRICE)) {
mapActivity.execInAppTask(new InAppHelper.InAppRunnable() { OsmandApplication app = mapActivity.getMyApplication();
@Override app.logEvent(mapActivity, "in_app_purchase_redirect");
public void run(InAppHelper helper) { app.getInAppPurchaseHelper().purchaseFullVersion(mapActivity);
mapActivity.getMyApplication().logEvent(mapActivity, "in_app_purchase_redirect"); } else if (url.contains(InAppPurchaseHelper.SKU_LIVE_UPDATES)){
helper.purchaseFullVersion(mapActivity);
}
});
} else if (url.contains(InAppHelper.SKU_LIVE_UPDATES)){
Intent intent = new Intent(mapActivity, OsmLiveActivity.class); Intent intent = new Intent(mapActivity, OsmLiveActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
intent.putExtra(OsmLiveActivity.OPEN_SUBSCRIPTION_INTENT_PARAM, true); intent.putExtra(OsmLiveActivity.OPEN_SUBSCRIPTION_INTENT_PARAM, true);

View file

@ -1,5 +1,6 @@
package net.osmand.plus.inapp; package net.osmand.plus.inapp;
import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.os.AsyncTask; import android.os.AsyncTask;
@ -26,29 +27,29 @@ import net.osmand.util.Algorithms;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public class InAppHelper { public class InAppPurchaseHelper {
// Debug tag, for logging // Debug tag, for logging
static final String TAG = "InAppHelper"; private static final String TAG = InAppPurchaseHelper.class.getSimpleName();
boolean mDebugLog = false; boolean mDebugLog = false;
private static boolean mSubscribedToLiveUpdates = false; private long lastValidationCheckTime;
private static boolean mFullVersionPurchased = false; private String liveUpdatesPrice;
private static boolean mDepthContoursPurchased = false; private String fullVersionPrice;
private static String mLiveUpdatesPrice; private String depthContoursPrice;
private static long lastValidationCheckTime;
private static String mFullVersionPrice;
private static String mDepthContoursPrice;
public static final String SKU_FULL_VERSION_PRICE = "osmand_full_version_price"; public static final String SKU_FULL_VERSION_PRICE = "osmand_full_version_price";
private static final String SKU_LIVE_UPDATES_FULL = "osm_live_subscription_2"; private static final String SKU_LIVE_UPDATES_FULL = "osm_live_subscription_2";
private static final String SKU_LIVE_UPDATES_FREE = "osm_free_live_subscription_2"; private static final String SKU_LIVE_UPDATES_FREE = "osm_free_live_subscription_2";
private static final String SKU_DEPTH_CONTOURS_FULL = "net.osmand.seadepth_plus"; private static final String SKU_DEPTH_CONTOURS_FULL = "net.osmand.seadepth_plus";
private static final String SKU_DEPTH_CONTOURS_FREE = "net.osmand.seadepth"; private static final String SKU_DEPTH_CONTOURS_FREE = "net.osmand.seadepth";
public static String SKU_LIVE_UPDATES; public static String SKU_LIVE_UPDATES;
public static String SKU_DEPTH_CONTOURS; public static String SKU_DEPTH_CONTOURS;
@ -58,15 +59,13 @@ public class InAppHelper {
// The helper object // The helper object
private IabHelper mHelper; private IabHelper mHelper;
private boolean stopAfterResult = false; private boolean isDeveloperVersion;
private boolean isDeveloperVersion = false;
private boolean forceRequestInventory = false;
private String token = ""; private String token = "";
private boolean inventoryRequesting = false; private InAppPurchaseTaskType activeTask;
private boolean stopRequested = false; private boolean processingTask = false;
private OsmandApplication ctx; private OsmandApplication ctx;
private List<InAppListener> listeners = new ArrayList<>(); private List<InAppPurchaseListener> listeners = new ArrayList<>();
/* base64EncodedPublicKey should be YOUR APPLICATION'S PUBLIC KEY /* base64EncodedPublicKey should be YOUR APPLICATION'S PUBLIC KEY
* (that you got from the Google Play developer console). This is not your * (that you got from the Google Play developer console). This is not your
@ -86,60 +85,64 @@ public class InAppHelper {
"I+ftJO46a1XkNh1dO2anUiQ8P/H4yOTqnMsXF7biyYuiwjXPOcy0OMhEHi54Dq6Mr3u5ZALOAkc" + "I+ftJO46a1XkNh1dO2anUiQ8P/H4yOTqnMsXF7biyYuiwjXPOcy0OMhEHi54Dq6Mr3u5ZALOAkc" +
"YTjh1H/ZgqIHy5ZluahINuDE76qdLYMXrDMQIDAQAB"; "YTjh1H/ZgqIHy5ZluahINuDE76qdLYMXrDMQIDAQAB";
public interface InAppListener { public interface InAppPurchaseListener {
void onError(String error); void onError(InAppPurchaseTaskType taskType, String error);
void onGetItems(); void onGetItems();
void onItemPurchased(String sku); void onItemPurchased(String sku);
void showProgress(); void showProgress(InAppPurchaseTaskType taskType);
void dismissProgress(); void dismissProgress(InAppPurchaseTaskType taskType);
}
public enum InAppPurchaseTaskType {
REQUEST_INVENTORY,
PURCHASE_FULL_VERSION,
PURCHASE_LIVE_UPDATES,
PURCHASE_DEPTH_CONTOURS
} }
public interface InAppRunnable { public interface InAppRunnable {
void run(InAppHelper helper); // return true if done and false if async task started
boolean run(InAppPurchaseHelper helper);
} }
public String getToken() { public String getToken() {
return token; return token;
} }
public static boolean isSubscribedToLiveUpdates() { public InAppPurchaseTaskType getActiveTask() {
return mSubscribedToLiveUpdates; return activeTask;
} }
public static boolean isFullVersionPurchased() { public boolean isSubscribedToLiveUpdates() {
return mFullVersionPurchased; return ctx.getSettings().LIVE_UPDATES_PURCHASED.get();
} }
public static boolean isDepthContoursPurchased() { public String getLiveUpdatesPrice() {
return mDepthContoursPurchased; return liveUpdatesPrice;
} }
public static String getLiveUpdatesPrice() { public String getFullVersionPrice() {
return mLiveUpdatesPrice; return fullVersionPrice;
} }
public static String getDepthContoursPrice() { public String getDepthContoursPrice() {
return mDepthContoursPrice; return depthContoursPrice;
} }
public static String getFullVersionPrice() { public String getSkuLiveUpdates() {
return mFullVersionPrice;
}
public static String getSkuLiveUpdates() {
return SKU_LIVE_UPDATES; return SKU_LIVE_UPDATES;
} }
public static boolean hasPrices(OsmandApplication app) { public boolean hasPrices() {
return !Algorithms.isEmpty(mLiveUpdatesPrice) return !Algorithms.isEmpty(liveUpdatesPrice)
&& (!Version.isFreeVersion(app) || !Algorithms.isEmpty(mFullVersionPrice)); && (!Version.isFreeVersion(ctx) || !Algorithms.isEmpty(fullVersionPrice));
} }
public static void initialize(OsmandApplication ctx) { private void initialize() {
if (SKU_LIVE_UPDATES == null) { if (SKU_LIVE_UPDATES == null) {
if (Version.isFreeVersion(ctx)) { if (Version.isFreeVersion(ctx)) {
SKU_LIVE_UPDATES = SKU_LIVE_UPDATES_FREE; SKU_LIVE_UPDATES = SKU_LIVE_UPDATES_FREE;
@ -156,26 +159,22 @@ public class InAppHelper {
} }
} }
public InAppHelper(OsmandApplication ctx, boolean forceRequestInventory) { public InAppPurchaseHelper(OsmandApplication ctx) {
this.ctx = ctx; this.ctx = ctx;
this.forceRequestInventory = forceRequestInventory; this.isDeveloperVersion = Version.isDeveloperVersion(ctx);
if (this.isDeveloperVersion) {
isDeveloperVersion = Version.isDeveloperVersion(ctx);
if (isDeveloperVersion) {
mSubscribedToLiveUpdates = true;
mFullVersionPurchased = true;
mDepthContoursPurchased = true;
ctx.getSettings().LIVE_UPDATES_PURCHASED.set(true); ctx.getSettings().LIVE_UPDATES_PURCHASED.set(true);
ctx.getSettings().FULL_VERSION_PURCHASED.set(true); ctx.getSettings().FULL_VERSION_PURCHASED.set(true);
ctx.getSettings().DEPTH_CONTOURS_PURCHASED.set(true); ctx.getSettings().DEPTH_CONTOURS_PURCHASED.set(true);
} }
initialize();
} }
public static boolean isInAppIntentoryRead() { public boolean hasInventory() {
return lastValidationCheckTime != 0; return lastValidationCheckTime != 0;
} }
public static boolean isPurchased(OsmandApplication ctx, String inAppSku) { public boolean isPurchased(String inAppSku) {
OsmandSettings settings = ctx.getSettings(); OsmandSettings settings = ctx.getSettings();
if (inAppSku.equals(SKU_FULL_VERSION_PRICE)) { if (inAppSku.equals(SKU_FULL_VERSION_PRICE)) {
return settings.FULL_VERSION_PURCHASED.get(); return settings.FULL_VERSION_PURCHASED.get();
@ -187,11 +186,18 @@ public class InAppHelper {
return false; return false;
} }
public void exec(final @NonNull InAppRunnable runnable) { private void exec(final @NonNull InAppPurchaseTaskType taskType, final @NonNull InAppRunnable runnable) {
this.stopAfterResult = true; if (isDeveloperVersion || !Version.isGooglePlayEnabled(ctx)) {
return;
}
if (processingTask) {
logError("Already processing task: " + taskType + ". Exit.");
return;
}
// Create the helper, passing it our context and the public key to verify signatures with // Create the helper, passing it our context and the public key to verify signatures with
logDebug("Creating InAppHelper."); logDebug("Creating InAppPurchaseHelper.");
mHelper = new IabHelper(ctx, BASE64_ENCODED_PUBLIC_KEY); mHelper = new IabHelper(ctx, BASE64_ENCODED_PUBLIC_KEY);
// enable debug logging (for a production application, you should set this to false). // enable debug logging (for a production application, you should set this to false).
@ -201,6 +207,8 @@ public class InAppHelper {
// will be called once setup completes. // will be called once setup completes.
logDebug("Starting setup."); logDebug("Starting setup.");
try { try {
processingTask = true;
activeTask = taskType;
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() { mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) { public void onIabSetupFinished(IabResult result) {
logDebug("Setup finished."); logDebug("Setup finished.");
@ -208,112 +216,115 @@ public class InAppHelper {
if (!result.isSuccess()) { if (!result.isSuccess()) {
// Oh noes, there was a problem. // Oh noes, there was a problem.
//complain("Problem setting up in-app billing: " + result); //complain("Problem setting up in-app billing: " + result);
notifyError(result.getMessage()); notifyError(taskType, result.getMessage());
if (stopAfterResult) { stop(true);
stop();
}
return; return;
} }
// Have we been disposed of in the meantime? If so, quit. // Have we been disposed of in the meantime? If so, quit.
if (mHelper == null) return; if (mHelper == null) {
stop(true);
return;
}
runnable.run(InAppHelper.this); processingTask = !runnable.run(InAppPurchaseHelper.this);
} }
}); });
} catch (Exception e) { } catch (Exception e) {
logError("exec Error", e); logError("exec Error", e);
if (stopAfterResult) { stop(true);
stop();
} }
} }
public boolean needRequestInventory() {
return !ctx.getSettings().BILLING_PURCHASE_TOKEN_SENT.get()
|| System.currentTimeMillis() - lastValidationCheckTime > PURCHASE_VALIDATION_PERIOD_MSEC;
} }
public void start(final boolean stopAfterResult) { public void requestInventory() {
this.stopAfterResult = stopAfterResult; notifyShowProgress(InAppPurchaseTaskType.REQUEST_INVENTORY);
exec(InAppPurchaseTaskType.REQUEST_INVENTORY, new InAppRunnable() {
// Create the helper, passing it our context and the public key to verify signatures with @Override
logDebug("Creating InAppHelper."); public boolean run(InAppPurchaseHelper helper) {
mHelper = new IabHelper(ctx, BASE64_ENCODED_PUBLIC_KEY);
// enable debug logging (for a production application, you should set this to false).
mHelper.enableDebugLogging(false);
// Start setup. This is asynchronous and the specified listener
// will be called once setup completes.
logDebug("Starting setup.");
try {
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
logDebug("Setup finished.");
if (!result.isSuccess()) {
// Oh noes, there was a problem.
//complain("Problem setting up in-app billing: " + result);
notifyError(result.getMessage());
if (stopAfterResult) {
stop();
}
return;
}
// Have we been disposed of in the meantime? If so, quit.
if (mHelper == null) return;
// IAB is fully set up. Now, let's get an inventory of stuff we own if needed.
if (forceRequestInventory || (!isDeveloperVersion &&
(!mSubscribedToLiveUpdates
|| !ctx.getSettings().BILLING_PURCHASE_TOKEN_SENT.get()
|| System.currentTimeMillis() - lastValidationCheckTime > PURCHASE_VALIDATION_PERIOD_MSEC))) {
logDebug("Setup successful. Querying inventory."); logDebug("Setup successful. Querying inventory.");
List<String> skus = new ArrayList<>(); List<String> skus = new ArrayList<>();
skus.add(SKU_LIVE_UPDATES); skus.add(SKU_LIVE_UPDATES);
skus.add(SKU_DEPTH_CONTOURS); skus.add(SKU_DEPTH_CONTOURS);
skus.add(SKU_FULL_VERSION_PRICE); skus.add(SKU_FULL_VERSION_PRICE);
try { try {
inventoryRequesting = true;
mHelper.queryInventoryAsync(true, skus, mGotInventoryListener); mHelper.queryInventoryAsync(true, skus, mGotInventoryListener);
return false;
} catch (Exception e) { } catch (Exception e) {
inventoryRequesting = false;
logError("queryInventoryAsync Error", e); logError("queryInventoryAsync Error", e);
notifyDismissProgress(); notifyDismissProgress(InAppPurchaseTaskType.REQUEST_INVENTORY);
if (stopAfterResult) { stop(true);
stop();
}
}
} else {
notifyDismissProgress();
if (stopAfterResult) {
stop();
}
} }
return true;
} }
}); });
}
public void purchaseFullVersion(final Activity activity) {
notifyShowProgress(InAppPurchaseTaskType.PURCHASE_FULL_VERSION);
exec(InAppPurchaseTaskType.PURCHASE_FULL_VERSION, new InAppRunnable() {
@Override
public boolean run(InAppPurchaseHelper helper) {
try {
mHelper.launchPurchaseFlow(activity,
SKU_FULL_VERSION_PRICE, RC_REQUEST, mPurchaseFinishedListener);
return false;
} catch (Exception e) { } catch (Exception e) {
logError("start Error", e); complain("Cannot launch full version purchase!");
if (stopAfterResult) { logError("purchaseFullVersion Error", e);
stop(); stop(true);
} }
return true;
} }
});
}
public void purchaseLiveUpdates(Activity activity, String email, String userName,
String countryDownloadName, boolean hideUserName) {
notifyShowProgress(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES);
new LiveUpdatesPurchaseTask(activity, email, userName, countryDownloadName, hideUserName)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
}
public void purchaseDepthContours(final Activity activity) {
notifyShowProgress(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS);
exec(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS, new InAppRunnable() {
@Override
public boolean run(InAppPurchaseHelper helper) {
try {
mHelper.launchPurchaseFlow(activity,
SKU_DEPTH_CONTOURS, RC_REQUEST, mPurchaseFinishedListener);
return false;
} catch (Exception e) {
complain("Cannot launch depth contours purchase!");
logError("purchaseDepthContours Error", e);
stop(true);
}
return true;
}
});
} }
// Listener that's called when we finish querying the items and subscriptions we own // Listener that's called when we finish querying the items and subscriptions we own
private QueryInventoryFinishedListener mGotInventoryListener = new QueryInventoryFinishedListener() { private QueryInventoryFinishedListener mGotInventoryListener = new QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result, Inventory inventory) { public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
logDebug("Query inventory finished."); logDebug("Query inventory finished.");
inventoryRequesting = false;
// Have we been disposed of in the meantime? If so, quit. // Have we been disposed of in the meantime? If so, quit.
if (mHelper == null) return; if (mHelper == null) {
stop(true);
return;
}
// Is it a failure? // Is it a failure?
if (result.isFailure() || stopRequested) { if (result.isFailure()) {
logError("Failed to query inventory: " + result); logError("Failed to query inventory: " + result);
notifyError(result.getMessage()); notifyError(InAppPurchaseTaskType.REQUEST_INVENTORY, result.getMessage());
if (stopAfterResult || stopRequested) { stop(true);
stop();
}
return; return;
} }
@ -327,47 +338,43 @@ public class InAppHelper {
// Do we have the live updates? // Do we have the live updates?
Purchase liveUpdatesPurchase = inventory.getPurchase(SKU_LIVE_UPDATES); Purchase liveUpdatesPurchase = inventory.getPurchase(SKU_LIVE_UPDATES);
mSubscribedToLiveUpdates = isDeveloperVersion || (liveUpdatesPurchase != null && liveUpdatesPurchase.getPurchaseState() == 0); boolean subscribedToLiveUpdates = (liveUpdatesPurchase != null && liveUpdatesPurchase.getPurchaseState() == 0);
if (mSubscribedToLiveUpdates) { //subscribedToLiveUpdates = false;
ctx.getSettings().LIVE_UPDATES_PURCHASED.set(true); ctx.getSettings().LIVE_UPDATES_PURCHASED.set(subscribedToLiveUpdates);
}
Purchase fullVersionPurchase = inventory.getPurchase(SKU_FULL_VERSION_PRICE); Purchase fullVersionPurchase = inventory.getPurchase(SKU_FULL_VERSION_PRICE);
mFullVersionPurchased = isDeveloperVersion || (fullVersionPurchase != null && fullVersionPurchase.getPurchaseState() == 0); boolean fullVersionPurchased = (fullVersionPurchase != null && fullVersionPurchase.getPurchaseState() == 0);
if (mFullVersionPurchased) { if (fullVersionPurchased) {
ctx.getSettings().FULL_VERSION_PURCHASED.set(true); ctx.getSettings().FULL_VERSION_PURCHASED.set(true);
} }
Purchase depthContoursPurchase = inventory.getPurchase(SKU_DEPTH_CONTOURS); Purchase depthContoursPurchase = inventory.getPurchase(SKU_DEPTH_CONTOURS);
mDepthContoursPurchased = isDeveloperVersion || (depthContoursPurchase != null && depthContoursPurchase.getPurchaseState() == 0); boolean depthContoursPurchased = (depthContoursPurchase != null && depthContoursPurchase.getPurchaseState() == 0);
if (mDepthContoursPurchased) { if (depthContoursPurchased) {
ctx.getSettings().DEPTH_CONTOURS_PURCHASED.set(true); ctx.getSettings().DEPTH_CONTOURS_PURCHASED.set(true);
} }
lastValidationCheckTime = System.currentTimeMillis(); lastValidationCheckTime = System.currentTimeMillis();
logDebug("User " + (mSubscribedToLiveUpdates ? "HAS" : "DOES NOT HAVE") logDebug("User " + (subscribedToLiveUpdates ? "HAS" : "DOES NOT HAVE")
+ " live updates purchased."); + " live updates purchased.");
if (inventory.hasDetails(SKU_LIVE_UPDATES)) { if (inventory.hasDetails(SKU_LIVE_UPDATES)) {
SkuDetails liveUpdatesDetails = inventory.getSkuDetails(SKU_LIVE_UPDATES); SkuDetails liveUpdatesDetails = inventory.getSkuDetails(SKU_LIVE_UPDATES);
mLiveUpdatesPrice = liveUpdatesDetails.getPrice(); liveUpdatesPrice = liveUpdatesDetails.getPrice();
} }
if (inventory.hasDetails(SKU_DEPTH_CONTOURS)) {
SkuDetails depthContoursDetails = inventory.getSkuDetails(SKU_DEPTH_CONTOURS);
mDepthContoursPrice = depthContoursDetails.getPrice();
}
if (inventory.hasDetails(SKU_FULL_VERSION_PRICE)) { if (inventory.hasDetails(SKU_FULL_VERSION_PRICE)) {
SkuDetails fullPriceDetails = inventory.getSkuDetails(SKU_FULL_VERSION_PRICE); SkuDetails fullPriceDetails = inventory.getSkuDetails(SKU_FULL_VERSION_PRICE);
mFullVersionPrice = fullPriceDetails.getPrice(); fullVersionPrice = fullPriceDetails.getPrice();
}
if (inventory.hasDetails(SKU_DEPTH_CONTOURS)) {
SkuDetails depthContoursDetails = inventory.getSkuDetails(SKU_DEPTH_CONTOURS);
depthContoursPrice = depthContoursDetails.getPrice();
} }
OsmandSettings settings = ctx.getSettings(); OsmandSettings settings = ctx.getSettings();
settings.INAPPS_READ.set(true); settings.INAPPS_READ.set(true);
boolean needSendToken = false; boolean needSendToken = false;
if (!isDeveloperVersion && liveUpdatesPurchase != null) { if (liveUpdatesPurchase != null) {
if ((Algorithms.isEmpty(settings.BILLING_USER_ID.get()) || Algorithms.isEmpty(settings.BILLING_USER_TOKEN.get())) if ((Algorithms.isEmpty(settings.BILLING_USER_ID.get()) || Algorithms.isEmpty(settings.BILLING_USER_TOKEN.get()))
&& !Algorithms.isEmpty(liveUpdatesPurchase.getDeveloperPayload())) { && !Algorithms.isEmpty(liveUpdatesPurchase.getDeveloperPayload())) {
String payload = liveUpdatesPurchase.getDeveloperPayload(); String payload = liveUpdatesPurchase.getDeveloperPayload();
@ -390,11 +397,9 @@ public class InAppHelper {
final OnRequestResultListener listener = new OnRequestResultListener() { final OnRequestResultListener listener = new OnRequestResultListener() {
@Override @Override
public void onResult(String result) { public void onResult(String result) {
notifyDismissProgress(); notifyDismissProgress(InAppPurchaseTaskType.REQUEST_INVENTORY);
notifyGetItems(); notifyGetItems();
if (stopAfterResult || stopRequested) { stop(true);
stop();
}
logDebug("Initial inapp query finished"); logDebug("Initial inapp query finished");
} }
}; };
@ -407,81 +412,28 @@ public class InAppHelper {
} }
}; };
public void purchaseFullVersion(final Activity activity) { @SuppressLint("StaticFieldLeak")
if (mHelper == null) { private class LiveUpdatesPurchaseTask extends AsyncTask<Void, Void, String> {
//complain("In-app hepler is not initialized!");
notifyError("In-app hepler is not initialized!");
if (stopAfterResult) {
stop();
}
return;
}
logDebug("Launching purchase flow for full version"); private WeakReference<Activity> activity;
if (mHelper != null) {
try {
mHelper.launchPurchaseFlow(activity,
SKU_FULL_VERSION_PRICE, RC_REQUEST, mPurchaseFinishedListener);
} catch (Exception e) {
complain("Cannot launch full version purchase!");
logError("purchaseFullVersion Error", e);
if (stopAfterResult) {
stop();
}
}
}
}
public void purchaseDepthContours(final Activity activity) { private String email;
if (mHelper == null) { private String userName;
//complain("In-app hepler is not initialized!"); private String countryDownloadName;
notifyError("In-app hepler is not initialized!"); private boolean hideUserName;
if (stopAfterResult) {
stop();
}
return;
}
logDebug("Launching purchase flow for sea depth contours");
if (mHelper != null) {
try {
mHelper.launchPurchaseFlow(activity,
SKU_DEPTH_CONTOURS, RC_REQUEST, mPurchaseFinishedListener);
} catch (Exception e) {
complain("Cannot launch depth contours purchase!");
logError("purchaseDepthContours Error", e);
if (stopAfterResult) {
stop();
}
}
}
}
public void purchaseLiveUpdates(final Activity activity, final String email, final String userName,
final String countryDownloadName, final boolean hideUserName) {
try {
if (mHelper == null || !mHelper.subscriptionsSupported()) {
complain("Subscriptions not supported on your device yet. Sorry!");
notifyError("Subscriptions not supported on your device yet. Sorry!");
if (stopAfterResult) {
stop();
}
return;
}
} catch (Exception e) {
logError("purchaseLiveUpdates Error", e);
if (stopAfterResult) {
stop();
}
return;
}
notifyShowProgress();
new AsyncTask<Void, Void, String>() {
private String userId; private String userId;
LiveUpdatesPurchaseTask(Activity activity, String email, String userName,
String countryDownloadName, boolean hideUserName) {
this.activity = new WeakReference<>(activity);
this.email = email;
this.userName = userName;
this.countryDownloadName = countryDownloadName;
this.hideUserName = hideUserName;
}
@Override @Override
protected String doInBackground(Void... params) { protected String doInBackground(Void... params) {
userId = ctx.getSettings().BILLING_USER_ID.get(); userId = ctx.getSettings().BILLING_USER_ID.get();
@ -509,11 +461,9 @@ public class InAppHelper {
logDebug("Response=" + response); logDebug("Response=" + response);
if (response == null) { if (response == null) {
complain("Cannot retrieve userId from server."); complain("Cannot retrieve userId from server.");
notifyDismissProgress(); notifyDismissProgress(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES);
notifyError("Cannot retrieve userId from server."); notifyError(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES, "Cannot retrieve userId from server.");
if (stopAfterResult) { stop(true);
stop();
}
return; return;
} else { } else {
@ -528,39 +478,42 @@ public class InAppHelper {
String message = "JSON parsing error: " String message = "JSON parsing error: "
+ (e.getMessage() == null ? "unknown" : e.getMessage()); + (e.getMessage() == null ? "unknown" : e.getMessage());
complain(message); complain(message);
notifyDismissProgress(); notifyDismissProgress(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES);
notifyError(message); notifyError(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES, message);
if (stopAfterResult) { stop(true);
stop();
}
} }
} }
notifyDismissProgress(); notifyDismissProgress(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES);
if (!Algorithms.isEmpty(userId)) { if (!Algorithms.isEmpty(userId)) {
logDebug("Launching purchase flow for live updates subscription for userId=" + userId); logDebug("Launching purchase flow for live updates subscription for userId=" + userId);
String payload = userId + " " + token; final String payload = userId + " " + token;
if (mHelper != null) { exec(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES, new InAppRunnable() {
@Override
public boolean run(InAppPurchaseHelper helper) {
try { try {
mHelper.launchPurchaseFlow(activity, Activity a = activity.get();
if (a != null) {
mHelper.launchPurchaseFlow(a,
SKU_LIVE_UPDATES, IabHelper.ITEM_TYPE_SUBS, SKU_LIVE_UPDATES, IabHelper.ITEM_TYPE_SUBS,
RC_REQUEST, mPurchaseFinishedListener, payload); RC_REQUEST, mPurchaseFinishedListener, payload);
return false;
} else {
stop(true);
}
} catch (Exception e) { } catch (Exception e) {
logError("launchPurchaseFlow Error", e); logError("launchPurchaseFlow Error", e);
if (stopAfterResult) { stop(true);
stop();
}
} }
return true;
} }
});
} else { } else {
notifyError("Empty userId"); notifyError(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES,"Empty userId");
if (stopAfterResult) { stop(true);
stop();
} }
} }
} }
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
}
public boolean onActivityResultHandled(int requestCode, int resultCode, Intent data) { public boolean onActivityResultHandled(int requestCode, int resultCode, Intent data) {
logDebug("onActivityResult(" + requestCode + "," + resultCode + "," + data); logDebug("onActivityResult(" + requestCode + "," + resultCode + "," + data);
@ -590,15 +543,16 @@ public class InAppHelper {
logDebug("Purchase finished: " + result + ", purchase: " + purchase); logDebug("Purchase finished: " + result + ", purchase: " + purchase);
// if we were disposed of in the meantime, quit. // if we were disposed of in the meantime, quit.
if (mHelper == null) return; if (mHelper == null) {
stop(true);
return;
}
if (result.isFailure()) { if (result.isFailure()) {
complain("Error purchasing: " + result); complain("Error purchasing: " + result);
notifyDismissProgress(); notifyDismissProgress(activeTask);
notifyError("Error purchasing: " + result); notifyError(activeTask, "Error purchasing: " + result);
if (stopAfterResult) { stop(true);
stop();
}
return; return;
} }
@ -611,58 +565,61 @@ public class InAppHelper {
@Override @Override
public void onResult(String result) { public void onResult(String result) {
showToast(ctx.getString(R.string.osm_live_thanks)); showToast(ctx.getString(R.string.osm_live_thanks));
mSubscribedToLiveUpdates = true;
ctx.getSettings().LIVE_UPDATES_PURCHASED.set(true); ctx.getSettings().LIVE_UPDATES_PURCHASED.set(true);
notifyDismissProgress(); notifyDismissProgress(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES);
notifyItemPurchased(SKU_LIVE_UPDATES); notifyItemPurchased(SKU_LIVE_UPDATES);
if (stopAfterResult) { stop(true);
stop();
}
} }
}); });
}
if (purchase.getSku().equals(SKU_FULL_VERSION_PRICE)) { } else if (purchase.getSku().equals(SKU_FULL_VERSION_PRICE)) {
// bought full version // bought full version
logDebug("Full version purchased."); logDebug("Full version purchased.");
showToast(ctx.getString(R.string.full_version_thanks)); showToast(ctx.getString(R.string.full_version_thanks));
mFullVersionPurchased = true;
ctx.getSettings().FULL_VERSION_PURCHASED.set(true); ctx.getSettings().FULL_VERSION_PURCHASED.set(true);
notifyDismissProgress(); notifyDismissProgress(InAppPurchaseTaskType.PURCHASE_FULL_VERSION);
notifyItemPurchased(SKU_FULL_VERSION_PRICE); notifyItemPurchased(SKU_FULL_VERSION_PRICE);
if (stopAfterResult) { stop(true);
stop();
} } else if (purchase.getSku().equals(SKU_DEPTH_CONTOURS)) {
}
if (purchase.getSku().equals(SKU_DEPTH_CONTOURS)) {
// bought sea depth contours // bought sea depth contours
logDebug("Sea depth contours purchased."); logDebug("Sea depth contours purchased.");
showToast(ctx.getString(R.string.sea_depth_thanks)); showToast(ctx.getString(R.string.sea_depth_thanks));
mDepthContoursPurchased = true;
ctx.getSettings().DEPTH_CONTOURS_PURCHASED.set(true); ctx.getSettings().DEPTH_CONTOURS_PURCHASED.set(true);
ctx.getSettings().getCustomRenderBooleanProperty("depthContours").set(true); ctx.getSettings().getCustomRenderBooleanProperty("depthContours").set(true);
notifyDismissProgress(); notifyDismissProgress(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS);
notifyItemPurchased(SKU_DEPTH_CONTOURS); notifyItemPurchased(SKU_DEPTH_CONTOURS);
if (stopAfterResult) { stop(true);
stop();
} } else {
notifyDismissProgress(activeTask);
stop(true);
} }
} }
}; };
// Do not forget call stop() when helper is not needed anymore // Do not forget call stop() when helper is not needed anymore
public void stop() { public void stop() {
stop(false);
}
private void stop(boolean taskDone) {
logDebug("Destroying helper."); logDebug("Destroying helper.");
if (mHelper != null) { if (mHelper != null) {
if (!inventoryRequesting) { if (taskDone) {
stopRequested = false; processingTask = false;
}
if (!processingTask) {
activeTask = null;
mHelper.dispose(); mHelper.dispose();
mHelper = null; mHelper = null;
} else {
stopRequested = true;
} }
} else {
processingTask = false;
activeTask = null;
} }
} }
@ -739,46 +696,46 @@ public class InAppHelper {
} }
} }
private void notifyError(String message) { private void notifyError(InAppPurchaseTaskType taskType, String message) {
for (InAppListener l : listeners) { for (InAppPurchaseListener l : listeners) {
l.onError(message); l.onError(taskType, message);
} }
} }
private void notifyGetItems() { private void notifyGetItems() {
for (InAppListener l : listeners) { for (InAppPurchaseListener l : listeners) {
l.onGetItems(); l.onGetItems();
} }
} }
private void notifyItemPurchased(String sku) { private void notifyItemPurchased(String sku) {
for (InAppListener l : listeners) { for (InAppPurchaseListener l : listeners) {
l.onItemPurchased(sku); l.onItemPurchased(sku);
} }
} }
private void notifyShowProgress() { private void notifyShowProgress(InAppPurchaseTaskType taskType) {
for (InAppListener l : listeners) { for (InAppPurchaseListener l : listeners) {
l.showProgress(); l.showProgress(taskType);
} }
} }
private void notifyDismissProgress() { private void notifyDismissProgress(InAppPurchaseTaskType taskType) {
for (InAppListener l : listeners) { for (InAppPurchaseListener l : listeners) {
l.dismissProgress(); l.dismissProgress(taskType);
} }
} }
public void addListener(InAppListener listener) { public void addListener(InAppPurchaseListener listener) {
this.listeners.add(listener); this.listeners.add(listener);
} }
public void removeListener(InAppListener listener) { public void removeListener(InAppPurchaseListener listener) {
this.listeners.remove(listener); this.listeners.remove(listener);
} }
private void complain(String message) { private void complain(String message) {
logError("**** InAppHelper Error: " + message); logError("**** InAppPurchaseHelper Error: " + message);
showToast(message); showToast(message);
} }
@ -787,7 +744,9 @@ public class InAppHelper {
} }
private void logDebug(String msg) { private void logDebug(String msg) {
if (mDebugLog) Log.d(TAG, msg); if (mDebugLog) {
Log.d(TAG, msg);
}
} }
private void logError(String msg) { private void logError(String msg) {

View file

@ -10,10 +10,10 @@ import android.content.res.Resources;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.DrawableRes; import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.support.v4.view.MenuItemCompat; import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
@ -45,10 +45,12 @@ import net.osmand.plus.Version;
import net.osmand.plus.activities.LocalIndexHelper; import net.osmand.plus.activities.LocalIndexHelper;
import net.osmand.plus.activities.LocalIndexInfo; import net.osmand.plus.activities.LocalIndexInfo;
import net.osmand.plus.activities.OsmandBaseExpandableListAdapter; import net.osmand.plus.activities.OsmandBaseExpandableListAdapter;
import net.osmand.plus.activities.OsmandInAppPurchaseActivity;
import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.base.BaseOsmAndFragment;
import net.osmand.plus.download.ui.AbstractLoadLocalIndexTask; import net.osmand.plus.download.ui.AbstractLoadLocalIndexTask;
import net.osmand.plus.inapp.InAppHelper; import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.plus.inapp.InAppHelper.InAppListener; import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseListener;
import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseTaskType;
import net.osmand.plus.resources.IncrementalChangesManager; import net.osmand.plus.resources.IncrementalChangesManager;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -73,7 +75,7 @@ import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceUpdateFreq
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.runLiveUpdate; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.runLiveUpdate;
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.setAlarmForPendingIntent; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.setAlarmForPendingIntent;
public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppListener { public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppPurchaseListener {
public static final int TITLE = R.string.live_updates; public static final int TITLE = R.string.live_updates;
private static final int SUBSCRIPTION_SETTINGS = 5; private static final int SUBSCRIPTION_SETTINGS = 5;
public static final Comparator<LocalIndexInfo> LOCAL_INDEX_INFO_COMPARATOR = new Comparator<LocalIndexInfo>() { public static final Comparator<LocalIndexInfo> LOCAL_INDEX_INFO_COMPARATOR = new Comparator<LocalIndexInfo>() {
@ -90,10 +92,11 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppList
private ProgressBar progressBar; private ProgressBar progressBar;
private boolean processing; private boolean processing;
public InAppHelper getInAppHelper() { @Nullable
public InAppPurchaseHelper getInAppPurchaseHelper() {
Activity activity = getActivity(); Activity activity = getActivity();
if (activity instanceof OsmLiveActivity) { if (activity instanceof OsmandInAppPurchaseActivity) {
return ((OsmLiveActivity) activity).getInAppHelper(); return ((OsmandInAppPurchaseActivity) activity).getPurchaseHelper();
} else { } else {
return null; return null;
} }
@ -121,7 +124,8 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppList
listView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() { listView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override @Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
if (!processing && InAppHelper.isSubscribedToLiveUpdates()) { InAppPurchaseHelper purchaseHelper = getInAppPurchaseHelper();
if (!processing && purchaseHelper != null && purchaseHelper.isSubscribedToLiveUpdates()) {
final FragmentManager fragmentManager = getChildFragmentManager(); final FragmentManager fragmentManager = getChildFragmentManager();
LiveUpdatesSettingsDialogFragment LiveUpdatesSettingsDialogFragment
.createInstance(adapter.getChild(groupPosition, childPosition).getFileName()) .createInstance(adapter.getChild(groupPosition, childPosition).getFileName())
@ -143,7 +147,8 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppList
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override @Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (position == 0 && !processing && InAppHelper.isSubscribedToLiveUpdates()) { InAppPurchaseHelper purchaseHelper = getInAppPurchaseHelper();
if (position == 0 && !processing && purchaseHelper != null && purchaseHelper.isSubscribedToLiveUpdates()) {
SubscriptionFragment subscriptionFragment = new SubscriptionFragment(); SubscriptionFragment subscriptionFragment = new SubscriptionFragment();
subscriptionFragment.setEditMode(true); subscriptionFragment.setEditMode(true);
subscriptionFragment.show(getChildFragmentManager(), SubscriptionFragment.TAG); subscriptionFragment.show(getChildFragmentManager(), SubscriptionFragment.TAG);
@ -207,17 +212,17 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppList
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
InAppHelper helper = getInAppHelper(); InAppPurchaseHelper purchaseHelper = getInAppPurchaseHelper();
if (helper != null) { if (purchaseHelper != null) {
if (purchaseHelper.getActiveTask() == InAppPurchaseTaskType.REQUEST_INVENTORY) {
enableProgress(); enableProgress();
helper.addListener(this); }
helper.start(false); purchaseHelper.addListener(this);
} }
if (((OsmLiveActivity) getActivity()).shouldOpenSubscription()) { if (((OsmLiveActivity) getActivity()).shouldOpenSubscription()) {
SubscriptionFragment subscriptionFragment = new SubscriptionFragment(); SubscriptionFragment subscriptionFragment = new SubscriptionFragment();
subscriptionFragment.show(getChildFragmentManager(), SubscriptionFragment.TAG); subscriptionFragment.show(getChildFragmentManager(), SubscriptionFragment.TAG);
} }
} }
@Override @Override
@ -227,11 +232,11 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppList
} }
@Override @Override
public void onDestroy() { public void onPause() {
super.onDestroy(); super.onPause();
InAppHelper helper = getInAppHelper(); InAppPurchaseHelper purchaseHelper = getInAppPurchaseHelper();
if (helper != null) { if (purchaseHelper != null) {
helper.removeListener(this); purchaseHelper.removeListener(this);
} }
} }
@ -383,7 +388,8 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppList
@Override @Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) { if (isChecked) {
if (InAppHelper.isSubscribedToLiveUpdates()) { InAppPurchaseHelper purchaseHelper = getInAppPurchaseHelper();
if (purchaseHelper != null && purchaseHelper.isSubscribedToLiveUpdates()) {
switchOnLiveUpdates(settings); switchOnLiveUpdates(settings);
} else { } else {
liveUpdatesSwitch.setChecked(false); liveUpdatesSwitch.setChecked(false);
@ -578,7 +584,8 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppList
descriptionTextView.setText(context.getString(R.string.last_map_change, lastCheckString)); descriptionTextView.setText(context.getString(R.string.last_map_change, lastCheckString));
} }
if (!fragment.isProcessing() && InAppHelper.isSubscribedToLiveUpdates()) { InAppPurchaseHelper purchaseHelper = fragment.getInAppPurchaseHelper();
if (!fragment.isProcessing() && purchaseHelper != null && purchaseHelper.isSubscribedToLiveUpdates()) {
final View.OnClickListener clickListener = new View.OnClickListener() { final View.OnClickListener clickListener = new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -673,14 +680,14 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppList
} }
@Override @Override
public void onError(String error) { public void onError(InAppPurchaseTaskType taskType, String error) {
disableProgress(); disableProgress();
} }
@Override @Override
public void onGetItems() { public void onGetItems() {
getSettings().LIVE_UPDATES_PURCHASED.set(InAppHelper.isSubscribedToLiveUpdates()); InAppPurchaseHelper purchaseHelper = getInAppPurchaseHelper();
if (!InAppHelper.isSubscribedToLiveUpdates()) { if (purchaseHelper != null && !purchaseHelper.isSubscribedToLiveUpdates()) {
getSettings().IS_LIVE_UPDATES_ON.set(false); getSettings().IS_LIVE_UPDATES_ON.set(false);
adapter.enableLiveUpdates(false); adapter.enableLiveUpdates(false);
} }
@ -689,18 +696,19 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppList
@Override @Override
public void onItemPurchased(String sku) { public void onItemPurchased(String sku) {
if (InAppHelper.getSkuLiveUpdates().equals(sku)) { InAppPurchaseHelper purchaseHelper = getInAppPurchaseHelper();
if (purchaseHelper != null && purchaseHelper.getSkuLiveUpdates().equals(sku)) {
updateSubscriptionHeader(); updateSubscriptionHeader();
} }
} }
@Override @Override
public void showProgress() { public void showProgress(InAppPurchaseTaskType taskType) {
enableProgress(); enableProgress();
} }
@Override @Override
public void dismissProgress() { public void dismissProgress(InAppPurchaseTaskType taskType) {
disableProgress(); disableProgress();
} }
} }

View file

@ -15,10 +15,8 @@ import android.view.MenuItem;
import net.osmand.AndroidNetworkUtils; import net.osmand.AndroidNetworkUtils;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.Version;
import net.osmand.plus.download.AbstractDownloadActivity; import net.osmand.plus.download.AbstractDownloadActivity;
import net.osmand.plus.download.DownloadIndexesThread; import net.osmand.plus.download.DownloadIndexesThread.DownloadEvents;
import net.osmand.plus.inapp.InAppHelper;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -28,32 +26,21 @@ import java.util.Date;
import java.util.Locale; import java.util.Locale;
import java.util.TimeZone; import java.util.TimeZone;
public class OsmLiveActivity extends AbstractDownloadActivity implements DownloadIndexesThread.DownloadEvents { public class OsmLiveActivity extends AbstractDownloadActivity implements DownloadEvents {
private final static Log LOG = PlatformUtil.getLog(OsmLiveActivity.class); private final static Log LOG = PlatformUtil.getLog(OsmLiveActivity.class);
public final static String OPEN_SUBSCRIPTION_INTENT_PARAM = "open_subscription_intent_param"; public final static String OPEN_SUBSCRIPTION_INTENT_PARAM = "open_subscription_intent_param";
private LiveUpdatesFragmentPagerAdapter pagerAdapter; private LiveUpdatesFragmentPagerAdapter pagerAdapter;
private InAppHelper inAppHelper;
private boolean openSubscription; private boolean openSubscription;
private GetLastUpdateDateTask getLastUpdateDateTask; private GetLastUpdateDateTask getLastUpdateDateTask;
private static final String URL = "https://osmand.net/api/osmlive_status"; private static final String URL = "https://osmand.net/api/osmlive_status";
public InAppHelper getInAppHelper() {
return inAppHelper;
}
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
getMyApplication().applyTheme(this); getMyApplication().applyTheme(this);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_livie_updates); setContentView(R.layout.activity_livie_updates);
if (Version.isGooglePlayEnabled(getMyApplication())) {
inAppHelper = new InAppHelper(getMyApplication(), false);
}
if (Version.isDeveloperVersion(getMyApplication())) {
inAppHelper = null;
}
Intent intent = getIntent(); Intent intent = getIntent();
if (intent != null && intent.getExtras() != null) { if (intent != null && intent.getExtras() != null) {
openSubscription = intent.getExtras().getBoolean(OPEN_SUBSCRIPTION_INTENT_PARAM, false); openSubscription = intent.getExtras().getBoolean(OPEN_SUBSCRIPTION_INTENT_PARAM, false);
@ -82,17 +69,6 @@ public class OsmLiveActivity extends AbstractDownloadActivity implements Downloa
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Pass on the activity result to the helper for handling
if (inAppHelper == null || !inAppHelper.onActivityResultHandled(requestCode, resultCode, data)) {
// not handled, so handle it ourselves (here's where you'd
// perform any handling of activity results not related to in-app
// billing...
super.onActivityResult(requestCode, resultCode, data);
}
}
@Override @Override
protected void onPause() { protected void onPause() {
super.onPause(); super.onPause();
@ -102,17 +78,17 @@ public class OsmLiveActivity extends AbstractDownloadActivity implements Downloa
@Override @Override
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
if (inAppHelper != null) {
inAppHelper.stop();
}
if (getLastUpdateDateTask != null) { if (getLastUpdateDateTask != null) {
getLastUpdateDateTask.cancel(true); getLastUpdateDateTask.cancel(true);
} }
} }
public boolean isInAppPurchaseAllowed() {
return true;
}
@Override @Override
public void newDownloadIndexes() { public void newDownloadIndexes() {
} }
@Override @Override

View file

@ -3,6 +3,8 @@ package net.osmand.plus.liveupdates;
import android.app.Activity; import android.app.Activity;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v7.widget.AppCompatCheckBox; import android.support.v7.widget.AppCompatCheckBox;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -22,9 +24,11 @@ import net.osmand.AndroidUtils;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.OsmandInAppPurchaseActivity;
import net.osmand.plus.base.BaseOsmAndDialogFragment; import net.osmand.plus.base.BaseOsmAndDialogFragment;
import net.osmand.plus.inapp.InAppHelper; import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.plus.inapp.InAppHelper.InAppListener; import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseListener;
import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseTaskType;
import net.osmand.plus.liveupdates.CountrySelectionFragment.CountryItem; import net.osmand.plus.liveupdates.CountrySelectionFragment.CountryItem;
import net.osmand.plus.liveupdates.CountrySelectionFragment.OnFragmentInteractionListener; import net.osmand.plus.liveupdates.CountrySelectionFragment.OnFragmentInteractionListener;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -35,7 +39,7 @@ import org.json.JSONObject;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class SubscriptionFragment extends BaseOsmAndDialogFragment implements InAppListener, OnFragmentInteractionListener { public class SubscriptionFragment extends BaseOsmAndDialogFragment implements InAppPurchaseListener, OnFragmentInteractionListener {
public static final String TAG = "SubscriptionFragment"; public static final String TAG = "SubscriptionFragment";
private static final String EDIT_MODE_ID = "edit_mode_id"; private static final String EDIT_MODE_ID = "edit_mode_id";
@ -59,10 +63,11 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
this.editMode = editMode; this.editMode = editMode;
} }
public InAppHelper getInAppHelper() { @Nullable
public InAppPurchaseHelper getInAppPurchaseHelper() {
Activity activity = getActivity(); Activity activity = getActivity();
if (activity instanceof OsmLiveActivity) { if (activity instanceof OsmandInAppPurchaseActivity) {
return ((OsmLiveActivity) activity).getInAppHelper(); return ((OsmandInAppPurchaseActivity) activity).getPurchaseHelper();
} else { } else {
return null; return null;
} }
@ -103,14 +108,9 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
InAppHelper helper = getInAppHelper();
if (helper != null) {
helper.addListener(this);
}
String userName = settings.BILLING_USER_NAME.get(); String userName = settings.BILLING_USER_NAME.get();
String email = settings.BILLING_USER_EMAIL.get(); String email = settings.BILLING_USER_EMAIL.get();
String countryDownloadName = settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.get(); String countryDownloadName = settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.get();
@ -214,8 +214,8 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
saveChangesButton.setOnClickListener(new View.OnClickListener() { saveChangesButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
InAppHelper helper = getInAppHelper(); InAppPurchaseHelper purchaseHelper = getInAppPurchaseHelper();
if (helper != null && applySettings(userNameEdit.getText().toString().trim(), if (purchaseHelper != null && applySettings(userNameEdit.getText().toString().trim(),
emailEdit.getText().toString().trim(), hideUserNameCheckbox.isChecked())) { emailEdit.getText().toString().trim(), hideUserNameCheckbox.isChecked())) {
final Map<String, String> parameters = new HashMap<>(); final Map<String, String> parameters = new HashMap<>();
@ -224,16 +224,16 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
parameters.put("email", settings.BILLING_USER_EMAIL.get()); parameters.put("email", settings.BILLING_USER_EMAIL.get());
parameters.put("cemail", prevEmail); parameters.put("cemail", prevEmail);
parameters.put("userid", settings.BILLING_USER_ID.get()); parameters.put("userid", settings.BILLING_USER_ID.get());
parameters.put("token", helper.getToken()); parameters.put("token", purchaseHelper.getToken());
showProgress(); showProgress(null);
AndroidNetworkUtils.sendRequestAsync(getMyApplication(), AndroidNetworkUtils.sendRequestAsync(getMyApplication(),
"http://download.osmand.net/subscription/update.php", "http://download.osmand.net/subscription/update.php",
parameters, "Sending data...", true, true, new AndroidNetworkUtils.OnRequestResultListener() { parameters, "Sending data...", true, true, new AndroidNetworkUtils.OnRequestResultListener() {
@Override @Override
public void onResult(String result) { public void onResult(String result) {
dismissProgress(); dismissProgress(null);
OsmandApplication app = getMyApplication(); OsmandApplication app = getMyApplication();
if (result != null) { if (result != null) {
try { try {
@ -283,12 +283,12 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
subscribeButton.setOnClickListener(new View.OnClickListener() { subscribeButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
InAppHelper helper = getInAppHelper(); InAppPurchaseHelper purchaseHelper = getInAppPurchaseHelper();
if (helper != null) { if (purchaseHelper != null) {
if (applySettings(userNameEdit.getText().toString().trim(), if (applySettings(userNameEdit.getText().toString().trim(),
emailEdit.getText().toString().trim(), hideUserNameCheckbox.isChecked())) { emailEdit.getText().toString().trim(), hideUserNameCheckbox.isChecked())) {
helper.purchaseLiveUpdates(getActivity(), purchaseHelper.purchaseLiveUpdates(getActivity(),
settings.BILLING_USER_EMAIL.get(), settings.BILLING_USER_EMAIL.get(),
settings.BILLING_USER_NAME.get(), settings.BILLING_USER_NAME.get(),
settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.get(), settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.get(),
@ -308,13 +308,27 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
return view; return view;
} }
@Override
public void onResume() {
super.onResume();
InAppPurchaseHelper purchaseHelper = getInAppPurchaseHelper();
if (purchaseHelper != null) {
purchaseHelper.addListener(this);
}
}
@Override
public void onPause() {
super.onPause();
InAppPurchaseHelper purchaseHelper = getInAppPurchaseHelper();
if (purchaseHelper != null) {
purchaseHelper.removeListener(this);
}
}
@Override @Override
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
InAppHelper helper = getInAppHelper();
if (helper != null) {
helper.removeListener(this);
}
if (dlg != null && dlg.isShowing()) { if (dlg != null && dlg.isShowing()) {
dlg.hide(); dlg.hide();
} }
@ -350,7 +364,7 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
} }
@Override @Override
public void onError(String error) { public void onError(InAppPurchaseTaskType taskType, String error) {
} }
@Override @Override
@ -365,7 +379,7 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
} }
@Override @Override
public void showProgress() { public void showProgress(InAppPurchaseTaskType taskType) {
if (dlg != null) { if (dlg != null) {
dlg.dismiss(); dlg.dismiss();
} }
@ -377,7 +391,7 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
} }
@Override @Override
public void dismissProgress() { public void dismissProgress(InAppPurchaseTaskType taskType) {
if (dlg != null) { if (dlg != null) {
dlg.dismiss(); dlg.dismiss();
dlg = null; dlg = null;
@ -402,8 +416,9 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
} }
if (view != null) { if (view != null) {
TextView priceTextView = (TextView) view.findViewById(R.id.priceTextView); TextView priceTextView = (TextView) view.findViewById(R.id.priceTextView);
if (InAppHelper.getLiveUpdatesPrice() != null) { InAppPurchaseHelper purchaseHelper = getInAppPurchaseHelper();
priceTextView.setText(InAppHelper.getLiveUpdatesPrice()); if (purchaseHelper.getLiveUpdatesPrice() != null) {
priceTextView.setText(purchaseHelper.getLiveUpdatesPrice());
} }
} }
} }