Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
39e7ba876e
40 changed files with 1866 additions and 1180 deletions
|
@ -50,8 +50,8 @@ body {
|
|||
h1 {
|
||||
font-size: 2em;
|
||||
color: #212121;
|
||||
font-family: serif;
|
||||
letter-spacing: 0.03em;
|
||||
font-family: RobotoSlab-Regular;
|
||||
letter-spacing: 0.02em;
|
||||
word-wrap: break-word;
|
||||
padding-top: 5%;
|
||||
font-weight: normal;
|
||||
|
@ -59,14 +59,14 @@ h1 {
|
|||
|
||||
h2 {
|
||||
font-size: 1.5em;
|
||||
color: #575757;
|
||||
color: #454545;
|
||||
font-family: RobotoSlab-Regular;
|
||||
font-weight:100;
|
||||
word-wrap: break-word;
|
||||
margin-top: 3%;
|
||||
padding-bottom: 3%;
|
||||
/* font-weight: bold; */
|
||||
padding-top: 2%;
|
||||
padding-bottom: 4%;
|
||||
line-height: 1.6em;
|
||||
letter-spacing: 0.01em;
|
||||
letter-spacing: 0.015em;
|
||||
border-bottom: 1px solid #eaecf0;
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ h3 {
|
|||
font-family: sans-serif;
|
||||
word-wrap: break-word;
|
||||
font-weight: bold;
|
||||
margin-top: 3%;
|
||||
margin-top: 5%;
|
||||
margin-bottom: 3%;
|
||||
line-height: 1.6em;
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ h3 {
|
|||
p {
|
||||
font-family: sans-serif;
|
||||
font-size: 1.1em;
|
||||
line-height: 1.5em;
|
||||
line-height: 1.6em;
|
||||
}
|
||||
|
||||
ul {
|
||||
|
@ -162,8 +162,8 @@ pre {
|
|||
.geo {
|
||||
background-color: #fafafa;
|
||||
border: 1px solid #e6e6e6;
|
||||
border-radius: 5px;
|
||||
padding: 3% 3% 3% 3%;
|
||||
border-radius: 4px;
|
||||
padding: 10px 10px 10px 10px;
|
||||
color: #237bff;
|
||||
font-size: 0.9em;
|
||||
font-weight: bold;
|
||||
|
@ -174,7 +174,7 @@ pre {
|
|||
|
||||
@font-face {
|
||||
font-family: RobotoSlab-Regular;
|
||||
src: url("file:///assets/fonts/RobotoSlab-Regular.ttf")
|
||||
src: url("fonts/RobotoSlab-Regular.ttf")
|
||||
}
|
||||
|
||||
td {
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 7.7 KiB |
BIN
OsmAnd/res/drawable-xxhdpi/img_logo_38dp_sea_depth.png
Normal file
BIN
OsmAnd/res/drawable-xxhdpi/img_logo_38dp_sea_depth.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.9 KiB |
|
@ -6,9 +6,11 @@
|
|||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/shared_string_explore"/>
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:paddingBottom="@dimen/map_markers_recycler_view_padding_bottom"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -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"
|
||||
|
@ -17,11 +16,6 @@
|
|||
android:paddingBottom="@dimen/list_header_padding"
|
||||
android:paddingTop="@dimen/list_header_padding">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/bannerTopLayout"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -80,158 +74,6 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/priceInfoLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/list_content_padding"
|
||||
android:orientation="vertical">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="@color/dashboard_divider_dark"
|
||||
android:visibility="visible"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/fullVersionLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/list_content_padding"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="visible">
|
||||
|
||||
<android.support.v7.widget.AppCompatImageView
|
||||
android:layout_width="54dp"
|
||||
android:layout_height="32dp"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/ic_action_osmand_logo"
|
||||
android:tint="@color/osmand_orange"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="@dimen/list_content_padding"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fullVersionTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/osmand_unlimited"
|
||||
android:textSize="@dimen/default_list_text_size_large"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fullVersionDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6dp"
|
||||
android:text="@string/osmand_plus_banner_desc"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/fullVersionProgress"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:indeterminate="true"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<android.support.v7.widget.AppCompatButton
|
||||
android:id="@+id/fullVersionButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:background="@drawable/blue_button_drawable"
|
||||
android:paddingBottom="4dp"
|
||||
android:paddingLeft="14dp"
|
||||
android:paddingRight="14dp"
|
||||
android:paddingTop="4dp"
|
||||
android:textColor="@color/color_white"
|
||||
android:visibility="visible"
|
||||
tools:text="GET FOR 5 EUR"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/osmLiveLayoutTopDivider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginLeft="54dp"
|
||||
android:layout_marginTop="@dimen/list_content_padding"
|
||||
android:background="@color/dashboard_divider_dark"
|
||||
android:visibility="visible"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/osmLiveLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/list_content_padding"
|
||||
android:layout_marginBottom="@dimen/list_content_padding"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<android.support.v7.widget.AppCompatImageView
|
||||
android:layout_width="54dp"
|
||||
android:layout_height="32dp"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/ic_action_osm_live"
|
||||
android:tint="@color/osmand_orange"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="@dimen/list_content_padding"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/osmLiveTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/osm_live_subscription"
|
||||
android:textSize="@dimen/default_list_text_size_large"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/osmLiveDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6dp"
|
||||
android:text="@string/osm_live_banner_desc"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/osmLiveProgress"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:indeterminate="true"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<android.support.v7.widget.AppCompatButton
|
||||
android:id="@+id/osmLiveButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:background="@drawable/blue_button_drawable"
|
||||
android:paddingBottom="4dp"
|
||||
android:paddingLeft="14dp"
|
||||
android:paddingRight="14dp"
|
||||
android:paddingTop="4dp"
|
||||
android:textColor="@color/color_white"
|
||||
tools:text="GET FOR 1,5 EUR PER MONTH"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding"
|
||||
android:layout_marginTop="2dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?attr/wikivoyage_primary_text_color"
|
||||
android:textSize="@dimen/travel_card_title_text_size"
|
||||
android:textSize="@dimen/travel_card_primary_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:text="Download file"/>
|
||||
|
||||
|
@ -48,7 +48,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/wikivoyage_secondary_text"
|
||||
android:textSize="@dimen/travel_card_title_size"
|
||||
android:textSize="@dimen/travel_card_primary_text_size"
|
||||
osmand:typeface="@string/font_roboto_regular"
|
||||
tools:text="Download this Wikivoyage travel guides file to view articles about places around the world without an internet connection."/>
|
||||
|
||||
|
@ -56,15 +56,17 @@
|
|||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/bottom_sheet_selected_item_title_height"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/content_padding"
|
||||
android:layout_marginLeft="@dimen/bottom_sheet_content_margin_small"
|
||||
android:layout_marginRight="@dimen/bottom_sheet_content_margin_small"
|
||||
android:background="@drawable/travel_card_stroke_bg"
|
||||
android:minHeight="@dimen/bottom_sheet_selected_item_title_height"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingRight="@dimen/content_padding">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/file_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
|
@ -81,7 +83,7 @@
|
|||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/file_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -89,9 +91,10 @@
|
|||
android:maxLines="1"
|
||||
android:textColor="?attr/wikivoyage_primary_text_color"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
osmand:typeface="@string/font_roboto_regular"
|
||||
tools:text="Wikivoyage"/>
|
||||
|
||||
<TextView
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/file_description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -99,8 +102,19 @@
|
|||
android:maxLines="1"
|
||||
android:textColor="@color/wikivoyage_secondary_text"
|
||||
android:textSize="@dimen/default_sub_text_size"
|
||||
osmand:typeface="@string/font_roboto_regular"
|
||||
tools:text="255 Mb • Update 11 April"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_bar"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:minHeight="0dp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -119,22 +133,25 @@
|
|||
android:background="@drawable/wikivoyage_secondary_btn_bg">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/left_button"
|
||||
android:id="@+id/secondary_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/wikivoyage_card_button_height"
|
||||
android:layout_gravity="center"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:letterSpacing="@dimen/text_button_letter_spacing"
|
||||
android:maxLines="1"
|
||||
android:textColor="?attr/wikivoyage_active_color"
|
||||
android:textSize="@dimen/text_button_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:ignore="UnusedAttribute"
|
||||
tools:text="Later"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/buttons_divider"
|
||||
android:layout_width="@dimen/bottom_sheet_content_margin_small"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
|
@ -145,17 +162,19 @@
|
|||
android:background="@drawable/wikivoyage_primary_btn_bg">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/right_button"
|
||||
android:id="@+id/primary_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/wikivoyage_card_button_height"
|
||||
android:layout_gravity="center"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:letterSpacing="@dimen/text_button_letter_spacing"
|
||||
android:maxLines="1"
|
||||
android:textColor="?attr/wikivoyage_primary_btn_text_color"
|
||||
android:textSize="@dimen/text_button_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:ignore="UnusedAttribute"
|
||||
tools:text="Update"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
|
68
OsmAnd/res/layout/wikivoyage_open_beta_card.xml
Normal file
68
OsmAnd/res/layout/wikivoyage_open_beta_card.xml
Normal file
|
@ -0,0 +1,68 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout 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:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginBottom="@dimen/list_content_padding"
|
||||
android:layout_marginTop="@dimen/list_content_padding"
|
||||
android:background="@drawable/travel_card_bg">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/background_image"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/welcome_to_open_beta"
|
||||
tools:src="@drawable/img_help_wikivoyage_articles" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/list_content_padding"
|
||||
android:layout_marginEnd="@dimen/list_content_padding"
|
||||
android:layout_marginLeft="@dimen/list_content_padding"
|
||||
android:layout_marginRight="@dimen/list_content_padding"
|
||||
android:layout_marginStart="@dimen/list_content_padding"
|
||||
android:layout_marginTop="@dimen/bottom_sheet_icon_margin"
|
||||
tools:text="@string/welcome_to_open_beta" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/list_content_padding"
|
||||
android:layout_marginEnd="@dimen/list_content_padding"
|
||||
android:layout_marginLeft="@dimen/list_content_padding"
|
||||
android:layout_marginRight="@dimen/list_content_padding"
|
||||
android:layout_marginStart="@dimen/list_content_padding"
|
||||
tools:text="@string/welcome_to_open_beta_description" />
|
||||
|
||||
<View
|
||||
android:id="@+id/bottom_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/wikivoyage_card_divider_color" />
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/bottom_button_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/bottom_sheet_title_height"
|
||||
android:layout_gravity="center"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:gravity="center"
|
||||
android:textColor="?attr/color_dialog_buttons"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:text="@string/get_unlimited_access" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
79
OsmAnd/res/layout/wikivoyage_start_editing_card.xml
Normal file
79
OsmAnd/res/layout/wikivoyage_start_editing_card.xml
Normal file
|
@ -0,0 +1,79 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout 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:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginBottom="@dimen/list_content_padding"
|
||||
android:layout_marginTop="@dimen/list_content_padding"
|
||||
android:background="@drawable/travel_card_bg">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/wikivoyage_start_editing_image_background"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/list_content_padding"
|
||||
android:layout_marginEnd="@dimen/list_content_padding"
|
||||
android:layout_marginLeft="@dimen/list_content_padding"
|
||||
android:layout_marginRight="@dimen/list_content_padding"
|
||||
android:layout_marginStart="@dimen/list_content_padding"
|
||||
android:layout_marginTop="42dp"
|
||||
android:layout_weight="1"
|
||||
android:textColor="@color/primary_text_dark"
|
||||
tools:text="@string/start_editing_card_image_text" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/background_image"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/wikivoyage_explore_card_image_height"
|
||||
android:contentDescription="@string/welcome_to_open_beta"
|
||||
android:src="@drawable/img_help_wikivoyage_contribute" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/list_content_padding"
|
||||
android:layout_marginEnd="@dimen/list_content_padding"
|
||||
android:layout_marginLeft="@dimen/list_content_padding"
|
||||
android:layout_marginRight="@dimen/list_content_padding"
|
||||
android:layout_marginStart="@dimen/list_content_padding"
|
||||
android:layout_marginTop="@dimen/list_content_padding"
|
||||
tools:text="@string/start_editing_card_description" />
|
||||
|
||||
<View
|
||||
android:id="@+id/bottom_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/wikivoyage_card_divider_color" />
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/bottom_button_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/bottom_sheet_title_height"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:textColor="?attr/color_dialog_buttons"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:text="@string/start_editing" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -101,7 +101,7 @@
|
|||
<dimen name="default_sub_text_size_small">12sp</dimen>
|
||||
<dimen name="welcome_header_text_size">27sp</dimen>
|
||||
<dimen name="text_button_text_size">22sp</dimen>
|
||||
<dimen name="travel_card_title_text_size">22sp</dimen>
|
||||
<dimen name="travel_card_primary_text_size">22sp</dimen>
|
||||
|
||||
<dimen name="dialog_header_text_size">24sp</dimen>
|
||||
|
||||
|
|
|
@ -428,5 +428,6 @@
|
|||
<color name="wikivoyage_primary_text_light">#212121</color>
|
||||
<color name="wikivoyage_primary_text_dark">#cccccc</color>
|
||||
<color name="wikivoyage_secondary_text">#727272</color>
|
||||
<color name="wikivoyage_start_editing_image_background">#339966</color>
|
||||
|
||||
</resources>
|
|
@ -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>
|
||||
|
@ -175,7 +176,7 @@
|
|||
<dimen name="default_sub_text_size_small">10sp</dimen>
|
||||
<dimen name="welcome_header_text_size">23sp</dimen>
|
||||
<dimen name="text_button_text_size">15sp</dimen>
|
||||
<dimen name="travel_card_title_text_size">15sp</dimen>
|
||||
<dimen name="travel_card_primary_text_size">15sp</dimen>
|
||||
|
||||
<dimen name="default_split_segments_overview">13sp</dimen>
|
||||
<dimen name="default_split_segments_data">13sp</dimen>
|
||||
|
@ -291,5 +292,7 @@
|
|||
<dimen name="wikivoyage_search_icon_margin_right">22dp</dimen>
|
||||
<dimen name="wikivoyage_search_divider_margin_start">64dp</dimen>
|
||||
|
||||
<dimen name="wikivoyage_explore_card_image_height">144dp</dimen>
|
||||
|
||||
<dimen name="text_button_letter_spacing" format="float">0.01</dimen>
|
||||
</resources>
|
|
@ -9,6 +9,16 @@
|
|||
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
|
||||
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
|
||||
-->
|
||||
<string name="travel_card_update_descr">We prepared updates and fixes in the Wikivoyage data, update the file to see them.</string>
|
||||
<string name="travel_card_download_descr">Download this Wikivoyage travel guides file to view articles about places around the world without an internet connection.</string>
|
||||
<string name="update_is_available">Update is available</string>
|
||||
<string name="download_file">Download file</string>
|
||||
<string name="start_editing_card_image_text">The free worldwide travel guide that anyone can edit.</string>
|
||||
<string name="welcome_to_open_beta_description">Travel is based on Wikivoyage. During open beta testing you have the opportunity to evaluate all the features for free. After the end of the beta period, Travel will be available to subscribers of OsmAnd Unlimited and the owners of OsmAnd+</string>
|
||||
<string name="start_editing_card_description">You can edit any article on Wikivoyage, and we hope that you do. We need your knowledge, your experience, your talent, and your attention</string>
|
||||
<string name="start_editing">Start editing</string>
|
||||
<string name="get_unlimited_access">Get unlimited access</string>
|
||||
<string name="welcome_to_open_beta">Welcome, to the open beta!</string>
|
||||
<string name="travel_guide">Travel Guide</string>
|
||||
<string name="travel_guide_description">Browse the Wikivoyage guides to the most interesting places on the planet inside OsmAnd without an internet connection.</string>
|
||||
<string name="monthly_map_updates">Map updates: <b>every month</b></string>
|
||||
|
@ -23,7 +33,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 & Hillshade maps</string>
|
||||
<string name="unlock_all_features">Unlock all OsmAnd features</string>
|
||||
|
||||
<string name="purchase_dialog_title">Choose plan</string>
|
||||
|
@ -2854,4 +2864,12 @@
|
|||
<string name="toast_empty_name_error">Location has no name</string>
|
||||
<string name="tunnel_warning">Tunnel ahead</string>
|
||||
<string name="show_tunnels">Tunnels</string>
|
||||
<string name="download_wikipedia_description">Download the Wikipedia articles for %1$s to read them offline.</string>
|
||||
<string name="download_wikipedia_label">Download Wikipedia data</string>
|
||||
<string name="open_in_browser_wiki">Open article online</string>
|
||||
<string name="open_in_browser_wiki_description">View this article in a browser.</string>
|
||||
<string name="download_wiki_region_placeholder">this region</string>
|
||||
<string name="wiki_article_search_text">Searching for the necessary wiki article</string>
|
||||
<string name="wiki_article_not_found">Article not found</string>
|
||||
<string name="how_to_open_wiki_title">How to open Wikipedia articles?</string>
|
||||
</resources>
|
||||
|
|
|
@ -577,6 +577,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>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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)));
|
||||
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(ctx.getString(R.string.purchase_subscription_title, InAppHelper.getLiveUpdatesPrice()));
|
||||
buttonTitle.setText(getString(R.string.purchase_subscription_title, purchaseHelper.getLiveUpdatesPrice()));
|
||||
}
|
||||
buttonSubtitle.setText(R.string.osm_live_month_cost_desc);
|
||||
cardButton.setOnClickListener(new View.OnClickListener() {
|
||||
if (progress) {
|
||||
buttonTitle.setVisibility(View.GONE);
|
||||
buttonSubtitle.setVisibility(View.GONE);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
osmLiveCardButton.setOnClickListener(null);
|
||||
} else {
|
||||
buttonTitle.setVisibility(View.VISIBLE);
|
||||
buttonSubtitle.setVisibility(View.VISIBLE);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
osmLiveCardButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
subscript();
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
return cardView;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)));
|
||||
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(ctx.getString(R.string.purchase_unlim_title, InAppHelper.getFullVersionPrice()));
|
||||
buttonTitle.setText(getString(R.string.purchase_unlim_title, purchaseHelper.getFullVersionPrice()));
|
||||
}
|
||||
buttonSubtitle.setText(R.string.in_app_purchase_desc);
|
||||
cardButton.setOnClickListener(new View.OnClickListener() {
|
||||
if (progress) {
|
||||
buttonTitle.setVisibility(View.GONE);
|
||||
buttonSubtitle.setVisibility(View.GONE);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
planTypeCardButton.setOnClickListener(null);
|
||||
} else {
|
||||
buttonTitle.setVisibility(View.VISIBLE);
|
||||
buttonSubtitle.setVisibility(View.VISIBLE);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
planTypeCardButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
purchaseFullVersion();
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
return cardView;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -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
|
|||
}
|
||||
}
|
||||
|
||||
public boolean isInAppPurchaseAllowed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@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 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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 onInAppPurchaseGetItems() {
|
||||
visibleBanner.updateFreeVersionBanner();
|
||||
for (WeakReference<Fragment> ref : fragSet) {
|
||||
Fragment f = ref.get();
|
||||
if (f instanceof InAppPurchaseListener && f.isAdded()) {
|
||||
((InAppPurchaseListener) f).onGetItems();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void purchaseDepthContours() {
|
||||
if (inAppHelper != null) {
|
||||
getMyApplication().logEvent(this, "depth_contours_purchase_redirect");
|
||||
inAppHelper.purchaseDepthContours(this);
|
||||
@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,25 +410,14 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
|
|||
}
|
||||
|
||||
|
||||
public static class FreeVersionDialog {
|
||||
public static class FreeVersionBanner {
|
||||
private final View freeVersionBanner;
|
||||
private final View 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
|
||||
|
@ -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,12 +484,8 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
|
|||
}
|
||||
|
||||
updateFreeVersionBanner();
|
||||
if(dialog) {
|
||||
expandBanner();
|
||||
} else {
|
||||
collapseBanner();
|
||||
}
|
||||
}
|
||||
|
||||
public void updateFreeVersionBanner() {
|
||||
if (!shouldShowFreeVersionBanner(ctx.getMyApplication())) {
|
||||
|
@ -630,30 +501,9 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
private void setMinimizedFreeVersionBanner(boolean minimize) {
|
||||
if (minimize && isDownlodingPermitted(ctx.getMyApplication().getSettings())) {
|
||||
collapseBanner();
|
||||
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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,15 +59,13 @@ 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
|
||||
|
@ -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,112 +216,115 @@ 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 boolean needRequestInventory() {
|
||||
return !ctx.getSettings().BILLING_PURCHASE_TOKEN_SENT.get()
|
||||
|| System.currentTimeMillis() - lastValidationCheckTime > PURCHASE_VALIDATION_PERIOD_MSEC;
|
||||
}
|
||||
|
||||
public void start(final boolean stopAfterResult) {
|
||||
this.stopAfterResult = stopAfterResult;
|
||||
|
||||
// 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))) {
|
||||
|
||||
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 {
|
||||
inventoryRequesting = true;
|
||||
mHelper.queryInventoryAsync(true, skus, mGotInventoryListener);
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
inventoryRequesting = false;
|
||||
logError("queryInventoryAsync Error", e);
|
||||
notifyDismissProgress();
|
||||
if (stopAfterResult) {
|
||||
stop();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
notifyDismissProgress();
|
||||
if (stopAfterResult) {
|
||||
stop();
|
||||
}
|
||||
notifyDismissProgress(InAppPurchaseTaskType.REQUEST_INVENTORY);
|
||||
stop(true);
|
||||
}
|
||||
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) {
|
||||
logError("start Error", e);
|
||||
if (stopAfterResult) {
|
||||
stop();
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -327,47 +338,43 @@ public class InAppHelper {
|
|||
|
||||
// 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,81 +412,28 @@ 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> {
|
||||
|
||||
logDebug("Launching purchase flow for full version");
|
||||
if (mHelper != null) {
|
||||
try {
|
||||
mHelper.launchPurchaseFlow(activity,
|
||||
SKU_FULL_VERSION_PRICE, RC_REQUEST, mPurchaseFinishedListener);
|
||||
} catch (Exception e) {
|
||||
complain("Cannot launch full version purchase!");
|
||||
logError("purchaseFullVersion Error", e);
|
||||
if (stopAfterResult) {
|
||||
stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private WeakReference<Activity> activity;
|
||||
|
||||
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();
|
||||
}
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logError("purchaseLiveUpdates Error", e);
|
||||
if (stopAfterResult) {
|
||||
stop();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
notifyShowProgress();
|
||||
|
||||
new AsyncTask<Void, Void, String>() {
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doInBackground(Void... params) {
|
||||
userId = ctx.getSettings().BILLING_USER_ID.get();
|
||||
|
@ -509,11 +461,9 @@ public class InAppHelper {
|
|||
logDebug("Response=" + response);
|
||||
if (response == null) {
|
||||
complain("Cannot retrieve userId from server.");
|
||||
notifyDismissProgress();
|
||||
notifyError("Cannot retrieve userId from server.");
|
||||
if (stopAfterResult) {
|
||||
stop();
|
||||
}
|
||||
notifyDismissProgress(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES);
|
||||
notifyError(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES, "Cannot retrieve userId from server.");
|
||||
stop(true);
|
||||
return;
|
||||
|
||||
} else {
|
||||
|
@ -528,39 +478,42 @@ public class InAppHelper {
|
|||
String message = "JSON parsing error: "
|
||||
+ (e.getMessage() == null ? "unknown" : e.getMessage());
|
||||
complain(message);
|
||||
notifyDismissProgress();
|
||||
notifyError(message);
|
||||
if (stopAfterResult) {
|
||||
stop();
|
||||
}
|
||||
notifyDismissProgress(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES);
|
||||
notifyError(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES, message);
|
||||
stop(true);
|
||||
}
|
||||
}
|
||||
|
||||
notifyDismissProgress();
|
||||
notifyDismissProgress(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES);
|
||||
if (!Algorithms.isEmpty(userId)) {
|
||||
logDebug("Launching purchase flow for live updates subscription for userId=" + userId);
|
||||
String payload = userId + " " + token;
|
||||
if (mHelper != null) {
|
||||
final String payload = userId + " " + token;
|
||||
exec(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES, new InAppRunnable() {
|
||||
@Override
|
||||
public boolean run(InAppPurchaseHelper helper) {
|
||||
try {
|
||||
mHelper.launchPurchaseFlow(activity,
|
||||
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();
|
||||
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) {
|
||||
logDebug("onActivityResult(" + requestCode + "," + resultCode + "," + 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) {
|
|
@ -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) {
|
||||
InAppPurchaseHelper purchaseHelper = getInAppPurchaseHelper();
|
||||
if (purchaseHelper != null) {
|
||||
if (purchaseHelper.getActiveTask() == InAppPurchaseTaskType.REQUEST_INVENTORY) {
|
||||
enableProgress();
|
||||
helper.addListener(this);
|
||||
helper.start(false);
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -851,6 +851,19 @@ public class ResourceManager {
|
|||
return map;
|
||||
}
|
||||
|
||||
public List<AmenityIndexRepositoryBinary> getWikiAmenityRepository(double lat, double lon) {
|
||||
List<AmenityIndexRepositoryBinary> repos = new ArrayList<>();
|
||||
for (String filename : amenityRepositories.keySet()) {
|
||||
if (filename.contains("_wiki")
|
||||
|| filename.contains(IndexConstants.BINARY_WIKI_MAP_INDEX_EXT)) {
|
||||
AmenityIndexRepository repository = amenityRepositories.get(filename);
|
||||
if (repository.checkContains(lat, lon) && repository instanceof AmenityIndexRepositoryBinary) {
|
||||
repos.add((AmenityIndexRepositoryBinary) repository);
|
||||
}
|
||||
}
|
||||
}
|
||||
return repos;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////// Working with address ///////////////////////////////////////////
|
||||
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
package net.osmand.plus.wikivoyage;
|
||||
|
||||
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
@ -12,29 +16,42 @@ import android.util.Log;
|
|||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
|
||||
import net.osmand.binary.BinaryMapDataObject;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.map.OsmandRegions;
|
||||
import net.osmand.plus.GPXUtilities;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.mapcontextmenu.WikipediaDialogFragment;
|
||||
import net.osmand.plus.resources.AmenityIndexRepositoryBinary;
|
||||
import net.osmand.plus.wikivoyage.article.WikivoyageArticleDialogFragment;
|
||||
import net.osmand.plus.wikivoyage.article.WikivoyageArticleWikiLinkFragment;
|
||||
import net.osmand.plus.wikivoyage.data.TravelArticle;
|
||||
import net.osmand.plus.wikivoyage.explore.WikivoyageExploreDialogFragment;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static android.support.v4.app.FragmentManager.POP_BACK_STACK_INCLUSIVE;
|
||||
|
||||
|
||||
interface RegionCallback {
|
||||
void onRegionFound(String s);
|
||||
}
|
||||
/**
|
||||
* Custom WebView client to handle the internal links.
|
||||
*/
|
||||
|
||||
public class WikivoyageWebViewClient extends WebViewClient {
|
||||
public class WikivoyageWebViewClient extends WebViewClient implements RegionCallback {
|
||||
|
||||
private static final String TAG = WikivoyageWebViewClient.class.getSimpleName();
|
||||
|
||||
|
@ -43,11 +60,16 @@ public class WikivoyageWebViewClient extends WebViewClient {
|
|||
private Context context;
|
||||
private TravelArticle article;
|
||||
private boolean nightMode;
|
||||
private String regionName;
|
||||
|
||||
private static final String PREFIX_GEO = "geo:";
|
||||
private static final String PAGE_PREFIX_HTTP = "http://";
|
||||
private static final String PAGE_PREFIX_HTTPS = "https://";
|
||||
private static final String WEB_DOMAIN = ".wikivoyage.com/wiki/";
|
||||
private static final String WIKIVOAYAGE_DOMAIN = ".wikivoyage.com/wiki/";
|
||||
private static final String WIKI_DOMAIN = ".wikipedia.org/wiki/";
|
||||
private FetchWikiRegion fetchRegionTask;
|
||||
private WikiArticleSearchTask articleSearchTask;
|
||||
|
||||
|
||||
public WikivoyageWebViewClient(FragmentActivity context, FragmentManager fm, boolean nightMode) {
|
||||
app = (OsmandApplication) context.getApplication();
|
||||
|
@ -58,24 +80,21 @@ public class WikivoyageWebViewClient extends WebViewClient {
|
|||
|
||||
@Override
|
||||
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
||||
if (url.contains(WEB_DOMAIN)) {
|
||||
String lang = url.substring(url.startsWith(PAGE_PREFIX_HTTPS) ? PAGE_PREFIX_HTTPS.length() : 0, url.indexOf("."));
|
||||
String articleName = url.replace(PAGE_PREFIX_HTTPS + lang + WEB_DOMAIN, "")
|
||||
.replaceAll("_", " ");
|
||||
try {
|
||||
articleName = URLDecoder.decode(articleName, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
Log.w(TAG, e.getMessage(), e);
|
||||
}
|
||||
if (url.contains(WIKIVOAYAGE_DOMAIN)) {
|
||||
String lang = getLang(url);
|
||||
String articleName = getArticleNameFromUrl(url, lang);
|
||||
long articleId = app.getTravelDbHelper().getArticleId(articleName, lang);
|
||||
if (articleId != 0) {
|
||||
WikivoyageArticleDialogFragment.showInstance(app, fragmentManager, articleId, lang);
|
||||
} else {
|
||||
warnAboutExternalLoad(url);
|
||||
warnAboutExternalLoad(url, context, nightMode);
|
||||
}
|
||||
return true;
|
||||
} else if (url.contains(WIKI_DOMAIN)) {
|
||||
String articleName = getArticleNameFromUrl(url, getLang(url));
|
||||
getWikiArticle(articleName, url);
|
||||
} else if (url.startsWith(PAGE_PREFIX_HTTP) || url.startsWith(PAGE_PREFIX_HTTPS)) {
|
||||
warnAboutExternalLoad(url);
|
||||
warnAboutExternalLoad(url, context, nightMode);
|
||||
} else if (url.startsWith(PREFIX_GEO)) {
|
||||
if (article != null) {
|
||||
List<GPXUtilities.WptPt> points = article.getGpxFile().getPoints();
|
||||
|
@ -120,7 +139,27 @@ public class WikivoyageWebViewClient extends WebViewClient {
|
|||
return true;
|
||||
}
|
||||
|
||||
private void warnAboutExternalLoad(final String url) {
|
||||
@NonNull
|
||||
private String getLang(String url) {
|
||||
return url.substring(url.startsWith(PAGE_PREFIX_HTTPS) ? PAGE_PREFIX_HTTPS.length() : 0, url.indexOf("."));
|
||||
}
|
||||
|
||||
private String getArticleNameFromUrl(String url, String lang) {
|
||||
String domain = url.contains(WIKIVOAYAGE_DOMAIN) ? WIKIVOAYAGE_DOMAIN : WIKI_DOMAIN;
|
||||
String articleName = url.replace(PAGE_PREFIX_HTTPS + lang + domain, "")
|
||||
.replaceAll("_", " ");
|
||||
try {
|
||||
articleName = URLDecoder.decode(articleName, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
Log.w(TAG, e.getMessage(), e);
|
||||
}
|
||||
return articleName;
|
||||
}
|
||||
|
||||
private static void warnAboutExternalLoad(final String url, final Context context, final boolean nightMode) {
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
new AlertDialog.Builder(context)
|
||||
.setTitle(url)
|
||||
.setMessage(R.string.online_webpage_warning)
|
||||
|
@ -136,5 +175,160 @@ public class WikivoyageWebViewClient extends WebViewClient {
|
|||
|
||||
public void setArticle(TravelArticle article) {
|
||||
this.article = article;
|
||||
if (this.article != null && app != null) {
|
||||
fetchRegionTask = new FetchWikiRegion(this, app.getRegions(), article.getLat(), article.getLon());
|
||||
fetchRegionTask.execute();
|
||||
}
|
||||
}
|
||||
|
||||
private void getWikiArticle(String name, String url) {
|
||||
List<AmenityIndexRepositoryBinary> indexes = app.getResourceManager()
|
||||
.getWikiAmenityRepository(article.getLat(), article.getLon());
|
||||
if (indexes.isEmpty()) {
|
||||
WikivoyageArticleWikiLinkFragment.showInstance(fragmentManager, regionName == null ?
|
||||
"" : regionName, url);
|
||||
} else {
|
||||
articleSearchTask = new WikiArticleSearchTask(name, indexes, (MapActivity) context, nightMode, url);
|
||||
articleSearchTask.execute();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRegionFound(String s) {
|
||||
regionName = s;
|
||||
}
|
||||
|
||||
public void stopRunningAsyncTasks() {
|
||||
if (articleSearchTask != null && articleSearchTask.getStatus() == AsyncTask.Status.RUNNING) {
|
||||
articleSearchTask.cancel(false);
|
||||
}
|
||||
if (fetchRegionTask != null && fetchRegionTask.getStatus() == AsyncTask.Status.RUNNING) {
|
||||
fetchRegionTask.cancel(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static class FetchWikiRegion extends AsyncTask<Void, Void, String> {
|
||||
|
||||
private RegionCallback callback;
|
||||
private OsmandRegions osmandRegions;
|
||||
private double lat;
|
||||
private double lon;
|
||||
|
||||
FetchWikiRegion(RegionCallback callback, OsmandRegions osmandRegions, double lat, double lon) {
|
||||
this.callback = callback;
|
||||
this.osmandRegions = osmandRegions;
|
||||
this.lat = lat;
|
||||
this.lon = lon;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doInBackground(Void... voids) {
|
||||
if (osmandRegions != null) {
|
||||
int x31 = MapUtils.get31TileNumberX(lon);
|
||||
int y31 = MapUtils.get31TileNumberY(lat);
|
||||
List<BinaryMapDataObject> dataObjects = null;
|
||||
try {
|
||||
if (isCancelled()) {
|
||||
return null;
|
||||
}
|
||||
dataObjects = osmandRegions.query(x31, y31);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (dataObjects != null) {
|
||||
for (BinaryMapDataObject b : dataObjects) {
|
||||
if (isCancelled()) {
|
||||
break;
|
||||
}
|
||||
if(osmandRegions.contain(b, x31, y31)) {
|
||||
return osmandRegions.getLocaleName(osmandRegions.getDownloadName(b), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCancelled(){
|
||||
callback = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String result) {
|
||||
if (callback != null) {
|
||||
callback.onRegionFound(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class WikiArticleSearchTask extends AsyncTask<Void, Void, List<Amenity>> {
|
||||
private ProgressDialog dialog;
|
||||
private String name;
|
||||
private List<AmenityIndexRepositoryBinary> indexes;
|
||||
private WeakReference<MapActivity> weakContext;
|
||||
private boolean isNightMode;
|
||||
private String url;
|
||||
|
||||
WikiArticleSearchTask(String articleName, List<AmenityIndexRepositoryBinary> indexes,
|
||||
MapActivity context, boolean isNightMode, String url) {
|
||||
name = articleName;
|
||||
this.indexes = indexes;
|
||||
weakContext = new WeakReference<>(context);
|
||||
dialog = createProgressDialog();
|
||||
this.isNightMode = isNightMode;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
if (dialog != null) {
|
||||
dialog.show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Amenity> doInBackground(Void... voids) {
|
||||
List<Amenity> found = new ArrayList<>();
|
||||
for (AmenityIndexRepositoryBinary repo : indexes) {
|
||||
if (isCancelled()) {
|
||||
break;
|
||||
}
|
||||
found.addAll(repo.searchAmenitiesByName(0, 0, 0, 0,
|
||||
Integer.MAX_VALUE, Integer.MAX_VALUE, name, null));
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCancelled(){
|
||||
dialog = null;
|
||||
indexes.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<Amenity> found) {
|
||||
MapActivity activity = weakContext.get();
|
||||
if (activity != null && !activity.isActivityDestroyed() && dialog != null) {
|
||||
dialog.dismiss();
|
||||
if (!found.isEmpty()) {
|
||||
WikipediaDialogFragment.showInstance(activity, found.get(0));
|
||||
} else {
|
||||
warnAboutExternalLoad(url, weakContext.get(), isNightMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ProgressDialog createProgressDialog() {
|
||||
MapActivity activity = weakContext.get();
|
||||
if (activity != null && !activity.isActivityDestroyed()) {
|
||||
ProgressDialog dialog = new ProgressDialog(activity);
|
||||
dialog.setCancelable(false);
|
||||
dialog.setMessage(activity.getString(R.string.wiki_article_search_text));
|
||||
return dialog;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -247,6 +247,14 @@ public class WikivoyageArticleDialogFragment extends WikivoyageBaseDialogFragmen
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
if (webViewClient != null) {
|
||||
webViewClient.stopRunningAsyncTasks();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
package net.osmand.plus.wikivoyage.article;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.view.View;
|
||||
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.base.MenuBottomSheetDialogFragment;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription;
|
||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerHalfItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleDividerItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
|
||||
import net.osmand.plus.mapcontextmenu.WikipediaDialogFragment;
|
||||
|
||||
public class WikivoyageArticleWikiLinkFragment extends MenuBottomSheetDialogFragment {
|
||||
|
||||
public static final String TAG = WikivoyageArticleWikiLinkFragment.class.getSimpleName();
|
||||
|
||||
public static final String ARTICLE_URL_KEY = "article_url";
|
||||
private static final String WIKI_REGION = "region";
|
||||
|
||||
private String articleUrl;
|
||||
private String wikiRegion;
|
||||
|
||||
@Override
|
||||
public void createMenuItems(Bundle savedInstanceState) {
|
||||
Context ctx = getContext();
|
||||
if (ctx == null) {
|
||||
return;
|
||||
}
|
||||
if (savedInstanceState != null) {
|
||||
articleUrl = savedInstanceState.getString(ARTICLE_URL_KEY);
|
||||
wikiRegion = savedInstanceState.getString(WIKI_REGION);
|
||||
} else {
|
||||
Bundle args = getArguments();
|
||||
if (args != null) {
|
||||
articleUrl = args.getString(ARTICLE_URL_KEY);
|
||||
wikiRegion = args.getString(WIKI_REGION);
|
||||
}
|
||||
}
|
||||
items.add(new TitleItem(getString(R.string.how_to_open_wiki_title)));
|
||||
|
||||
BaseBottomSheetItem wikiLinkitem = new TitleItem.Builder().setTitle(articleUrl)
|
||||
.setTitleColorId(nightMode
|
||||
? R.color.wikivoyage_contents_parent_icon_dark : R.color.wikivoyage_contents_parent_icon_light)
|
||||
.setLayoutId(R.layout.bottom_sheet_item_title)
|
||||
.create();
|
||||
items.add(wikiLinkitem);
|
||||
items.add(new TitleDividerItem(getContext()));
|
||||
|
||||
Drawable downloadIcon = getIcon(R.drawable.ic_action_import, nightMode
|
||||
? R.color.wikivoyage_contents_parent_icon_dark : R.color.wikivoyage_contents_parent_icon_light);
|
||||
|
||||
Drawable viewOnlineIcon = getIcon(R.drawable.ic_world_globe_dark, nightMode
|
||||
? R.color.wikivoyage_contents_parent_icon_dark : R.color.wikivoyage_contents_parent_icon_light);
|
||||
|
||||
BaseBottomSheetItem wikiDownloadItem = new BottomSheetItemWithDescription.Builder()
|
||||
.setDescription(getString(R.string.download_wikipedia_description, wikiRegion.isEmpty() ?
|
||||
getString(R.string.download_wiki_region_placeholder) : wikiRegion))
|
||||
.setIcon(downloadIcon)
|
||||
.setTitle(getString(R.string.download_wikipedia_label))
|
||||
.setLayoutId(R.layout.bottom_sheet_item_with_descr_56dp)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
MapActivity mapActivity = (MapActivity) getActivity();
|
||||
Intent newIntent = new Intent(mapActivity, mapActivity.getMyApplication().getAppCustomization()
|
||||
.getDownloadActivity());
|
||||
newIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
||||
mapActivity.startActivity(newIntent);
|
||||
dismiss();
|
||||
}
|
||||
})
|
||||
.create();
|
||||
items.add(wikiDownloadItem);
|
||||
|
||||
items.add(new DividerHalfItem(getContext()));
|
||||
|
||||
BaseBottomSheetItem wikiArticleOnlineItem = new BottomSheetItemWithDescription.Builder()
|
||||
.setDescription(getString(R.string.open_in_browser_wiki_description))
|
||||
.setIcon(viewOnlineIcon)
|
||||
.setTitle(getString(R.string.open_in_browser_wiki))
|
||||
.setLayoutId(R.layout.bottom_sheet_item_with_descr_56dp)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
WikipediaDialogFragment.showFullArticle(getContext(), Uri.parse(articleUrl), nightMode);
|
||||
dismiss();
|
||||
}
|
||||
})
|
||||
.create();
|
||||
items.add(wikiArticleOnlineItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putString(ARTICLE_URL_KEY, articleUrl);
|
||||
outState.putString(WIKI_REGION, wikiRegion);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean useScrollableItemsContainer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getBgColorId() {
|
||||
return nightMode ? R.color.wikivoyage_bottom_bar_bg_dark : R.color.bg_color_light;
|
||||
}
|
||||
|
||||
public static boolean showInstance(@NonNull FragmentManager fm,
|
||||
@NonNull String region,
|
||||
@NonNull String articleUrl) {
|
||||
try {
|
||||
Bundle args = new Bundle();
|
||||
args.putString(ARTICLE_URL_KEY, articleUrl);
|
||||
args.putString(WIKI_REGION, region);
|
||||
WikivoyageArticleWikiLinkFragment fragment = new WikivoyageArticleWikiLinkFragment();
|
||||
|
||||
fragment.setArguments(args);
|
||||
fragment.show(fm, TAG);
|
||||
return true;
|
||||
} catch (RuntimeException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -91,14 +91,27 @@ public class TravelArticle {
|
|||
return null;
|
||||
}
|
||||
|
||||
int firstParagraphStart = content.indexOf("<p>");
|
||||
int firstParagraphEnd = content.indexOf("</p>");
|
||||
String pOpened = "<p>";
|
||||
String pClosed = "</p>";
|
||||
|
||||
int firstParagraphStart = content.indexOf(pOpened);
|
||||
int firstParagraphEnd = content.indexOf(pClosed);
|
||||
if (firstParagraphStart == -1 || firstParagraphEnd == -1) {
|
||||
return null;
|
||||
}
|
||||
int pClosedLength = pClosed.length();
|
||||
String firstParagraphHtml = content.substring(firstParagraphStart, firstParagraphEnd + pClosedLength);
|
||||
while (firstParagraphHtml.length() == (pOpened.length() + pClosedLength)
|
||||
&& (firstParagraphEnd + pClosedLength) < content.length()) {
|
||||
firstParagraphStart = content.indexOf(pOpened, firstParagraphEnd);
|
||||
firstParagraphEnd = firstParagraphStart == -1 ? -1 : content.indexOf(pClosed, firstParagraphStart);
|
||||
if (firstParagraphStart != -1 && firstParagraphEnd != -1) {
|
||||
firstParagraphHtml = content.substring(firstParagraphStart, firstParagraphEnd + pClosedLength);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 4 is the length of </p> tag
|
||||
String firstParagraphHtml = content.substring(firstParagraphStart, firstParagraphEnd + 4);
|
||||
String firstParagraphText = Html.fromHtml(firstParagraphHtml).toString().trim();
|
||||
String[] phrases = firstParagraphText.split("\\. ");
|
||||
|
||||
|
|
|
@ -3,18 +3,41 @@ package net.osmand.plus.wikivoyage.explore;
|
|||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.base.BaseOsmAndFragment;
|
||||
import net.osmand.plus.wikivoyage.explore.travelcards.BaseTravelCard;
|
||||
import net.osmand.plus.wikivoyage.explore.travelcards.OpenBetaTravelCard;
|
||||
import net.osmand.plus.wikivoyage.explore.travelcards.StartEditingTravelCard;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ExploreTabFragment extends BaseOsmAndFragment {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_explore_tab, container, false);
|
||||
OsmandApplication app = getMyApplication();
|
||||
boolean nightMode = !getSettings().isLightContent();
|
||||
|
||||
final View mainView = inflater.inflate(R.layout.fragment_explore_tab, container, false);
|
||||
|
||||
ArrayList<BaseTravelCard> items = new ArrayList<>();
|
||||
|
||||
OpenBetaTravelCard openBetaTravelCard = new OpenBetaTravelCard(app, nightMode, getFragmentManager());
|
||||
StartEditingTravelCard startEditingTravelCard = new StartEditingTravelCard(app, nightMode);
|
||||
items.add(openBetaTravelCard);
|
||||
items.add(startEditingTravelCard);
|
||||
|
||||
final RecyclerView rv = (RecyclerView) mainView.findViewById(R.id.recycler_view);
|
||||
rv.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
return mainView;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
package net.osmand.plus.wikivoyage.explore.travelcards;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.dialogs.ChoosePlanDialogFragment;
|
||||
|
||||
public class OpenBetaTravelCard extends BaseTravelCard {
|
||||
|
||||
private FragmentManager fragmentManager;
|
||||
|
||||
public OpenBetaTravelCard(OsmandApplication app, boolean nightMode, FragmentManager fragmentManager) {
|
||||
super(app, nightMode);
|
||||
this.fragmentManager = fragmentManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder) {
|
||||
if (viewHolder instanceof OpenBetaTravelVH) {
|
||||
final OpenBetaTravelVH holder = (OpenBetaTravelVH) viewHolder;
|
||||
holder.title.setText(R.string.welcome_to_open_beta);
|
||||
holder.description.setText(R.string.welcome_to_open_beta_description);
|
||||
holder.backgroundImage.setImageResource(R.drawable.img_help_wikivoyage_articles);
|
||||
holder.button.setText(R.string.get_unlimited_access);
|
||||
holder.button.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
ChoosePlanDialogFragment.showFreeVersionInstance(fragmentManager);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class OpenBetaTravelVH extends RecyclerView.ViewHolder {
|
||||
|
||||
final TextView title;
|
||||
final TextView description;
|
||||
final TextView button;
|
||||
final ImageView backgroundImage;
|
||||
|
||||
OpenBetaTravelVH(final View itemView) {
|
||||
super(itemView);
|
||||
title = (TextView) itemView.findViewById(R.id.title);
|
||||
description = (TextView) itemView.findViewById(R.id.description);
|
||||
button = (TextView) itemView.findViewById(R.id.bottom_button_text);
|
||||
backgroundImage = (ImageView) itemView.findViewById(R.id.background_image);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCardType() {
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package net.osmand.plus.wikivoyage.explore.travelcards;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.customtabs.CustomTabsIntent;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
|
||||
public class StartEditingTravelCard extends BaseTravelCard {
|
||||
|
||||
public StartEditingTravelCard(OsmandApplication app, boolean nightMode) {
|
||||
super(app, nightMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder) {
|
||||
if (viewHolder instanceof StartEditingTravelVH) {
|
||||
final StartEditingTravelVH holder = (StartEditingTravelVH) viewHolder;
|
||||
holder.title.setText(R.string.start_editing_card_image_text);
|
||||
holder.description.setText(R.string.start_editing_card_description);
|
||||
holder.backgroundImage.setImageResource(R.drawable.img_help_wikivoyage_contribute);
|
||||
holder.button.setText(R.string.start_editing);
|
||||
holder.button.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder()
|
||||
.setToolbarColor(ContextCompat.getColor(app, nightMode ? R.color.actionbar_dark_color : R.color.actionbar_light_color))
|
||||
.build();
|
||||
String text = "https://" + app.getLanguage().toLowerCase() + ".m.wikivoyage.org";
|
||||
customTabsIntent.launchUrl(app, Uri.parse(text));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class StartEditingTravelVH extends RecyclerView.ViewHolder {
|
||||
|
||||
final TextView title;
|
||||
final TextView description;
|
||||
final TextView button;
|
||||
final ImageView backgroundImage;
|
||||
|
||||
StartEditingTravelVH(final View itemView) {
|
||||
super(itemView);
|
||||
title = (TextView) itemView.findViewById(R.id.title);
|
||||
description = (TextView) itemView.findViewById(R.id.description);
|
||||
button = (TextView) itemView.findViewById(R.id.bottom_button_text);
|
||||
backgroundImage = (ImageView) itemView.findViewById(R.id.background_image);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCardType() {
|
||||
return 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
package net.osmand.plus.wikivoyage.explore.travelcards;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
|
||||
public class TravelDownloadUpdateCard extends BaseTravelCard {
|
||||
|
||||
public static final int TYPE = 50;
|
||||
|
||||
private boolean download;
|
||||
private boolean loadingInProgress;
|
||||
|
||||
public TravelDownloadUpdateCard(OsmandApplication app, boolean nightMode, boolean download) {
|
||||
super(app, nightMode);
|
||||
this.download = download;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder) {
|
||||
if (viewHolder instanceof CardViewHolder) {
|
||||
CardViewHolder holder = (CardViewHolder) viewHolder;
|
||||
holder.title.setText(getTitle());
|
||||
holder.icon.setImageDrawable(getIcon());
|
||||
holder.description.setText(getDescription());
|
||||
holder.fileIcon.setImageDrawable(getFileIcon());
|
||||
holder.fileTitle.setText(getFileTitle());
|
||||
holder.fileDescription.setText(getFileDescription());
|
||||
boolean primaryBtnVisible = updatePrimaryButton(holder.primaryButton);
|
||||
boolean secondaryBtnVisible = updateSecondaryButton(holder.secondaryBtn);
|
||||
holder.buttonsDivider.setVisibility(primaryBtnVisible && secondaryBtnVisible ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCardType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private String getTitle() {
|
||||
if (loadingInProgress) {
|
||||
return app.getString(R.string.shared_string_downloading) + "...";
|
||||
}
|
||||
return app.getString(download ? R.string.download_file : R.string.update_is_available);
|
||||
}
|
||||
|
||||
private Drawable getIcon() {
|
||||
int id = download ? R.drawable.travel_card_download_icon : R.drawable.travel_card_update_icon;
|
||||
return ContextCompat.getDrawable(app, id);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private String getDescription() {
|
||||
return app.getString(download ? R.string.travel_card_download_descr : R.string.travel_card_update_descr);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private String getFileTitle() {
|
||||
return "Some file"; // TODO
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private String getFileDescription() {
|
||||
return "Some description"; // TODO
|
||||
}
|
||||
|
||||
private Drawable getFileIcon() {
|
||||
return getActiveIcon(R.drawable.ic_action_read_article);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if button is visible, false otherwise.
|
||||
*/
|
||||
private boolean updateSecondaryButton(TextView btn) {
|
||||
if (loadingInProgress || !download) {
|
||||
btn.setText(loadingInProgress ? R.string.shared_string_cancel : R.string.later);
|
||||
btn.setVisibility(View.VISIBLE);
|
||||
btn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onSecondaryBtnClick();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
btn.setVisibility(View.GONE);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if button is visible, false otherwise.
|
||||
*/
|
||||
private boolean updatePrimaryButton(TextView btn) {
|
||||
if (!loadingInProgress) {
|
||||
btn.setText(download ? R.string.shared_string_download : R.string.shared_string_update);
|
||||
btn.setVisibility(View.VISIBLE);
|
||||
btn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onPrimaryBtnClick();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
btn.setVisibility(View.GONE);
|
||||
return false;
|
||||
}
|
||||
|
||||
private void onSecondaryBtnClick() {
|
||||
|
||||
}
|
||||
|
||||
private void onPrimaryBtnClick() {
|
||||
|
||||
}
|
||||
|
||||
public class CardViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
final TextView title;
|
||||
final ImageView icon;
|
||||
final TextView description;
|
||||
final ImageView fileIcon;
|
||||
final TextView fileTitle;
|
||||
final TextView fileDescription;
|
||||
final ProgressBar progressBar;
|
||||
final TextView secondaryBtn;
|
||||
final View buttonsDivider;
|
||||
final TextView primaryButton;
|
||||
|
||||
@SuppressWarnings("RedundantCast")
|
||||
public CardViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
title = (TextView) itemView.findViewById(R.id.title);
|
||||
icon = (ImageView) itemView.findViewById(R.id.icon);
|
||||
description = (TextView) itemView.findViewById(R.id.description);
|
||||
fileIcon = (ImageView) itemView.findViewById(R.id.file_icon);
|
||||
fileTitle = (TextView) itemView.findViewById(R.id.file_title);
|
||||
fileDescription = (TextView) itemView.findViewById(R.id.file_description);
|
||||
progressBar = (ProgressBar) itemView.findViewById(R.id.progress_bar);
|
||||
secondaryBtn = (TextView) itemView.findViewById(R.id.secondary_button);
|
||||
buttonsDivider = itemView.findViewById(R.id.buttons_divider);
|
||||
primaryButton = (TextView) itemView.findViewById(R.id.primary_button);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue