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"?>
<LinearLayout
android:id="@+id/freeVersionBanner"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:osmand="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/freeVersionBanner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/osmo_header_dark"
@ -18,220 +17,63 @@
android:paddingTop="@dimen/list_header_padding">
<LinearLayout
android:id="@+id/bannerTopLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:orientation="vertical"
android:paddingLeft="@dimen/list_content_padding"
android:paddingRight="@dimen/list_content_padding">
<LinearLayout
android:id="@+id/bannerTopLayout"
android:id="@+id/freeVersionBannerTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="@dimen/list_content_padding"
android:paddingRight="@dimen/list_content_padding">
<LinearLayout
android:id="@+id/freeVersionBannerTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="4dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/free_version_title"/>
<TextView
android:id="@+id/downloadsLeftTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="@string/downloads_left_template"/>
</LinearLayout>
android:padding="4dp">
<TextView
android:id="@+id/freeVersionDescriptionTextView"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="4dp"
tools:text="@string/free_version_message"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="8dp"
android:layout_margin="4dp">
<ProgressBar
android:id="@+id/downloadsLeftProgressBar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:max="10"
android:progressDrawable="@drawable/number_of_downloads_progress_bar_drawable"
android:saveEnabled="false"
tools:progress="6"/>
<LinearLayout
android:id="@+id/marksLinearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"/>
</FrameLayout>
android:layout_weight="1"
android:text="@string/free_version_title"/>
<TextView
android:id="@+id/downloadsLeftTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="@string/downloads_left_template"/>
</LinearLayout>
<LinearLayout
android:id="@+id/priceInfoLayout"
<TextView
android:id="@+id/freeVersionDescriptionTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/list_content_padding"
android:orientation="vertical">
android:layout_margin="4dp"
tools:text="@string/free_version_message"/>
<View
<FrameLayout
android:layout_width="match_parent"
android:layout_height="8dp"
android:layout_margin="4dp">
<ProgressBar
android:id="@+id/downloadsLeftProgressBar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/dashboard_divider_dark"
android:visibility="visible"/>
android:layout_height="match_parent"
android:max="10"
android:progressDrawable="@drawable/number_of_downloads_progress_bar_drawable"
android:saveEnabled="false"
tools:progress="6"/>
<LinearLayout
android:id="@+id/fullVersionLayout"
android:id="@+id/marksLinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/list_content_padding"
android:orientation="horizontal"
android:visibility="visible">
android:layout_height="match_parent"
android:orientation="horizontal"/>
</FrameLayout>
<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>
</LinearLayout>
</LinearLayout>

View file

@ -13,11 +13,19 @@
android:background="?attr/selectableItemBackground"
android:minHeight="@dimen/card_button_min_size"
android:orientation="vertical"
android:gravity="center"
android:paddingBottom="@dimen/list_header_padding"
android:paddingLeft="@dimen/list_content_padding"
android:paddingRight="@dimen/list_content_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
android:id="@+id/card_button_title"
android:layout_width="match_parent"

View file

@ -21,7 +21,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/action_bar_height"
android:layout_height="wrap_content"
android:orientation="horizontal">
<android.support.v7.widget.AppCompatImageView
@ -33,6 +33,17 @@
android:src="@drawable/ic_arrow_back"
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
@ -43,16 +54,6 @@
android:layout_marginRight="@dimen/list_content_padding_large"
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
android:id="@+id/info_container"
android:layout_width="match_parent"
@ -70,16 +71,6 @@
</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>

View file

@ -7,7 +7,8 @@
<dimen name="title_text_size">28sp</dimen>
<dimen name="card_title_row_min_height">64dp</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_border">6dp</dimen>

View file

@ -23,7 +23,7 @@
<string name="unlimited_downloads">Unlimited downloads</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="purchase_dialog_title">Choose plan</string>

View file

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

View file

@ -31,6 +31,7 @@ import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.download.ui.AbstractLoadLocalIndexTask;
import net.osmand.plus.helpers.AvoidSpecificRoads;
import net.osmand.plus.helpers.WaypointHelper;
import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.plus.liveupdates.LiveUpdatesHelper;
import net.osmand.plus.mapmarkers.MapMarkersDbHelper;
import net.osmand.plus.monitoring.LiveMonitoringHelper;
@ -421,6 +422,7 @@ public class AppInitializer implements IProgress {
e.printStackTrace();
}
app.applyTheme(app);
app.inAppPurchaseHelper = startupInit(new InAppPurchaseHelper(app), InAppPurchaseHelper.class);
app.poiTypes = startupInit(MapPoiTypes.getDefaultNoInit(), MapPoiTypes.class);
app.routingHelper = startupInit(new RoutingHelper(app), RoutingHelper.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.v7.app.AlertDialog;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.View;
import android.view.accessibility.AccessibilityManager;
import android.widget.ImageView;
@ -46,7 +45,7 @@ import net.osmand.plus.dialogs.RateUsBottomSheetDialog;
import net.osmand.plus.download.DownloadIndexesThread;
import net.osmand.plus.helpers.AvoidSpecificRoads;
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.mapmarkers.MapMarkersDbHelper;
import net.osmand.plus.monitoring.LiveMonitoringHelper;
@ -120,6 +119,7 @@ public class OsmandApplication extends MultiDexApplication {
GeocodingLookupService geocodingLookupService;
QuickSearchHelper searchUICore;
TravelDbHelper travelDbHelper;
InAppPurchaseHelper inAppPurchaseHelper;
RoutingConfiguration.Builder defaultRoutingConfig;
private Locale preferredLocale = null;
@ -166,7 +166,6 @@ public class OsmandApplication extends MultiDexApplication {
// if(!osmandSettings.FOLLOW_THE_ROUTE.get()) {
// targetPointsHelper.clearPointToNavigate(false);
// }
InAppHelper.initialize(this);
initExternalLibs();
startApplication();
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;
}
public InAppPurchaseHelper getInAppPurchaseHelper() {
return inAppPurchaseHelper;
}
public CommandPlayer getPlayer() {
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<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
public final OsmandPreference<String> USER_OSM_BUG_NAME =
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.ImportGpxBottomSheetDialogFragment;
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.MapContextMenu;
import net.osmand.plus.mapcontextmenu.MapContextMenuFragment;
@ -204,7 +205,7 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
private boolean permissionGranted;
private boolean mIsDestroyed = false;
private InAppHelper inAppHelper;
private InAppPurchaseHelper inAppPurchaseHelper;
private Timer splashScreenTimer;
private ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
@ -1214,8 +1215,8 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
if (atlasMapRendererView != null) {
atlasMapRendererView.handleOnDestroy();
}
if (inAppHelper != null) {
inAppHelper.stop();
if (inAppPurchaseHelper != null) {
inAppPurchaseHelper.stop();
}
mIsDestroyed = true;
}
@ -1513,7 +1514,7 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
@Override
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;
}
for (ActivityResultListener listener : activityResultListeners) {
@ -1920,43 +1921,4 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
DESTINATION_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;
import android.annotation.SuppressLint;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
@ -11,7 +12,8 @@ import android.view.ViewGroup;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
public class OsmandActionBarActivity extends AppCompatActivity {
@SuppressLint("Registered")
public class OsmandActionBarActivity extends OsmandInAppPurchaseActivity {
protected boolean haveHomeButton = true;
@ -50,8 +52,4 @@ public class OsmandActionBarActivity extends AppCompatActivity {
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.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.ColorRes;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
@ -18,68 +21,117 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import net.osmand.AndroidUtils;
import net.osmand.PlatformUtil;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.Version;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.BaseOsmAndDialogFragment;
import net.osmand.plus.download.DownloadActivity;
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.srtmplugin.SRTMPlugin;
import net.osmand.plus.widgets.TextViewEx;
import org.apache.commons.logging.Log;
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();
private static final Log LOG = PlatformUtil.getLog(ChoosePlanDialogFragment.class);
private static final String PLAN_TYPE_KEY = "plan_type";
private OsmandApplication app;
private InAppPurchaseHelper purchaseHelper;
private boolean nightMode;
private PlanType planType;
private OsmAndFeature[] osmandLiveFeatures = {
OsmAndFeature.UNLIMITED_DOWNLOADS,
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,
};
private View osmLiveCardButton;
private View planTypeCardButton;
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 osmandUnlimitedFeature;
private final OsmAndFeature[] osmLiveFeatures;
private final OsmAndFeature[] planTypeFeatures;
private final OsmAndFeature[] selectedOsmLiveFeatures;
private final OsmAndFeature[] selectedPlanTypeFeatures;
PlanType(OsmAndFeature osmandLiveFeature, OsmAndFeature osmandUnlimitedFeature) {
this.osmandLiveFeature = osmandLiveFeature;
this.osmandUnlimitedFeature = osmandUnlimitedFeature;
PlanType(OsmAndFeature[] osmLiveFeatures, OsmAndFeature[] selectedOsmLiveFeatures,
OsmAndFeature[] planTypeFeatures, OsmAndFeature[] selectedPlanTypeFeatures) {
this.osmLiveFeatures = osmLiveFeatures;
this.planTypeFeatures = planTypeFeatures;
this.selectedOsmLiveFeatures = selectedOsmLiveFeatures;
this.selectedPlanTypeFeatures = selectedPlanTypeFeatures;
}
public OsmAndFeature getOsmandLiveFeature() {
return osmandLiveFeature;
public OsmAndFeature[] getOsmLiveFeatures() {
return osmLiveFeatures;
}
public OsmAndFeature getOsmandUnlimitedFeature() {
return osmandUnlimitedFeature;
public OsmAndFeature[] getPlanTypeFeatures() {
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),
UNLIMITED_DOWNLOADS(R.string.unlimited_downloads),
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),
DONATION_TO_OSM(R.string.donation_to_osm);
@ -103,9 +156,27 @@ public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment {
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() {
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) {
super.onCreate(savedInstanceState);
app = getMyApplication();
purchaseHelper = app.getInAppPurchaseHelper();
Bundle args = getArguments();
if (args == null) {
args = savedInstanceState;
@ -130,13 +204,16 @@ public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment {
@NonNull
@Override
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);
Window window = dialog.getWindow();
if (window != null) {
if (!getSettings().DO_NOT_USE_ANIMATIONS.get()) {
window.getAttributes().windowAnimations = R.style.Animations_Alpha;
}
if (Build.VERSION.SDK_INT >= 21) {
window.setStatusBarColor(ContextCompat.getColor(getContext(), getStatusBarColor()));
}
}
return dialog;
}
@ -169,68 +246,28 @@ public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment {
switch (planType) {
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));
//infoDescription.setVisibility(View.GONE);
//View freeVersionInfoView = inflate(R.layout.purchase_dialog_info_free_version, infoContainer);
//initFreeVersionInfoView(ctx, freeVersionInfoView);
//infoContainer.addView(freeVersionInfoView);
break;
}
}
cardsContainer.addView(buildOsmAndLiveCard(ctx, cardsContainer));
cardsContainer.addView(buildOsmAndUnlimitedCard(ctx, cardsContainer));
cardsContainer.addView(buildOsmLiveCard(ctx, cardsContainer));
cardsContainer.addView(buildPlanTypeCard(ctx, cardsContainer));
return view;
}
/*
private void initFreeVersionInfoView(Context ctx, View freeVersionInfoView) {
TextView downloadsLeftTextView = (TextView) freeVersionInfoView.findViewById(R.id.downloadsLeftTextView);
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);
}
@ColorRes
protected int getStatusBarColor() {
return nightMode ? R.color.status_bar_wikivoyage_dark : R.color.status_bar_wikivoyage_light;
}
*/
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))
.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);
TextView headerTitle = (TextView) cardView.findViewById(R.id.header_title);
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);
ViewGroup rowsContainer = (ViewGroup) cardView.findViewById(R.id.rows_container);
View featureRowDiv = null;
for (OsmAndFeature feature : osmandLiveFeatures) {
for (OsmAndFeature feature : planType.getOsmLiveFeatures()) {
String featureName = feature.toHumanString(ctx);
// View featureRow = inflate(planType.osmandLiveFeature == feature
// ? R.layout.purchase_dialog_card_selected_row : R.layout.purchase_dialog_card_row, cardView);
View featureRow = inflate(R.layout.purchase_dialog_card_row, cardView);
View featureRow = inflate(planType.hasSelectedOsmLiveFeature(feature)
? R.layout.purchase_dialog_card_selected_row : R.layout.purchase_dialog_card_row, cardView);
TextViewEx titleView = (TextViewEx) featureRow.findViewById(R.id.title);
titleView.setText(featureName);
featureRowDiv = featureRow.findViewById(R.id.div);
@ -257,29 +293,49 @@ public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment {
TextViewEx cardDescription = (TextViewEx) cardView.findViewById(R.id.card_descr);
cardDescription.setText(R.string.osm_live_payment_desc);
View cardButton = cardView.findViewById(R.id.card_button);
TextViewEx buttonTitle = (TextViewEx) cardButton.findViewById(R.id.card_button_title);
TextViewEx buttonSubtitle = (TextViewEx) cardButton.findViewById(R.id.card_button_subtitle);
if (!InAppHelper.hasPrices(getMyApplication())) {
buttonTitle.setText(ctx.getString(R.string.purchase_subscription_title, ctx.getString(R.string.osm_live_default_price)));
} else {
buttonTitle.setText(ctx.getString(R.string.purchase_subscription_title, InAppHelper.getLiveUpdatesPrice()));
}
buttonSubtitle.setText(R.string.osm_live_month_cost_desc);
cardButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
subscript();
dismiss();
}
});
osmLiveCardButton = cardView.findViewById(R.id.card_button);
InAppPurchaseHelper purchaseHelper = app.getInAppPurchaseHelper();
boolean requestingInventory = purchaseHelper != null && purchaseHelper.getActiveTask() == InAppPurchaseTaskType.REQUEST_INVENTORY;
setupOsmLiveCardButton(requestingInventory);
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 {
buttonTitle.setText(getString(R.string.purchase_subscription_title, purchaseHelper.getLiveUpdatesPrice()));
}
buttonSubtitle.setText(R.string.osm_live_month_cost_desc);
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
public void onClick(View v) {
subscript();
dismiss();
}
});
}
}
}
private void subscript() {
Activity ctx = getActivity();
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.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
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);
TextView headerTitle = (TextView) cardView.findViewById(R.id.header_title);
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);
ViewGroup rowsContainer = (ViewGroup) cardView.findViewById(R.id.rows_container);
View featureRow = null;
for (OsmAndFeature feature : osmandUnlimitedFeatures) {
for (OsmAndFeature feature : planType.getPlanTypeFeatures()) {
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);
TextViewEx titleView = (TextViewEx) featureRow.findViewById(R.id.title);
titleView.setText(featureName);
@ -309,28 +365,46 @@ public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment {
TextViewEx cardDescription = (TextViewEx) cardView.findViewById(R.id.card_descr);
cardDescription.setText(R.string.in_app_purchase_desc_ex);
View cardButton = cardView.findViewById(R.id.card_button);
TextViewEx buttonTitle = (TextViewEx) cardButton.findViewById(R.id.card_button_title);
TextViewEx buttonSubtitle = (TextViewEx) cardButton.findViewById(R.id.card_button_subtitle);
if (!InAppHelper.hasPrices(getMyApplication())) {
buttonTitle.setText(ctx.getString(R.string.purchase_unlim_title, ctx.getString(R.string.full_version_price)));
} else {
buttonTitle.setText(ctx.getString(R.string.purchase_unlim_title, InAppHelper.getFullVersionPrice()));
}
buttonSubtitle.setText(R.string.in_app_purchase_desc);
cardButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
purchaseFullVersion();
dismiss();
}
});
planTypeCardButton = cardView.findViewById(R.id.card_button);
InAppPurchaseHelper purchaseHelper = app.getInAppPurchaseHelper();
boolean requestingInventory = purchaseHelper != null && purchaseHelper.getActiveTask() == InAppPurchaseTaskType.REQUEST_INVENTORY;
setupPlanTypeCardButton(requestingInventory);
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 {
buttonTitle.setText(getString(R.string.purchase_unlim_title, purchaseHelper.getFullVersionPrice()));
}
buttonSubtitle.setText(R.string.in_app_purchase_desc);
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
public void onClick(View v) {
purchaseFullVersion();
dismiss();
}
});
}
}
}
public void purchaseFullVersion() {
/*
OsmandApplication app = getMyApplication();
if (app.getRemoteBoolean(SHOW_PLUS_VERSION_INAPP_PARAM, true)) {
app.logEvent(getActivity(), "in_app_purchase_redirect_from_banner");
} else {
@ -338,12 +412,13 @@ public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment {
}
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);
InAppPurchaseHelper purchaseHelper = app.getInAppPurchaseHelper();
if (purchaseHelper != null) {
app.logEvent(getActivity(), "in_app_purchase_redirect");
purchaseHelper.purchaseFullVersion(getActivity());
}
} else {
app.logEvent(this, "paid_version_redirect");
app.logEvent(getActivity(), "paid_version_redirect");
Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse(Version.getUrlWithUtmRef(app, "net.osmand.plus")));
try {
@ -353,7 +428,6 @@ public class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment {
}
}
}
*/
}
@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) {
PlanType planType = PlanType.FREE_VERSION_BANNER;
showInstance(fm, planType);

View file

@ -1,12 +1,11 @@
package net.osmand.plus.download;
import android.Manifest;
import android.content.ActivityNotFoundException;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.StatFs;
@ -21,7 +20,6 @@ import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.Space;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.AppCompatButton;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
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.BottomSheetDialogFragment;
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.ui.ActiveDownloadsDialogFragment;
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.UpdatesIndexFragment;
import net.osmand.plus.helpers.FileNameTranslationHelper;
import net.osmand.plus.inapp.InAppHelper;
import net.osmand.plus.inapp.InAppHelper.InAppListener;
import net.osmand.plus.liveupdates.OsmLiveActivity;
import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseListener;
import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseTaskType;
import net.osmand.plus.openseamapsplugin.NauticalMapsPlugin;
import net.osmand.plus.srtmplugin.SRTMPlugin;
import net.osmand.plus.views.controls.PagerSlidingTabStrip;
@ -83,10 +79,8 @@ import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static net.osmand.plus.OsmandApplication.SHOW_PLUS_VERSION_INAPP_PARAM;
public class DownloadActivity extends AbstractDownloadActivity implements DownloadEvents,
OnRequestPermissionsResultCallback, InAppListener {
OnRequestPermissionsResultCallback {
private static final Log LOG = PlatformUtil.getLog(DownloadActivity.class);
public static final int UPDATES_TAB_NUMBER = 2;
@ -122,8 +116,6 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
protected WorldRegion downloadItem;
protected String downloadTargetFileName;
private InAppHelper inAppHelper;
private boolean srtmDisabled;
private boolean srtmNeedsInstallation;
private boolean nauticalPluginDisabled;
@ -196,11 +188,9 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
visibleBanner = new BannerAndDownloadFreeVersion(findViewById(R.id.mainLayout), this, true);
if (shouldShowFreeVersionBanner(getMyApplication())) {
visibleBanner.setUpdatingPrices(true);
visibleBanner.updateFreeVersionBanner();
}
startInAppHelper();
final Intent intent = getIntent();
if (intent != null && intent.getExtras() != null) {
filter = intent.getExtras().getString(FILTER_KEY);
@ -209,65 +199,60 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
}
}
@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);
}
public boolean isInAppPurchaseAllowed() {
return true;
}
@Override
public void onDestroy() {
super.onDestroy();
stopInAppHelper();
}
public void startInAppHelper() {
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 onInAppPurchaseError(InAppPurchaseTaskType taskType, String error) {
visibleBanner.updateFreeVersionBanner();
for (WeakReference<Fragment> ref : fragSet) {
Fragment f = ref.get();
if (f instanceof InAppPurchaseListener && f.isAdded()) {
((InAppPurchaseListener) f).onError(taskType, error);
}
}
}
public void purchaseDepthContours() {
if (inAppHelper != null) {
getMyApplication().logEvent(this, "depth_contours_purchase_redirect");
inAppHelper.purchaseDepthContours(this);
@Override
public void onInAppPurchaseGetItems() {
visibleBanner.updateFreeVersionBanner();
for (WeakReference<Fragment> ref : fragSet) {
Fragment f = ref.get();
if (f instanceof InAppPurchaseListener && f.isAdded()) {
((InAppPurchaseListener) f).onGetItems();
}
}
}
@Override
public void onInAppPurchaseItemPurchased(String sku) {
visibleBanner.updateFreeVersionBanner();
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
@UiThread
public void downloadInProgress() {
@ -478,26 +410,15 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
}
public static class FreeVersionDialog {
public static class FreeVersionBanner {
private final View freeVersionBanner;
private final View freeVersionBannerTitle;
private boolean updatingPrices;
private final View priceInfoLayout;
private final TextView freeVersionDescriptionTextView;
private final TextView downloadsLeftTextView;
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 boolean dialog;
private OnClickListener onCollapseListener = new OnClickListener() {
@Override
public void onClick(View v) {
@ -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.dialog = dialog;
freeVersionBanner = view.findViewById(R.id.freeVersionBanner);
downloadsLeftTextView = (TextView) freeVersionBanner.findViewById(R.id.downloadsLeftTextView);
downloadsLeftProgressBar = (ProgressBar) freeVersionBanner.findViewById(R.id.downloadsLeftProgressBar);
priceInfoLayout = freeVersionBanner.findViewById(R.id.priceInfoLayout);
freeVersionDescriptionTextView = (TextView) freeVersionBanner
.findViewById(R.id.freeVersionDescriptionTextView);
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() {
freeVersionDescriptionTextView.setVisibility(View.GONE);
// buttonsLinearLayout.setVisibility(View.GONE);
priceInfoLayout.setVisibility(View.GONE);
freeVersionBannerTitle.setVisibility(View.VISIBLE);
}
public void expandBanner() {
freeVersionDescriptionTextView.setVisibility(View.VISIBLE);
// buttonsLinearLayout.setVisibility(View.VISIBLE);
priceInfoLayout.setVisibility(View.VISIBLE);
freeVersionBannerTitle.setVisibility(View.VISIBLE);
}
public void initFreeVersionBanner() {
if (!shouldShowFreeVersionBanner(ctx.getMyApplication())) {
freeVersionBanner.setVisibility(View.GONE);
@ -559,33 +461,6 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
downloadsLeftProgressBar.setMax(DownloadValidationManager.MAXIMUM_AVAILABLE_FREE_DOWNLOADS);
freeVersionDescriptionTextView.setText(ctx.getString(R.string.free_version_message,
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);
Space spaceView = new Space(ctx);
@ -609,11 +484,7 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
}
updateFreeVersionBanner();
if(dialog) {
expandBanner();
} else {
collapseBanner();
}
collapseBanner();
}
public void updateFreeVersionBanner() {
@ -630,28 +501,7 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
int downloadsLeft = DownloadValidationManager.MAXIMUM_AVAILABLE_FREE_DOWNLOADS - mapsDownloaded;
downloadsLeft = Math.max(downloadsLeft, 0);
downloadsLeftTextView.setText(ctx.getString(R.string.downloads_left_template, downloadsLeft));
if(!dialog) {
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);
}
freeVersionBanner.findViewById(R.id.bannerTopLayout).setOnClickListener(onCollapseListener);
}
private void setMinimizedFreeVersionBanner(boolean minimize) {
@ -668,7 +518,6 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
final Integer mapsDownloaded = settings.NUMBER_OF_FREE_DOWNLOADS.get() + activeTasks;
downloadsLeftProgressBar.setProgress(mapsDownloaded);
}
}
public static class BannerAndDownloadFreeVersion {
@ -681,26 +530,24 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
private final DownloadActivity ctx;
private boolean showSpace;
private FreeVersionDialog freeVersionDialog;
private FreeVersionBanner freeVersionBanner;
public BannerAndDownloadFreeVersion(View view, final DownloadActivity ctx, boolean showSpace) {
this.ctx = ctx;
this.showSpace = showSpace;
freeVersionDialog = new FreeVersionDialog(view, ctx, false);
freeVersionBanner = new FreeVersionBanner(view, ctx);
downloadProgressLayout = view.findViewById(R.id.downloadProgressLayout);
progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
leftTextView = (TextView) view.findViewById(R.id.leftTextView);
rightTextView = (TextView) view.findViewById(R.id.rightTextView);
freeVersionDialog.initFreeVersionBanner();
freeVersionBanner.initFreeVersionBanner();
updateBannerInProgress();
}
public void setUpdatingPrices(boolean updatingPrices) {
freeVersionDialog.setUpdatingPrices(updatingPrices);
public void updateFreeVersionBanner() {
freeVersionBanner.updateFreeVersionBanner();
}
public void updateBannerInProgress() {
@ -715,13 +562,13 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
} else {
downloadProgressLayout.setVisibility(View.VISIBLE);
}
freeVersionDialog.updateFreeVersionBanner();
freeVersionBanner.updateFreeVersionBanner();
} else {
boolean indeterminate = basicProgressAsyncTask.isIndeterminate();
String message = basicProgressAsyncTask.getDescription();
int percent = basicProgressAsyncTask.getProgressPercentage();
freeVersionDialog.setMinimizedFreeVersionBanner(true);
freeVersionDialog.updateAvailableDownloads();
freeVersionBanner.setMinimizedFreeVersionBanner(true);
freeVersionBanner.updateAvailableDownloads();
downloadProgressLayout.setVisibility(View.VISIBLE);
downloadProgressLayout.setOnClickListener(new OnClickListener() {
@Override
@ -735,27 +582,14 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
rightTextView.setText(null);
} else {
progressBar.setProgress(percent);
// final String format = ctx.getString(R.string.downloading_number_of_files);
leftTextView.setText(message);
rightTextView.setText(percent + "%");
}
}
}
public void hideDownloadProgressLayout() {
downloadProgressLayout.setVisibility(View.GONE);
}
public void showDownloadProgressLayout() {
downloadProgressLayout.setVisibility(View.VISIBLE);
}
}
@SuppressLint("StaticFieldLeak")
public void reloadLocalIndexes() {
AsyncTask<Void, String, List<String>> task = new AsyncTask<Void, String, List<String>>() {
@Override

View file

@ -1,5 +1,6 @@
package net.osmand.plus.download.ui;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.DialogInterface;
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.DownloadValidationManager;
import net.osmand.plus.download.IndexItem;
import net.osmand.plus.inapp.InAppHelper;
import net.osmand.plus.inapp.InAppHelper.InAppListener;
import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseListener;
import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseTaskType;
import net.osmand.util.Algorithms;
import org.json.JSONException;
@ -55,7 +57,7 @@ import java.util.List;
import java.util.Map;
public class DownloadResourceGroupFragment extends DialogFragment implements DownloadEvents,
InAppListener, OnChildClickListener {
InAppPurchaseListener, OnChildClickListener {
public static final int RELOAD_ID = 0;
public static final int SEARCH_ID = 1;
public static final String TAG = "RegionDialogFragment";
@ -67,6 +69,7 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
protected DownloadResourceGroupAdapter listAdapter;
private DownloadResourceGroup group;
private DownloadActivity activity;
private InAppPurchaseHelper purchaseHelper;
private Toolbar toolbar;
private View searchView;
private View restorePurchasesView;
@ -75,6 +78,7 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
purchaseHelper = getDownloadActivity().getPurchaseHelper();
boolean isLightTheme = getMyApplication().getSettings().OSMAND_THEME.get() == OsmandSettings.OSMAND_LIGHT_THEME;
int themeId = isLightTheme ? R.style.OsmandLightTheme : R.style.OsmandDarkTheme;
setStyle(STYLE_NO_FRAME, themeId);
@ -152,7 +156,7 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
}
private void addRestorePurchasesRow() {
if (!openAsDialog() && !InAppHelper.isInAppIntentoryRead()) {
if (!openAsDialog() && purchaseHelper != null && !purchaseHelper.hasInventory()) {
restorePurchasesView = activity.getLayoutInflater().inflate(R.layout.restore_purchases_list_footer, null);
((ImageView) restorePurchasesView.findViewById(R.id.icon)).setImageDrawable(
getMyApplication().getIconsCache().getThemedIcon(R.drawable.ic_action_reset_to_default_dark));
@ -160,7 +164,7 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
@Override
public void onClick(View v) {
restorePurchasesView.findViewById(R.id.progressBar).setVisibility(View.VISIBLE);
activity.startInAppHelper();
purchaseHelper.requestInventory();
}
});
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
&& !InAppHelper.isInAppIntentoryRead()) {
&& purchaseHelper != null && !purchaseHelper.hasInventory()) {
if (worldBaseMapItem != null && worldBaseMapItem.isDownloaded()) {
restorePurchasesView.findViewById(R.id.container).setVisibility(View.VISIBLE);
}
@ -260,6 +264,7 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
alertDialog.show();
}
@SuppressLint("StaticFieldLeak")
private void doSubscribe(final String email) {
new AsyncTask<Void, Void, String>() {
@ -329,7 +334,7 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
}
@Override
public void onError(String error) {
public void onError(InAppPurchaseTaskType taskType, String error) {
}
@Override
@ -346,11 +351,11 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
}
@Override
public void showProgress() {
public void showProgress(InAppPurchaseTaskType taskType) {
}
@Override
public void dismissProgress() {
public void dismissProgress(InAppPurchaseTaskType taskType) {
if (restorePurchasesView != null && restorePurchasesView.findViewById(R.id.container).getVisibility() == View.VISIBLE) {
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.Version;
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.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarController;
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()) {
String inAppSku = url.substring(INAPP_PREFIX.length());
if (InAppHelper.isPurchased(app, inAppSku)) {
InAppPurchaseHelper purchaseHelper = app.getInAppPurchaseHelper();
if (purchaseHelper != null && purchaseHelper.isPurchased(inAppSku)) {
return;
}
}
@ -210,15 +211,11 @@ public class DiscountHelper {
private static void openUrl(final MapActivity mapActivity, String url) {
if (url.startsWith(INAPP_PREFIX)) {
if (url.contains(InAppHelper.SKU_FULL_VERSION_PRICE)) {
mapActivity.execInAppTask(new InAppHelper.InAppRunnable() {
@Override
public void run(InAppHelper helper) {
mapActivity.getMyApplication().logEvent(mapActivity, "in_app_purchase_redirect");
helper.purchaseFullVersion(mapActivity);
}
});
} else if (url.contains(InAppHelper.SKU_LIVE_UPDATES)){
if (url.contains(InAppPurchaseHelper.SKU_FULL_VERSION_PRICE)) {
OsmandApplication app = mapActivity.getMyApplication();
app.logEvent(mapActivity, "in_app_purchase_redirect");
app.getInAppPurchaseHelper().purchaseFullVersion(mapActivity);
} else if (url.contains(InAppPurchaseHelper.SKU_LIVE_UPDATES)){
Intent intent = new Intent(mapActivity, OsmLiveActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
intent.putExtra(OsmLiveActivity.OPEN_SUBSCRIPTION_INTENT_PARAM, true);

View file

@ -1,5 +1,6 @@
package net.osmand.plus.inapp;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
@ -26,29 +27,29 @@ import net.osmand.util.Algorithms;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class InAppHelper {
public class InAppPurchaseHelper {
// Debug tag, for logging
static final String TAG = "InAppHelper";
private static final String TAG = InAppPurchaseHelper.class.getSimpleName();
boolean mDebugLog = false;
private static boolean mSubscribedToLiveUpdates = false;
private static boolean mFullVersionPurchased = false;
private static boolean mDepthContoursPurchased = false;
private static String mLiveUpdatesPrice;
private static long lastValidationCheckTime;
private static String mFullVersionPrice;
private static String mDepthContoursPrice;
private long lastValidationCheckTime;
private String liveUpdatesPrice;
private String fullVersionPrice;
private String depthContoursPrice;
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_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_FREE = "net.osmand.seadepth";
public static String SKU_LIVE_UPDATES;
public static String SKU_DEPTH_CONTOURS;
@ -58,27 +59,25 @@ public class InAppHelper {
// The helper object
private IabHelper mHelper;
private boolean stopAfterResult = false;
private boolean isDeveloperVersion = false;
private boolean forceRequestInventory = false;
private boolean isDeveloperVersion;
private String token = "";
private boolean inventoryRequesting = false;
private boolean stopRequested = false;
private InAppPurchaseTaskType activeTask;
private boolean processingTask = false;
private OsmandApplication ctx;
private List<InAppListener> listeners = new ArrayList<>();
private List<InAppPurchaseListener> listeners = new ArrayList<>();
/* base64EncodedPublicKey should be YOUR APPLICATION'S PUBLIC KEY
* (that you got from the Google Play developer console). This is not your
* developer public key, it's the *app-specific* public key.
*
* Instead of just storing the entire literal string here embedded in the
* program, construct the key at runtime from pieces or
* use bit manipulation (for example, XOR with some other string) to hide
* the actual key. The key itself is not secret information, but we don't
* want to make it easy for an attacker to replace the public key with one
* of their own and then fake messages from the server.
*/
* (that you got from the Google Play developer console). This is not your
* developer public key, it's the *app-specific* public key.
*
* Instead of just storing the entire literal string here embedded in the
* program, construct the key at runtime from pieces or
* use bit manipulation (for example, XOR with some other string) to hide
* the actual key. The key itself is not secret information, but we don't
* want to make it easy for an attacker to replace the public key with one
* of their own and then fake messages from the server.
*/
private static final String BASE64_ENCODED_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgk8cEx" +
"UO4mfEwWFLkQnX1Tkzehr4SnXLXcm2Osxs5FTJPEgyTckTh0POKVMrxeGLn0KoTY2NTgp1U/inp" +
"wccWisPhVPEmw9bAVvWsOkzlyg1kv03fJdnAXRBSqDDPV6X8Z3MtkPVqZkupBsxyIllEILKHK06" +
@ -86,60 +85,64 @@ public class InAppHelper {
"I+ftJO46a1XkNh1dO2anUiQ8P/H4yOTqnMsXF7biyYuiwjXPOcy0OMhEHi54Dq6Mr3u5ZALOAkc" +
"YTjh1H/ZgqIHy5ZluahINuDE76qdLYMXrDMQIDAQAB";
public interface InAppListener {
void onError(String error);
public interface InAppPurchaseListener {
void onError(InAppPurchaseTaskType taskType, String error);
void onGetItems();
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 {
void run(InAppHelper helper);
// return true if done and false if async task started
boolean run(InAppPurchaseHelper helper);
}
public String getToken() {
return token;
}
public static boolean isSubscribedToLiveUpdates() {
return mSubscribedToLiveUpdates;
public InAppPurchaseTaskType getActiveTask() {
return activeTask;
}
public static boolean isFullVersionPurchased() {
return mFullVersionPurchased;
public boolean isSubscribedToLiveUpdates() {
return ctx.getSettings().LIVE_UPDATES_PURCHASED.get();
}
public static boolean isDepthContoursPurchased() {
return mDepthContoursPurchased;
public String getLiveUpdatesPrice() {
return liveUpdatesPrice;
}
public static String getLiveUpdatesPrice() {
return mLiveUpdatesPrice;
public String getFullVersionPrice() {
return fullVersionPrice;
}
public static String getDepthContoursPrice() {
return mDepthContoursPrice;
public String getDepthContoursPrice() {
return depthContoursPrice;
}
public static String getFullVersionPrice() {
return mFullVersionPrice;
}
public static String getSkuLiveUpdates() {
public String getSkuLiveUpdates() {
return SKU_LIVE_UPDATES;
}
public static boolean hasPrices(OsmandApplication app) {
return !Algorithms.isEmpty(mLiveUpdatesPrice)
&& (!Version.isFreeVersion(app) || !Algorithms.isEmpty(mFullVersionPrice));
public boolean hasPrices() {
return !Algorithms.isEmpty(liveUpdatesPrice)
&& (!Version.isFreeVersion(ctx) || !Algorithms.isEmpty(fullVersionPrice));
}
public static void initialize(OsmandApplication ctx) {
private void initialize() {
if (SKU_LIVE_UPDATES == null) {
if (Version.isFreeVersion(ctx)) {
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.forceRequestInventory = forceRequestInventory;
isDeveloperVersion = Version.isDeveloperVersion(ctx);
if (isDeveloperVersion) {
mSubscribedToLiveUpdates = true;
mFullVersionPurchased = true;
mDepthContoursPurchased = true;
this.isDeveloperVersion = Version.isDeveloperVersion(ctx);
if (this.isDeveloperVersion) {
ctx.getSettings().LIVE_UPDATES_PURCHASED.set(true);
ctx.getSettings().FULL_VERSION_PURCHASED.set(true);
ctx.getSettings().DEPTH_CONTOURS_PURCHASED.set(true);
}
initialize();
}
public static boolean isInAppIntentoryRead() {
public boolean hasInventory() {
return lastValidationCheckTime != 0;
}
public static boolean isPurchased(OsmandApplication ctx, String inAppSku) {
public boolean isPurchased(String inAppSku) {
OsmandSettings settings = ctx.getSettings();
if (inAppSku.equals(SKU_FULL_VERSION_PRICE)) {
return settings.FULL_VERSION_PURCHASED.get();
@ -187,11 +186,18 @@ public class InAppHelper {
return false;
}
public void exec(final @NonNull InAppRunnable runnable) {
this.stopAfterResult = true;
private void exec(final @NonNull InAppPurchaseTaskType taskType, final @NonNull InAppRunnable runnable) {
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
logDebug("Creating InAppHelper.");
logDebug("Creating InAppPurchaseHelper.");
mHelper = new IabHelper(ctx, BASE64_ENCODED_PUBLIC_KEY);
// 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.
logDebug("Starting setup.");
try {
processingTask = true;
activeTask = taskType;
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
logDebug("Setup finished.");
@ -208,166 +216,165 @@ public class InAppHelper {
if (!result.isSuccess()) {
// Oh noes, there was a problem.
//complain("Problem setting up in-app billing: " + result);
notifyError(result.getMessage());
if (stopAfterResult) {
stop();
}
notifyError(taskType, result.getMessage());
stop(true);
return;
}
// 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) {
logError("exec Error", e);
if (stopAfterResult) {
stop();
}
stop(true);
}
}
public void start(final boolean stopAfterResult) {
this.stopAfterResult = stopAfterResult;
public boolean needRequestInventory() {
return !ctx.getSettings().BILLING_PURCHASE_TOKEN_SENT.get()
|| System.currentTimeMillis() - lastValidationCheckTime > PURCHASE_VALIDATION_PERIOD_MSEC;
}
// Create the helper, passing it our context and the public key to verify signatures with
logDebug("Creating InAppHelper.");
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.");
List<String> skus = new ArrayList<>();
skus.add(SKU_LIVE_UPDATES);
skus.add(SKU_DEPTH_CONTOURS);
skus.add(SKU_FULL_VERSION_PRICE);
try {
inventoryRequesting = true;
mHelper.queryInventoryAsync(true, skus, mGotInventoryListener);
} catch (Exception e) {
inventoryRequesting = false;
logError("queryInventoryAsync Error", e);
notifyDismissProgress();
if (stopAfterResult) {
stop();
}
}
} else {
notifyDismissProgress();
if (stopAfterResult) {
stop();
}
}
public void requestInventory() {
notifyShowProgress(InAppPurchaseTaskType.REQUEST_INVENTORY);
exec(InAppPurchaseTaskType.REQUEST_INVENTORY, new InAppRunnable() {
@Override
public boolean run(InAppPurchaseHelper helper) {
logDebug("Setup successful. Querying inventory.");
List<String> skus = new ArrayList<>();
skus.add(SKU_LIVE_UPDATES);
skus.add(SKU_DEPTH_CONTOURS);
skus.add(SKU_FULL_VERSION_PRICE);
try {
mHelper.queryInventoryAsync(true, skus, mGotInventoryListener);
return false;
} catch (Exception e) {
logError("queryInventoryAsync Error", e);
notifyDismissProgress(InAppPurchaseTaskType.REQUEST_INVENTORY);
stop(true);
}
});
} catch (Exception e) {
logError("start Error", e);
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) {
complain("Cannot launch full version purchase!");
logError("purchaseFullVersion Error", e);
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
private QueryInventoryFinishedListener mGotInventoryListener = new QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
logDebug("Query inventory finished.");
inventoryRequesting = false;
// 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?
if (result.isFailure() || stopRequested) {
if (result.isFailure()) {
logError("Failed to query inventory: " + result);
notifyError(result.getMessage());
if (stopAfterResult || stopRequested) {
stop();
}
notifyError(InAppPurchaseTaskType.REQUEST_INVENTORY, result.getMessage());
stop(true);
return;
}
logDebug("Query inventory was successful.");
/*
/*
* Check for items we own. Notice that for each purchase, we check
* the developer payload to see if it's correct! See
* verifyDeveloperPayload().
*/
* the developer payload to see if it's correct! See
* verifyDeveloperPayload().
*/
// Do we have the live updates?
Purchase liveUpdatesPurchase = inventory.getPurchase(SKU_LIVE_UPDATES);
mSubscribedToLiveUpdates = isDeveloperVersion || (liveUpdatesPurchase != null && liveUpdatesPurchase.getPurchaseState() == 0);
if (mSubscribedToLiveUpdates) {
ctx.getSettings().LIVE_UPDATES_PURCHASED.set(true);
}
boolean subscribedToLiveUpdates = (liveUpdatesPurchase != null && liveUpdatesPurchase.getPurchaseState() == 0);
//subscribedToLiveUpdates = false;
ctx.getSettings().LIVE_UPDATES_PURCHASED.set(subscribedToLiveUpdates);
Purchase fullVersionPurchase = inventory.getPurchase(SKU_FULL_VERSION_PRICE);
mFullVersionPurchased = isDeveloperVersion || (fullVersionPurchase != null && fullVersionPurchase.getPurchaseState() == 0);
if (mFullVersionPurchased) {
boolean fullVersionPurchased = (fullVersionPurchase != null && fullVersionPurchase.getPurchaseState() == 0);
if (fullVersionPurchased) {
ctx.getSettings().FULL_VERSION_PURCHASED.set(true);
}
Purchase depthContoursPurchase = inventory.getPurchase(SKU_DEPTH_CONTOURS);
mDepthContoursPurchased = isDeveloperVersion || (depthContoursPurchase != null && depthContoursPurchase.getPurchaseState() == 0);
if (mDepthContoursPurchased) {
boolean depthContoursPurchased = (depthContoursPurchase != null && depthContoursPurchase.getPurchaseState() == 0);
if (depthContoursPurchased) {
ctx.getSettings().DEPTH_CONTOURS_PURCHASED.set(true);
}
lastValidationCheckTime = System.currentTimeMillis();
logDebug("User " + (mSubscribedToLiveUpdates ? "HAS" : "DOES NOT HAVE")
logDebug("User " + (subscribedToLiveUpdates ? "HAS" : "DOES NOT HAVE")
+ " live updates purchased.");
if (inventory.hasDetails(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)) {
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();
settings.INAPPS_READ.set(true);
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()))
&& !Algorithms.isEmpty(liveUpdatesPurchase.getDeveloperPayload())) {
String payload = liveUpdatesPurchase.getDeveloperPayload();
@ -390,11 +397,9 @@ public class InAppHelper {
final OnRequestResultListener listener = new OnRequestResultListener() {
@Override
public void onResult(String result) {
notifyDismissProgress();
notifyDismissProgress(InAppPurchaseTaskType.REQUEST_INVENTORY);
notifyGetItems();
if (stopAfterResult || stopRequested) {
stop();
}
stop(true);
logDebug("Initial inapp query finished");
}
};
@ -407,159 +412,107 @@ public class InAppHelper {
}
};
public void purchaseFullVersion(final Activity activity) {
if (mHelper == null) {
//complain("In-app hepler is not initialized!");
notifyError("In-app hepler is not initialized!");
if (stopAfterResult) {
stop();
}
return;
@SuppressLint("StaticFieldLeak")
private class LiveUpdatesPurchaseTask extends AsyncTask<Void, Void, String> {
private WeakReference<Activity> activity;
private String email;
private String userName;
private String countryDownloadName;
private boolean hideUserName;
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;
}
logDebug("Launching purchase flow for full version");
if (mHelper != null) {
@Override
protected String doInBackground(Void... params) {
userId = ctx.getSettings().BILLING_USER_ID.get();
try {
mHelper.launchPurchaseFlow(activity,
SKU_FULL_VERSION_PRICE, RC_REQUEST, mPurchaseFinishedListener);
Map<String, String> parameters = new HashMap<>();
parameters.put("visibleName", hideUserName ? "" : userName);
parameters.put("preferredCountry", countryDownloadName);
parameters.put("email", email);
if (Algorithms.isEmpty(userId)) {
parameters.put("status", "new");
}
return AndroidNetworkUtils.sendRequest(ctx,
"http://download.osmand.net/subscription/register.php",
parameters, "Requesting userId...", true, true);
} catch (Exception e) {
complain("Cannot launch full version purchase!");
logError("purchaseFullVersion Error", e);
if (stopAfterResult) {
stop();
}
logError("sendRequest Error", e);
return null;
}
}
}
public void purchaseDepthContours(final Activity activity) {
if (mHelper == null) {
//complain("In-app hepler is not initialized!");
notifyError("In-app hepler is not initialized!");
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();
}
@Override
protected void onPostExecute(String response) {
logDebug("Response=" + response);
if (response == null) {
complain("Cannot retrieve userId from server.");
notifyDismissProgress(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES);
notifyError(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES, "Cannot retrieve userId from server.");
stop(true);
return;
}
} catch (Exception e) {
logError("purchaseLiveUpdates Error", e);
if (stopAfterResult) {
stop();
}
return;
}
notifyShowProgress();
new AsyncTask<Void, Void, String>() {
private String userId;
@Override
protected String doInBackground(Void... params) {
userId = ctx.getSettings().BILLING_USER_ID.get();
} else {
try {
Map<String, String> parameters = new HashMap<>();
parameters.put("visibleName", hideUserName ? "" : userName);
parameters.put("preferredCountry", countryDownloadName);
parameters.put("email", email);
if (Algorithms.isEmpty(userId)) {
parameters.put("status", "new");
}
return AndroidNetworkUtils.sendRequest(ctx,
"http://download.osmand.net/subscription/register.php",
parameters, "Requesting userId...", true, true);
} catch (Exception e) {
logError("sendRequest Error", e);
return null;
JSONObject obj = new JSONObject(response);
userId = obj.getString("userid");
ctx.getSettings().BILLING_USER_ID.set(userId);
token = obj.getString("token");
ctx.getSettings().BILLING_USER_TOKEN.set(token);
logDebug("UserId=" + userId);
} catch (JSONException e) {
String message = "JSON parsing error: "
+ (e.getMessage() == null ? "unknown" : e.getMessage());
complain(message);
notifyDismissProgress(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES);
notifyError(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES, message);
stop(true);
}
}
@Override
protected void onPostExecute(String response) {
logDebug("Response=" + response);
if (response == null) {
complain("Cannot retrieve userId from server.");
notifyDismissProgress();
notifyError("Cannot retrieve userId from server.");
if (stopAfterResult) {
stop();
}
return;
} else {
try {
JSONObject obj = new JSONObject(response);
userId = obj.getString("userid");
ctx.getSettings().BILLING_USER_ID.set(userId);
token = obj.getString("token");
ctx.getSettings().BILLING_USER_TOKEN.set(token);
logDebug("UserId=" + userId);
} catch (JSONException e) {
String message = "JSON parsing error: "
+ (e.getMessage() == null ? "unknown" : e.getMessage());
complain(message);
notifyDismissProgress();
notifyError(message);
if (stopAfterResult) {
stop();
}
}
}
notifyDismissProgress();
if (!Algorithms.isEmpty(userId)) {
logDebug("Launching purchase flow for live updates subscription for userId=" + userId);
String payload = userId + " " + token;
if (mHelper != null) {
notifyDismissProgress(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES);
if (!Algorithms.isEmpty(userId)) {
logDebug("Launching purchase flow for live updates subscription for userId=" + userId);
final String payload = userId + " " + token;
exec(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES, new InAppRunnable() {
@Override
public boolean run(InAppPurchaseHelper helper) {
try {
mHelper.launchPurchaseFlow(activity,
SKU_LIVE_UPDATES, IabHelper.ITEM_TYPE_SUBS,
RC_REQUEST, mPurchaseFinishedListener, payload);
Activity a = activity.get();
if (a != null) {
mHelper.launchPurchaseFlow(a,
SKU_LIVE_UPDATES, IabHelper.ITEM_TYPE_SUBS,
RC_REQUEST, mPurchaseFinishedListener, payload);
return false;
} else {
stop(true);
}
} catch (Exception e) {
logError("launchPurchaseFlow Error", e);
if (stopAfterResult) {
stop();
}
stop(true);
}
return true;
}
} else {
notifyError("Empty userId");
if (stopAfterResult) {
stop();
}
}
});
} else {
notifyError(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES,"Empty userId");
stop(true);
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
}
}
public boolean onActivityResultHandled(int requestCode, int resultCode, Intent data) {
@ -590,15 +543,16 @@ public class InAppHelper {
logDebug("Purchase finished: " + result + ", purchase: " + purchase);
// if we were disposed of in the meantime, quit.
if (mHelper == null) return;
if (mHelper == null) {
stop(true);
return;
}
if (result.isFailure()) {
complain("Error purchasing: " + result);
notifyDismissProgress();
notifyError("Error purchasing: " + result);
if (stopAfterResult) {
stop();
}
notifyDismissProgress(activeTask);
notifyError(activeTask, "Error purchasing: " + result);
stop(true);
return;
}
@ -611,58 +565,61 @@ public class InAppHelper {
@Override
public void onResult(String result) {
showToast(ctx.getString(R.string.osm_live_thanks));
mSubscribedToLiveUpdates = true;
ctx.getSettings().LIVE_UPDATES_PURCHASED.set(true);
notifyDismissProgress();
notifyDismissProgress(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES);
notifyItemPurchased(SKU_LIVE_UPDATES);
if (stopAfterResult) {
stop();
}
stop(true);
}
});
}
if (purchase.getSku().equals(SKU_FULL_VERSION_PRICE)) {
} else if (purchase.getSku().equals(SKU_FULL_VERSION_PRICE)) {
// bought full version
logDebug("Full version purchased.");
showToast(ctx.getString(R.string.full_version_thanks));
mFullVersionPurchased = true;
ctx.getSettings().FULL_VERSION_PURCHASED.set(true);
notifyDismissProgress();
notifyDismissProgress(InAppPurchaseTaskType.PURCHASE_FULL_VERSION);
notifyItemPurchased(SKU_FULL_VERSION_PRICE);
if (stopAfterResult) {
stop();
}
}
if (purchase.getSku().equals(SKU_DEPTH_CONTOURS)) {
stop(true);
} else if (purchase.getSku().equals(SKU_DEPTH_CONTOURS)) {
// bought sea depth contours
logDebug("Sea depth contours purchased.");
showToast(ctx.getString(R.string.sea_depth_thanks));
mDepthContoursPurchased = true;
ctx.getSettings().DEPTH_CONTOURS_PURCHASED.set(true);
ctx.getSettings().getCustomRenderBooleanProperty("depthContours").set(true);
notifyDismissProgress();
notifyDismissProgress(InAppPurchaseTaskType.PURCHASE_DEPTH_CONTOURS);
notifyItemPurchased(SKU_DEPTH_CONTOURS);
if (stopAfterResult) {
stop();
}
stop(true);
} else {
notifyDismissProgress(activeTask);
stop(true);
}
}
};
// Do not forget call stop() when helper is not needed anymore
public void stop() {
stop(false);
}
private void stop(boolean taskDone) {
logDebug("Destroying helper.");
if (mHelper != null) {
if (!inventoryRequesting) {
stopRequested = false;
if (taskDone) {
processingTask = false;
}
if (!processingTask) {
activeTask = null;
mHelper.dispose();
mHelper = null;
} else {
stopRequested = true;
}
} else {
processingTask = false;
activeTask = null;
}
}
@ -739,46 +696,46 @@ public class InAppHelper {
}
}
private void notifyError(String message) {
for (InAppListener l : listeners) {
l.onError(message);
private void notifyError(InAppPurchaseTaskType taskType, String message) {
for (InAppPurchaseListener l : listeners) {
l.onError(taskType, message);
}
}
private void notifyGetItems() {
for (InAppListener l : listeners) {
for (InAppPurchaseListener l : listeners) {
l.onGetItems();
}
}
private void notifyItemPurchased(String sku) {
for (InAppListener l : listeners) {
for (InAppPurchaseListener l : listeners) {
l.onItemPurchased(sku);
}
}
private void notifyShowProgress() {
for (InAppListener l : listeners) {
l.showProgress();
private void notifyShowProgress(InAppPurchaseTaskType taskType) {
for (InAppPurchaseListener l : listeners) {
l.showProgress(taskType);
}
}
private void notifyDismissProgress() {
for (InAppListener l : listeners) {
l.dismissProgress();
private void notifyDismissProgress(InAppPurchaseTaskType taskType) {
for (InAppPurchaseListener l : listeners) {
l.dismissProgress(taskType);
}
}
public void addListener(InAppListener listener) {
public void addListener(InAppPurchaseListener listener) {
this.listeners.add(listener);
}
public void removeListener(InAppListener listener) {
public void removeListener(InAppPurchaseListener listener) {
this.listeners.remove(listener);
}
private void complain(String message) {
logError("**** InAppHelper Error: " + message);
logError("**** InAppPurchaseHelper Error: " + message);
showToast(message);
}
@ -787,7 +744,9 @@ public class InAppHelper {
}
private void logDebug(String msg) {
if (mDebugLog) Log.d(TAG, msg);
if (mDebugLog) {
Log.d(TAG, msg);
}
}
private void logError(String msg) {

View file

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

View file

@ -15,10 +15,8 @@ import android.view.MenuItem;
import net.osmand.AndroidNetworkUtils;
import net.osmand.PlatformUtil;
import net.osmand.plus.R;
import net.osmand.plus.Version;
import net.osmand.plus.download.AbstractDownloadActivity;
import net.osmand.plus.download.DownloadIndexesThread;
import net.osmand.plus.inapp.InAppHelper;
import net.osmand.plus.download.DownloadIndexesThread.DownloadEvents;
import org.apache.commons.logging.Log;
@ -28,32 +26,21 @@ import java.util.Date;
import java.util.Locale;
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);
public final static String OPEN_SUBSCRIPTION_INTENT_PARAM = "open_subscription_intent_param";
private LiveUpdatesFragmentPagerAdapter pagerAdapter;
private InAppHelper inAppHelper;
private boolean openSubscription;
private GetLastUpdateDateTask getLastUpdateDateTask;
private static final String URL = "https://osmand.net/api/osmlive_status";
public InAppHelper getInAppHelper() {
return inAppHelper;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
getMyApplication().applyTheme(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_livie_updates);
if (Version.isGooglePlayEnabled(getMyApplication())) {
inAppHelper = new InAppHelper(getMyApplication(), false);
}
if (Version.isDeveloperVersion(getMyApplication())) {
inAppHelper = null;
}
Intent intent = getIntent();
if (intent != null && intent.getExtras() != null) {
openSubscription = intent.getExtras().getBoolean(OPEN_SUBSCRIPTION_INTENT_PARAM, false);
@ -82,17 +69,6 @@ public class OsmLiveActivity extends AbstractDownloadActivity implements Downloa
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
protected void onPause() {
super.onPause();
@ -102,17 +78,17 @@ public class OsmLiveActivity extends AbstractDownloadActivity implements Downloa
@Override
protected void onDestroy() {
super.onDestroy();
if (inAppHelper != null) {
inAppHelper.stop();
}
if (getLastUpdateDateTask != null) {
getLastUpdateDateTask.cancel(true);
}
}
public boolean isInAppPurchaseAllowed() {
return true;
}
@Override
public void newDownloadIndexes() {
}
@Override

View file

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