Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
58ae1bd3ab
11 changed files with 690 additions and 393 deletions
|
@ -38,6 +38,11 @@
|
||||||
<string name="osm_live_month_cost_desc">Monthly payment</string>
|
<string name="osm_live_month_cost_desc">Monthly payment</string>
|
||||||
<string name="osm_live_active">Active</string>
|
<string name="osm_live_active">Active</string>
|
||||||
<string name="osm_live_not_active">Inactive</string>
|
<string name="osm_live_not_active">Inactive</string>
|
||||||
|
<string name="osm_live_enter_email">Please enter valid E-mail address</string>
|
||||||
|
<string name="osm_live_enter_user_name">Please enter Public Name</string>
|
||||||
|
<string name="osm_live_thanks">Thank you for subscribing to live updates!</string>
|
||||||
|
<string name="osm_live_region_desc">Part your donation will be sent to OSM users who submit changes to the map in that region</string>
|
||||||
|
<string name="osm_live_subscription_settings">Subscription settings</string>
|
||||||
|
|
||||||
<string name="osm_live_header">This subscription enables hourly updates for all maps around the world.
|
<string name="osm_live_header">This subscription enables hourly updates for all maps around the world.
|
||||||
Major part of the income goes back to OSM community and is paid out per each OSM contribution.
|
Major part of the income goes back to OSM community and is paid out per each OSM contribution.
|
||||||
|
|
13
OsmAnd/res/drawable/btn_round_blue.xml
Normal file
13
OsmAnd/res/drawable/btn_round_blue.xml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item android:state_pressed="true"><shape android:shape="rectangle">
|
||||||
|
<solid android:color="@color/map_widget_blue_pressed" />
|
||||||
|
<corners android:radius="@dimen/map_button_rect_rad" />
|
||||||
|
</shape></item>
|
||||||
|
<item><shape android:shape="rectangle">
|
||||||
|
<solid android:color="@color/map_widget_blue" />
|
||||||
|
<corners android:radius="@dimen/map_button_rect_rad" />
|
||||||
|
</shape></item>
|
||||||
|
|
||||||
|
</selector>
|
|
@ -4,10 +4,10 @@
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
android:paddingLeft="8dp"
|
android:paddingLeft="8dp"
|
||||||
android:paddingRight="8dp"
|
android:paddingRight="8dp"
|
||||||
android:paddingTop="8dp"
|
android:paddingTop="8dp">
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/subscription_banner"
|
android:id="@+id/subscription_banner"
|
||||||
|
@ -20,26 +20,28 @@
|
||||||
android:paddingRight="8dp"
|
android:paddingRight="8dp"
|
||||||
android:paddingTop="16dp">
|
android:paddingTop="16dp">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:src="@drawable/ic_action_osm_live"/>
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/ic_action_osm_live"/>
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginLeft="10dp"
|
||||||
|
android:text="@string/osm_live_subscription"
|
||||||
|
android:textColor="@color/color_white"
|
||||||
|
android:textSize="@dimen/default_list_text_size"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:typeface="@string/font_roboto_regular"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/osm_live_subscription"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:layout_marginLeft="10dp"
|
|
||||||
android:textColor="@color/color_white"
|
|
||||||
android:textSize="@dimen/default_list_text_size"
|
|
||||||
android:textStyle="bold"
|
|
||||||
app:typeface="@string/font_roboto_regular"/>
|
|
||||||
</LinearLayout>
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -51,27 +53,28 @@
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="bottom|right"
|
android:layout_gravity="bottom|right"
|
||||||
android:gravity="right"
|
android:layout_marginTop="16dp"
|
||||||
android:layout_marginTop="16dp">
|
android:gravity="right">
|
||||||
<Button
|
|
||||||
android:id="@+id/read_more_button"
|
<Button
|
||||||
android:layout_width="wrap_content"
|
android:id="@+id/read_more_button"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:textColor="@color/color_white"
|
android:layout_height="wrap_content"
|
||||||
android:background="@drawable/btn_round_shade"
|
android:background="@drawable/btn_round_shade"
|
||||||
android:text="@string/shared_string_read_more"/>
|
android:text="@string/shared_string_read_more"
|
||||||
|
android:textColor="@color/color_white"/>
|
||||||
<Button
|
|
||||||
android:id="@+id/subscription_button"
|
<Button
|
||||||
android:layout_width="wrap_content"
|
android:id="@+id/subscription_button"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_marginLeft="32dp"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="@color/color_white"
|
android:layout_marginLeft="32dp"
|
||||||
android:background="@drawable/btn_round_shade"
|
android:background="@drawable/btn_round_shade"
|
||||||
android:text="@string/osm_live_subscribe_btn"/>
|
android:text="@string/osm_live_subscribe_btn"
|
||||||
</LinearLayout>
|
android:textColor="@color/color_white"/>
|
||||||
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
@ -85,33 +88,54 @@
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:gravity="center_vertical"
|
||||||
android:minHeight="44dp">
|
android:minHeight="64dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
<LinearLayout
|
||||||
android:layout_width="120dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="16dp"
|
android:orientation="vertical">
|
||||||
android:layout_marginRight="16dp"
|
|
||||||
android:text="@string/osm_live_subscription"
|
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
|
||||||
android:textSize="@dimen/default_desc_text_size"
|
|
||||||
app:typeface="@string/font_roboto_regular"/>
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
android:id="@+id/statusTextView"
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:text="@string/shared_string_status"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:textSize="@dimen/default_desc_text_size"
|
||||||
|
app:typeface="@string/font_roboto_regular"/>
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/statusTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:text="@string/osm_live_active"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:textSize="@dimen/default_list_text_size_large"
|
||||||
|
app:typeface="@string/font_roboto_medium"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginBottom="4dp"
|
android:gravity="right|center_vertical"
|
||||||
android:layout_marginLeft="16dp"
|
android:layout_marginRight="16dp">
|
||||||
android:layout_marginRight="16dp"
|
|
||||||
android:layout_marginTop="4dp"
|
<ImageView
|
||||||
android:gravity="right"
|
android:id="@+id/statusIcon"
|
||||||
android:text="@string/osm_live_active"
|
android:layout_width="wrap_content"
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
android:layout_height="wrap_content"
|
||||||
android:textSize="@dimen/default_desc_text_size"
|
android:src="@drawable/ic_action_done"/>
|
||||||
app:textAllCapsCompat="true"
|
|
||||||
app:typeface="@string/font_roboto_medium"/>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
|
@ -123,7 +147,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:minHeight="44dp">
|
android:minHeight="48dp">
|
||||||
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
@ -133,7 +157,7 @@
|
||||||
android:layout_marginRight="16dp"
|
android:layout_marginRight="16dp"
|
||||||
android:text="@string/osm_live_support_region"
|
android:text="@string/osm_live_support_region"
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
android:textSize="@dimen/default_desc_text_size"
|
android:textSize="@dimen/default_list_text_size"
|
||||||
app:typeface="@string/font_roboto_regular"/>
|
app:typeface="@string/font_roboto_regular"/>
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
@ -147,12 +171,12 @@
|
||||||
android:gravity="right"
|
android:gravity="right"
|
||||||
android:text="World"
|
android:text="World"
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
android:textSize="@dimen/default_desc_text_size"
|
android:textSize="@dimen/default_list_text_size"
|
||||||
app:typeface="@string/font_roboto_medium"/>
|
app:typeface="@string/font_roboto_medium"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
android:background="?attr/dashboard_divider"/>
|
android:background="?attr/dashboard_divider"/>
|
||||||
|
@ -160,71 +184,20 @@
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:gravity="right|center_vertical"
|
||||||
android:minHeight="44dp">
|
android:minHeight="48dp">
|
||||||
|
|
||||||
|
<Button
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
android:id="@+id/subscribeButton"
|
||||||
android:layout_width="120dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="16dp"
|
android:layout_marginLeft="16dp"
|
||||||
android:layout_marginRight="16dp"
|
android:layout_marginRight="6dp"
|
||||||
android:text="@string/shared_string_email_address"
|
android:background="?attr/selectableItemBackground"
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
android:paddingLeft="10dp"
|
||||||
android:textSize="@dimen/default_desc_text_size"
|
android:paddingRight="10dp"
|
||||||
app:typeface="@string/font_roboto_regular"/>
|
android:text="@string/osm_live_subscribe_btn"
|
||||||
|
android:textColor="?attr/color_dialog_buttons"/>
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
|
||||||
android:id="@+id/emailTextView"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="4dp"
|
|
||||||
android:layout_marginLeft="16dp"
|
|
||||||
android:layout_marginRight="16dp"
|
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
android:gravity="right"
|
|
||||||
android:text="my@email.com"
|
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
|
||||||
android:textSize="@dimen/default_desc_text_size"
|
|
||||||
app:typeface="@string/font_roboto_medium"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1dp"
|
|
||||||
android:background="?attr/dashboard_divider"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center"
|
|
||||||
android:minHeight="44dp">
|
|
||||||
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
|
||||||
android:layout_width="120dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginLeft="16dp"
|
|
||||||
android:layout_marginRight="16dp"
|
|
||||||
android:text="@string/osm_live_user_public_name"
|
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
|
||||||
android:textSize="@dimen/default_desc_text_size"
|
|
||||||
app:typeface="@string/font_roboto_regular"/>
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
|
||||||
android:id="@+id/userNameTextView"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="4dp"
|
|
||||||
android:layout_marginLeft="16dp"
|
|
||||||
android:layout_marginRight="16dp"
|
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
android:gravity="right"
|
|
||||||
android:text="None"
|
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
|
||||||
android:textSize="@dimen/default_desc_text_size"
|
|
||||||
app:typeface="@string/font_roboto_medium"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,12 @@
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/closeButton"
|
android:id="@+id/closeButton"
|
||||||
style="@style/Widget.AppCompat.Button.Borderless"
|
style="@style/Widget.AppCompat.Button.Borderless"
|
||||||
android:layout_width="48dp"
|
android:layout_width="52dp"
|
||||||
android:layout_height="48dp"
|
android:layout_height="52dp"
|
||||||
android:src="@drawable/ic_action_remove_dark"/>
|
android:src="@drawable/ic_action_remove_dark"/>
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/titleTextView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="16dp"
|
android:layout_marginLeft="16dp"
|
||||||
|
@ -142,21 +143,36 @@
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingLeft="2dp"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:text="@string/osm_live_support_region"/>
|
||||||
|
|
||||||
<net.osmand.plus.widgets.AutoCompleteTextViewEx
|
<net.osmand.plus.widgets.AutoCompleteTextViewEx
|
||||||
android:id="@+id/selectCountryEdit"
|
android:id="@+id/selectCountryEdit"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="16dp"
|
|
||||||
android:layout_marginRight="16dp"
|
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
android:paddingLeft="2dp"
|
android:paddingLeft="2dp"
|
||||||
android:paddingRight="0dp"
|
android:paddingRight="0dp"
|
||||||
android:drawableRight="@drawable/ic_action_arrow_drop_down"
|
android:drawableRight="@drawable/ic_action_arrow_drop_down"
|
||||||
android:editable="false"
|
android:editable="false"
|
||||||
android:hint="@string/osm_live_support_region"/>
|
android:text="Ukraine"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingLeft="2dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:text="@string/osm_live_region_desc"/>
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@ -165,11 +181,35 @@
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/editModeBottomView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/saveChangesButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="72dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingRight="16dp"
|
||||||
|
android:textColor="@color/color_white"
|
||||||
|
android:background="@drawable/btn_round_blue"
|
||||||
|
android:text="@string/shared_string_save_changes"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/purchaseCard"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="8dp"
|
android:layout_margin="8dp"
|
||||||
android:background="?attr/bg_card"
|
android:background="?attr/bg_card"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical"
|
||||||
|
android:visibility="visible">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
|
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
|
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="shared_string_status">Status</string>
|
||||||
|
<string name="shared_string_save_changes">Save changes</string>
|
||||||
<string name="shared_string_email_address">E-mail address</string>
|
<string name="shared_string_email_address">E-mail address</string>
|
||||||
<string name="rendering_attr_hideUnderground_name">Hide underground objects</string>
|
<string name="rendering_attr_hideUnderground_name">Hide underground objects</string>
|
||||||
<string name="data_is_not_available">Data is not available</string>
|
<string name="data_is_not_available">Data is not available</string>
|
||||||
|
|
147
OsmAnd/src/net/osmand/AndroidNetworkUtils.java
Normal file
147
OsmAnd/src/net/osmand/AndroidNetworkUtils.java
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
package net.osmand;
|
||||||
|
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
|
||||||
|
import net.osmand.osm.io.NetworkUtils;
|
||||||
|
import net.osmand.plus.OsmandApplication;
|
||||||
|
import net.osmand.plus.R;
|
||||||
|
import net.osmand.plus.Version;
|
||||||
|
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class AndroidNetworkUtils {
|
||||||
|
|
||||||
|
public interface OnRequestResultListener {
|
||||||
|
void onResult(String result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendRequestAsync(final OsmandApplication ctx,
|
||||||
|
final String url,
|
||||||
|
final Map<String, String> parameters,
|
||||||
|
final String userOperation,
|
||||||
|
final OnRequestResultListener listener) {
|
||||||
|
|
||||||
|
new AsyncTask<Void, Void, String>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String doInBackground(Void... params) {
|
||||||
|
try {
|
||||||
|
return sendRequest(ctx, url, parameters, userOperation);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(String response) {
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onResult(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}.execute((Void) null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String sendRequest(OsmandApplication ctx, String url, Map<String, String> parameters, String userOperation) {
|
||||||
|
HttpURLConnection connection = null;
|
||||||
|
try {
|
||||||
|
connection = NetworkUtils.getHttpURLConnection(url);
|
||||||
|
|
||||||
|
connection.setRequestProperty("Accept-Charset", "UTF-8");
|
||||||
|
connection.setRequestProperty("User-Agent", Version.getFullVersion(ctx));
|
||||||
|
connection.setConnectTimeout(15000);
|
||||||
|
|
||||||
|
if (parameters != null && parameters.size() > 0) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (Map.Entry<String, String> entry : parameters.entrySet()) {
|
||||||
|
if (sb.length() > 0) {
|
||||||
|
sb.append("&");
|
||||||
|
}
|
||||||
|
sb.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), "UTF-8"));
|
||||||
|
}
|
||||||
|
String params = sb.toString();
|
||||||
|
|
||||||
|
connection.setDoInput(true);
|
||||||
|
connection.setDoOutput(true);
|
||||||
|
connection.setUseCaches(false);
|
||||||
|
connection.setRequestMethod("POST");
|
||||||
|
|
||||||
|
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
|
||||||
|
connection.setRequestProperty("Content-Length", String.valueOf(params.getBytes("UTF-8").length));
|
||||||
|
connection.setFixedLengthStreamingMode(params.getBytes("UTF-8").length);
|
||||||
|
|
||||||
|
OutputStream output = new BufferedOutputStream(connection.getOutputStream());
|
||||||
|
output.write(params.getBytes("UTF-8"));
|
||||||
|
output.flush();
|
||||||
|
output.close();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
connection.setRequestMethod("GET");
|
||||||
|
connection.connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
|
||||||
|
String msg = userOperation
|
||||||
|
+ " " + ctx.getString(R.string.failed_op) + " : " + connection.getResponseMessage();
|
||||||
|
showToast(ctx, msg);
|
||||||
|
} else {
|
||||||
|
StringBuilder responseBody = new StringBuilder();
|
||||||
|
responseBody.setLength(0);
|
||||||
|
InputStream i = connection.getInputStream();
|
||||||
|
if (i != null) {
|
||||||
|
BufferedReader in = new BufferedReader(new InputStreamReader(i, "UTF-8"), 256);
|
||||||
|
String s;
|
||||||
|
boolean f = true;
|
||||||
|
while ((s = in.readLine()) != null) {
|
||||||
|
if (!f) {
|
||||||
|
responseBody.append("\n");
|
||||||
|
} else {
|
||||||
|
f = false;
|
||||||
|
}
|
||||||
|
responseBody.append(s);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
in.close();
|
||||||
|
i.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// ignore exception
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return responseBody.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
// that's tricky case why NPE is thrown to fix that problem httpClient could be used
|
||||||
|
String msg = ctx.getString(R.string.auth_failed);
|
||||||
|
showToast(ctx, msg);
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
showToast(ctx, MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
|
||||||
|
+ ": " + ctx.getResources().getString(R.string.shared_string_unexpected_error), userOperation));
|
||||||
|
} catch (IOException e) {
|
||||||
|
showToast(ctx, MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
|
||||||
|
+ ": " + ctx.getResources().getString(R.string.shared_string_io_error), userOperation));
|
||||||
|
} finally {
|
||||||
|
if (connection != null) {
|
||||||
|
connection.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void showToast(OsmandApplication ctx, String message) {
|
||||||
|
ctx.showToastMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -818,6 +818,7 @@ public class OsmandSettings {
|
||||||
public final OsmandPreference<String> BILLING_USER_COUNTRY_DOWNLOAD_NAME = new StringPreference("billing_user_country_download_name", "").makeGlobal();
|
public final OsmandPreference<String> BILLING_USER_COUNTRY_DOWNLOAD_NAME = new StringPreference("billing_user_country_download_name", "").makeGlobal();
|
||||||
public final OsmandPreference<Boolean> BILLING_HIDE_USER_NAME = new BooleanPreference("billing_hide_user_name", false).makeGlobal();
|
public final OsmandPreference<Boolean> BILLING_HIDE_USER_NAME = new BooleanPreference("billing_hide_user_name", false).makeGlobal();
|
||||||
public final OsmandPreference<Boolean> BILLING_PURCHASE_TOKEN_SENT = new BooleanPreference("billing_purchase_token_sent", false).makeGlobal();
|
public final OsmandPreference<Boolean> BILLING_PURCHASE_TOKEN_SENT = new BooleanPreference("billing_purchase_token_sent", false).makeGlobal();
|
||||||
|
public final OsmandPreference<Boolean> LIVE_UPDATES_PURCHASED = new BooleanPreference("billing_live_updates_purchased", false).makeGlobal();
|
||||||
|
|
||||||
// this value string is synchronized with settings_pref.xml preference name
|
// this value string is synchronized with settings_pref.xml preference name
|
||||||
public final OsmandPreference<String> USER_OSM_BUG_NAME =
|
public final OsmandPreference<String> USER_OSM_BUG_NAME =
|
||||||
|
|
|
@ -5,7 +5,8 @@ import android.content.Intent;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import net.osmand.osm.io.NetworkUtils;
|
import net.osmand.AndroidNetworkUtils;
|
||||||
|
import net.osmand.AndroidNetworkUtils.OnRequestResultListener;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
import net.osmand.plus.Version;
|
import net.osmand.plus.Version;
|
||||||
|
@ -19,16 +20,6 @@ import net.osmand.util.Algorithms;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.BufferedOutputStream;
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.text.MessageFormat;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -37,6 +28,7 @@ import java.util.Map;
|
||||||
public class InAppHelper {
|
public class InAppHelper {
|
||||||
// Debug tag, for logging
|
// Debug tag, for logging
|
||||||
static final String TAG = "InAppHelper";
|
static final String TAG = "InAppHelper";
|
||||||
|
boolean mDebugLog = false;
|
||||||
|
|
||||||
private static boolean mSubscribedToLiveUpdates = false;
|
private static boolean mSubscribedToLiveUpdates = false;
|
||||||
private static String mLiveUpdatesPrice;
|
private static String mLiveUpdatesPrice;
|
||||||
|
@ -112,7 +104,7 @@ public class InAppHelper {
|
||||||
"YTjh1H/ZgqIHy5ZluahINuDE76qdLYMXrDMQIDAQAB";
|
"YTjh1H/ZgqIHy5ZluahINuDE76qdLYMXrDMQIDAQAB";
|
||||||
|
|
||||||
// Create the helper, passing it our context and the public key to verify signatures with
|
// Create the helper, passing it our context and the public key to verify signatures with
|
||||||
Log.d(TAG, "Creating InAppHelper.");
|
logDebug("Creating InAppHelper.");
|
||||||
mHelper = new IabHelper(ctx, base64EncodedPublicKey);
|
mHelper = new IabHelper(ctx, base64EncodedPublicKey);
|
||||||
|
|
||||||
// enable debug logging (for a production application, you should set this to false).
|
// enable debug logging (for a production application, you should set this to false).
|
||||||
|
@ -120,10 +112,10 @@ public class InAppHelper {
|
||||||
|
|
||||||
// Start setup. This is asynchronous and the specified listener
|
// Start setup. This is asynchronous and the specified listener
|
||||||
// will be called once setup completes.
|
// will be called once setup completes.
|
||||||
Log.d(TAG, "Starting setup.");
|
logDebug("Starting setup.");
|
||||||
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
|
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
|
||||||
public void onIabSetupFinished(IabResult result) {
|
public void onIabSetupFinished(IabResult result) {
|
||||||
Log.d(TAG, "Setup finished.");
|
logDebug("Setup finished.");
|
||||||
|
|
||||||
if (!result.isSuccess()) {
|
if (!result.isSuccess()) {
|
||||||
// Oh noes, there was a problem.
|
// Oh noes, there was a problem.
|
||||||
|
@ -141,7 +133,7 @@ public class InAppHelper {
|
||||||
if (mHelper == null) return;
|
if (mHelper == null) return;
|
||||||
|
|
||||||
// IAB is fully set up. Now, let's get an inventory of stuff we own.
|
// IAB is fully set up. Now, let's get an inventory of stuff we own.
|
||||||
Log.d(TAG, "Setup successful. Querying inventory.");
|
logDebug("Setup successful. Querying inventory.");
|
||||||
List<String> skus = new ArrayList<>();
|
List<String> skus = new ArrayList<>();
|
||||||
skus.add(SKU_LIVE_UPDATES);
|
skus.add(SKU_LIVE_UPDATES);
|
||||||
mHelper.queryInventoryAsync(true, skus, mGotInventoryListener);
|
mHelper.queryInventoryAsync(true, skus, mGotInventoryListener);
|
||||||
|
@ -152,7 +144,7 @@ public class InAppHelper {
|
||||||
// Listener that's called when we finish querying the items and subscriptions we own
|
// Listener that's called when we finish querying the items and subscriptions we own
|
||||||
private IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
|
private IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
|
||||||
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
|
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
|
||||||
Log.d(TAG, "Query inventory finished.");
|
logDebug("Query inventory finished.");
|
||||||
|
|
||||||
// Have we been disposed of in the meantime? If so, quit.
|
// Have we been disposed of in the meantime? If so, quit.
|
||||||
if (mHelper == null) return;
|
if (mHelper == null) return;
|
||||||
|
@ -169,7 +161,7 @@ public class InAppHelper {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(TAG, "Query inventory was successful.");
|
logDebug("Query inventory was successful.");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for items we own. Notice that for each purchase, we check
|
* Check for items we own. Notice that for each purchase, we check
|
||||||
|
@ -180,7 +172,7 @@ public class InAppHelper {
|
||||||
// Do we have the live updates?
|
// Do we have the live updates?
|
||||||
Purchase liveUpdatesPurchase = inventory.getPurchase(SKU_LIVE_UPDATES);
|
Purchase liveUpdatesPurchase = inventory.getPurchase(SKU_LIVE_UPDATES);
|
||||||
mSubscribedToLiveUpdates = (liveUpdatesPurchase != null);
|
mSubscribedToLiveUpdates = (liveUpdatesPurchase != null);
|
||||||
Log.d(TAG, "User " + (mSubscribedToLiveUpdates ? "HAS" : "DOES NOT HAVE")
|
logDebug("User " + (mSubscribedToLiveUpdates ? "HAS" : "DOES NOT HAVE")
|
||||||
+ " live updates purchased.");
|
+ " live updates purchased.");
|
||||||
|
|
||||||
if (inventory.hasDetails(SKU_LIVE_UPDATES)) {
|
if (inventory.hasDetails(SKU_LIVE_UPDATES)) {
|
||||||
|
@ -200,12 +192,12 @@ public class InAppHelper {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(TAG, "Initial inapp query finished");
|
logDebug("Initial inapp query finished");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public void purchaseLiveUpdates(final Activity activity, final String email, final String userName,
|
public void purchaseLiveUpdates(final Activity activity, final String email, final String userName,
|
||||||
final String countryDownloadName) {
|
final String countryDownloadName, final boolean hideUserName) {
|
||||||
if (!mHelper.subscriptionsSupported()) {
|
if (!mHelper.subscriptionsSupported()) {
|
||||||
complain("Subscriptions not supported on your device yet. Sorry!");
|
complain("Subscriptions not supported on your device yet. Sorry!");
|
||||||
if (callbacks != null) {
|
if (callbacks != null) {
|
||||||
|
@ -228,59 +220,56 @@ public class InAppHelper {
|
||||||
@Override
|
@Override
|
||||||
protected String doInBackground(Void... params) {
|
protected String doInBackground(Void... params) {
|
||||||
userId = ctx.getSettings().BILLING_USER_ID.get();
|
userId = ctx.getSettings().BILLING_USER_ID.get();
|
||||||
if (Algorithms.isEmpty(userId)) {
|
try {
|
||||||
try {
|
Map<String, String> parameters = new HashMap<>();
|
||||||
Map<String, String> parameters = new HashMap<>();
|
parameters.put("visibleName", hideUserName ? "" : userName);
|
||||||
parameters.put("visibleName", userName);
|
parameters.put("preferredCountry", countryDownloadName);
|
||||||
parameters.put("preferredCountry", countryDownloadName);
|
parameters.put("email", email);
|
||||||
parameters.put("email", email);
|
if (Algorithms.isEmpty(userId)) {
|
||||||
parameters.put("status", "new");
|
parameters.put("status", "new");
|
||||||
|
|
||||||
return sendRequest("http://download.osmand.net/subscription/register.php",
|
|
||||||
parameters, "Requesting userId...");
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "sendRequest Error", e);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
return AndroidNetworkUtils.sendRequest(ctx,
|
||||||
|
"http://download.osmand.net/subscription/register.php",
|
||||||
|
parameters, "Requesting userId...");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logError("sendRequest Error", e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(String response) {
|
protected void onPostExecute(String response) {
|
||||||
if (Algorithms.isEmpty(userId)) {
|
logDebug("Response=" + response);
|
||||||
Log.d(TAG, "Response=" + response);
|
if (response == null) {
|
||||||
if (response == null) {
|
complain("Cannot retrieve userId from server.");
|
||||||
complain("Cannot retrieve userId from server.");
|
if (callbacks != null) {
|
||||||
|
callbacks.dismissProgress();
|
||||||
|
callbacks.onError("Cannot retrieve userId from server.");
|
||||||
|
}
|
||||||
|
if (stopAfterResult) {
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
JSONObject obj = new JSONObject(response);
|
||||||
|
userId = obj.getString("userid");
|
||||||
|
ctx.getSettings().BILLING_USER_ID.set(userId);
|
||||||
|
logDebug("UserId=" + userId);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
String message = "JSON parsing error: "
|
||||||
|
+ (e.getMessage() == null ? "unknown" : e.getMessage());
|
||||||
|
complain(message);
|
||||||
if (callbacks != null) {
|
if (callbacks != null) {
|
||||||
callbacks.dismissProgress();
|
callbacks.dismissProgress();
|
||||||
callbacks.onError("Cannot retrieve userId from server.");
|
callbacks.onError(message);
|
||||||
}
|
}
|
||||||
if (stopAfterResult) {
|
if (stopAfterResult) {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
JSONObject obj = new JSONObject(response);
|
|
||||||
userId = obj.getString("userid");
|
|
||||||
ctx.getSettings().BILLING_USER_ID.set(userId);
|
|
||||||
Log.d(TAG, "UserId=" + userId);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
String message = "JSON parsing error: "
|
|
||||||
+ (e.getMessage() == null ? "unknown" : e.getMessage());
|
|
||||||
complain(message);
|
|
||||||
if (callbacks != null) {
|
|
||||||
callbacks.dismissProgress();
|
|
||||||
callbacks.onError(message);
|
|
||||||
}
|
|
||||||
if (stopAfterResult) {
|
|
||||||
stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +277,7 @@ public class InAppHelper {
|
||||||
callbacks.dismissProgress();
|
callbacks.dismissProgress();
|
||||||
}
|
}
|
||||||
if (!Algorithms.isEmpty(userId)) {
|
if (!Algorithms.isEmpty(userId)) {
|
||||||
Log.d(TAG, "Launching purchase flow for live updates subscription for userId=" + userId);
|
logDebug("Launching purchase flow for live updates subscription for userId=" + userId);
|
||||||
String payload = userId;
|
String payload = userId;
|
||||||
if (mHelper != null) {
|
if (mHelper != null) {
|
||||||
mHelper.launchPurchaseFlow(activity,
|
mHelper.launchPurchaseFlow(activity,
|
||||||
|
@ -308,26 +297,31 @@ public class InAppHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onActivityResultHandled(int requestCode, int resultCode, Intent data) {
|
public boolean onActivityResultHandled(int requestCode, int resultCode, Intent data) {
|
||||||
Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data);
|
logDebug("onActivityResult(" + requestCode + "," + resultCode + "," + data);
|
||||||
if (mHelper == null) return false;
|
if (mHelper == null) return false;
|
||||||
|
|
||||||
// Pass on the activity result to the helper for handling
|
try {
|
||||||
if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
|
// Pass on the activity result to the helper for handling
|
||||||
// not handled, so handle it ourselves (here's where you'd
|
if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
|
||||||
// perform any handling of activity results not related to in-app
|
// not handled, so handle it ourselves (here's where you'd
|
||||||
// billing...
|
// perform any handling of activity results not related to in-app
|
||||||
//super.onActivityResult(requestCode, resultCode, data);
|
// billing...
|
||||||
|
//super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
logDebug("onActivityResult handled by IABUtil.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logError("onActivityResultHandled", e);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
|
||||||
Log.d(TAG, "onActivityResult handled by IABUtil.");
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback for when a purchase is finished
|
// Callback for when a purchase is finished
|
||||||
private IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
|
private IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
|
||||||
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
|
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
|
||||||
Log.d(TAG, "Purchase finished: " + result + ", purchase: " + purchase);
|
logDebug("Purchase finished: " + result + ", purchase: " + purchase);
|
||||||
|
|
||||||
// if we were disposed of in the meantime, quit.
|
// if we were disposed of in the meantime, quit.
|
||||||
if (mHelper == null) return;
|
if (mHelper == null) return;
|
||||||
|
@ -344,15 +338,17 @@ public class InAppHelper {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(TAG, "Purchase successful.");
|
logDebug("Purchase successful.");
|
||||||
|
|
||||||
if (purchase.getSku().equals(SKU_LIVE_UPDATES)) {
|
if (purchase.getSku().equals(SKU_LIVE_UPDATES)) {
|
||||||
// bought live updates
|
// bought live updates
|
||||||
sendToken(purchase.getToken());
|
sendToken(purchase.getToken());
|
||||||
|
|
||||||
Log.d(TAG, "Live updates subscription purchased.");
|
logDebug("Live updates subscription purchased.");
|
||||||
showToast("Thank you for subscribing to live updates!");
|
showToast(ctx.getString(R.string.osm_live_thanks));
|
||||||
mSubscribedToLiveUpdates = true;
|
mSubscribedToLiveUpdates = true;
|
||||||
|
ctx.getSettings().LIVE_UPDATES_PURCHASED.set(true);
|
||||||
|
|
||||||
if (callbacks != null) {
|
if (callbacks != null) {
|
||||||
callbacks.dismissProgress();
|
callbacks.dismissProgress();
|
||||||
callbacks.onItemPurchased(SKU_LIVE_UPDATES);
|
callbacks.onItemPurchased(SKU_LIVE_UPDATES);
|
||||||
|
@ -366,7 +362,7 @@ public class InAppHelper {
|
||||||
|
|
||||||
// Do not forget call stop() when helper is not needed anymore
|
// Do not forget call stop() when helper is not needed anymore
|
||||||
public void stop() {
|
public void stop() {
|
||||||
Log.d(TAG, "Destroying helper.");
|
logDebug("Destroying helper.");
|
||||||
if (mHelper != null) {
|
if (mHelper != null) {
|
||||||
mHelper.dispose();
|
mHelper.dispose();
|
||||||
mHelper = null;
|
mHelper = null;
|
||||||
|
@ -378,27 +374,35 @@ public class InAppHelper {
|
||||||
String email = ctx.getSettings().BILLING_USER_EMAIL.get();
|
String email = ctx.getSettings().BILLING_USER_EMAIL.get();
|
||||||
try {
|
try {
|
||||||
Map<String, String> parameters = new HashMap<>();
|
Map<String, String> parameters = new HashMap<>();
|
||||||
parameters.put("userId", userId);
|
parameters.put("userid", userId);
|
||||||
parameters.put("sku", SKU_LIVE_UPDATES);
|
parameters.put("sku", SKU_LIVE_UPDATES);
|
||||||
parameters.put("purchaseToken", token);
|
parameters.put("purchaseToken", token);
|
||||||
parameters.put("email", email);
|
parameters.put("email", email);
|
||||||
|
|
||||||
sendRequestAsync("http://download.osmand.net/subscription/purchased.php",
|
AndroidNetworkUtils.sendRequestAsync(ctx,
|
||||||
|
"http://download.osmand.net/subscription/purchased.php",
|
||||||
parameters, "Sending purchase info...", new OnRequestResultListener() {
|
parameters, "Sending purchase info...", new OnRequestResultListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onResult(String result) {
|
public void onResult(String result) {
|
||||||
if (result != null && result.trim().toLowerCase().equals("ok")) {
|
if (result != null) {
|
||||||
ctx.getSettings().BILLING_PURCHASE_TOKEN_SENT.set(true);
|
try {
|
||||||
|
JSONObject obj = new JSONObject(result);
|
||||||
|
if (!obj.has("error")) {
|
||||||
|
ctx.getSettings().BILLING_PURCHASE_TOKEN_SENT.set(true);
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
logError("sendToken", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "sendToken Error", e);
|
logError("sendToken Error", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void complain(String message) {
|
private void complain(String message) {
|
||||||
Log.e(TAG, "**** InAppHelper Error: " + message);
|
logError("**** InAppHelper Error: " + message);
|
||||||
showToast("Error: " + message);
|
showToast("Error: " + message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,124 +410,16 @@ public class InAppHelper {
|
||||||
ctx.showToastMessage(message);
|
ctx.showToastMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String sendRequest(String url, Map<String, String> parameters, String userOperation) {
|
void logDebug(String msg) {
|
||||||
Log.d(TAG, "Sending request " + url);
|
if (mDebugLog) Log.d(TAG, msg);
|
||||||
HttpURLConnection connection = null;
|
|
||||||
try {
|
|
||||||
connection = NetworkUtils.getHttpURLConnection(url);
|
|
||||||
|
|
||||||
connection.setRequestProperty("Accept-Charset", "UTF-8");
|
|
||||||
connection.setRequestProperty("User-Agent", Version.getFullVersion(ctx));
|
|
||||||
connection.setConnectTimeout(15000);
|
|
||||||
|
|
||||||
if (parameters != null && parameters.size() > 0) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (Map.Entry<String, String> entry : parameters.entrySet()) {
|
|
||||||
if (sb.length() > 0) {
|
|
||||||
sb.append("&");
|
|
||||||
}
|
|
||||||
sb.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), "UTF-8"));
|
|
||||||
}
|
|
||||||
String params = sb.toString();
|
|
||||||
|
|
||||||
connection.setDoInput(true);
|
|
||||||
connection.setDoOutput(true);
|
|
||||||
connection.setUseCaches(false);
|
|
||||||
connection.setRequestMethod("POST");
|
|
||||||
|
|
||||||
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
|
|
||||||
connection.setRequestProperty("Content-Length", String.valueOf(params.getBytes("UTF-8").length));
|
|
||||||
connection.setFixedLengthStreamingMode(params.getBytes("UTF-8").length);
|
|
||||||
|
|
||||||
OutputStream output = new BufferedOutputStream(connection.getOutputStream());
|
|
||||||
output.write(params.getBytes("UTF-8"));
|
|
||||||
output.flush();
|
|
||||||
output.close();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
connection.setRequestMethod("GET");
|
|
||||||
connection.connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
|
|
||||||
String msg = userOperation
|
|
||||||
+ " " + ctx.getString(R.string.failed_op) + " : " + connection.getResponseMessage();
|
|
||||||
Log.e(TAG, msg);
|
|
||||||
showToast(msg);
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Response : " + connection.getResponseMessage());
|
|
||||||
// populate return fields.
|
|
||||||
StringBuilder responseBody = new StringBuilder();
|
|
||||||
responseBody.setLength(0);
|
|
||||||
InputStream i = connection.getInputStream();
|
|
||||||
if (i != null) {
|
|
||||||
BufferedReader in = new BufferedReader(new InputStreamReader(i, "UTF-8"), 256);
|
|
||||||
String s;
|
|
||||||
boolean f = true;
|
|
||||||
while ((s = in.readLine()) != null) {
|
|
||||||
if (!f) {
|
|
||||||
responseBody.append("\n");
|
|
||||||
} else {
|
|
||||||
f = false;
|
|
||||||
}
|
|
||||||
responseBody.append(s);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
in.close();
|
|
||||||
i.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "sendRequest", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return responseBody.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (NullPointerException e) {
|
|
||||||
// that's tricky case why NPE is thrown to fix that problem httpClient could be used
|
|
||||||
String msg = ctx.getString(R.string.auth_failed);
|
|
||||||
Log.e(TAG, msg, e);
|
|
||||||
showToast(msg);
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
Log.e(TAG, userOperation + " " + ctx.getString(R.string.failed_op), e);
|
|
||||||
showToast(MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
|
|
||||||
+ ": " + ctx.getResources().getString(R.string.shared_string_unexpected_error), userOperation));
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, userOperation + " " + ctx.getString(R.string.failed_op), e);
|
|
||||||
showToast(MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
|
|
||||||
+ ": " + ctx.getResources().getString(R.string.shared_string_io_error), userOperation));
|
|
||||||
} finally {
|
|
||||||
if (connection != null) {
|
|
||||||
connection.disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendRequestAsync(final String url, final Map<String, String> parameters, final String userOperation, final OnRequestResultListener listener) {
|
void logError(String msg) {
|
||||||
|
Log.e(TAG, "Error: " + msg);
|
||||||
new AsyncTask<Void, Void, String>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String doInBackground(Void... params) {
|
|
||||||
try {
|
|
||||||
return sendRequest(url, parameters, userOperation);
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(String response) {
|
|
||||||
if (listener != null) {
|
|
||||||
listener.onResult(response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}.execute((Void) null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private interface OnRequestResultListener {
|
void logError(String msg, Throwable e) {
|
||||||
void onResult(String result);
|
Log.e(TAG, "Error: " + msg, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import net.osmand.plus.R;
|
||||||
import net.osmand.plus.base.BaseOsmAndDialogFragment;
|
import net.osmand.plus.base.BaseOsmAndDialogFragment;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
@ -185,7 +186,7 @@ public class CountrySelectionFragment extends BaseOsmAndDialogFragment {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CountryItem {
|
public static class CountryItem implements Serializable {
|
||||||
private String localName;
|
private String localName;
|
||||||
private String downloadName;
|
private String downloadName;
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,23 @@ package net.osmand.plus.liveupdates;
|
||||||
import android.app.AlarmManager;
|
import android.app.AlarmManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.DrawableRes;
|
import android.support.annotation.DrawableRes;
|
||||||
import android.support.v4.app.FragmentManager;
|
import android.support.v4.app.FragmentManager;
|
||||||
|
import android.support.v4.view.MenuItemCompat;
|
||||||
|
import android.support.v7.app.ActionBar;
|
||||||
import android.support.v7.widget.SwitchCompat;
|
import android.support.v7.widget.SwitchCompat;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.SubMenu;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.AbsListView;
|
import android.widget.AbsListView;
|
||||||
|
@ -57,6 +65,7 @@ import static net.osmand.plus.liveupdates.LiveUpdatesHelper.setAlarmForPendingIn
|
||||||
|
|
||||||
public class LiveUpdatesFragment extends BaseOsmAndFragment {
|
public class LiveUpdatesFragment extends BaseOsmAndFragment {
|
||||||
public static final String TITLE = "Live Updates";
|
public static final String TITLE = "Live Updates";
|
||||||
|
private static final int SUBSCRIPTION_SETTINGS = 5;
|
||||||
public static final Comparator<LocalIndexInfo> LOCAL_INDEX_INFO_COMPARATOR = new Comparator<LocalIndexInfo>() {
|
public static final Comparator<LocalIndexInfo> LOCAL_INDEX_INFO_COMPARATOR = new Comparator<LocalIndexInfo>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(LocalIndexInfo lhs, LocalIndexInfo rhs) {
|
public int compare(LocalIndexInfo lhs, LocalIndexInfo rhs) {
|
||||||
|
@ -71,6 +80,7 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment {
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
setHasOptionsMenu(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -94,27 +104,32 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//test
|
||||||
|
//getSettings().LIVE_UPDATES_PURCHASED.set(true);
|
||||||
|
|
||||||
subscriptionHeader = inflater.inflate(R.layout.live_updates_header, listView, false);
|
subscriptionHeader = inflater.inflate(R.layout.live_updates_header, listView, false);
|
||||||
|
updateHeader();
|
||||||
|
|
||||||
|
listView.addHeaderView(subscriptionHeader);
|
||||||
|
|
||||||
|
loadLocalIndexesTask = new LoadLocalIndexTask(adapter, this).execute();
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateHeader() {
|
||||||
View subscriptionBanner = subscriptionHeader.findViewById(R.id.subscription_banner);
|
View subscriptionBanner = subscriptionHeader.findViewById(R.id.subscription_banner);
|
||||||
View subscriptionInfo = subscriptionHeader.findViewById(R.id.subscription_info);
|
View subscriptionInfo = subscriptionHeader.findViewById(R.id.subscription_info);
|
||||||
Button subscriptionButton = (Button) subscriptionHeader.findViewById(R.id.subscription_button);
|
if (getSettings().LIVE_UPDATES_PURCHASED.get()) {
|
||||||
subscriptionButton.setOnClickListener(new View.OnClickListener() {
|
ImageView statusIcon = (ImageView) subscriptionHeader.findViewById(R.id.statusIcon);
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
SubscriptionFragment subscriptionFragment = new SubscriptionFragment();
|
|
||||||
subscriptionFragment.show(getChildFragmentManager(), SubscriptionFragment.TAG);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (InAppHelper.isSubscribedToLiveUpdates()) {
|
|
||||||
TextView statusTextView = (TextView) subscriptionHeader.findViewById(R.id.statusTextView);
|
TextView statusTextView = (TextView) subscriptionHeader.findViewById(R.id.statusTextView);
|
||||||
TextView regionNameTextView = (TextView) subscriptionHeader.findViewById(R.id.regionTextView);
|
TextView regionNameTextView = (TextView) subscriptionHeader.findViewById(R.id.regionTextView);
|
||||||
TextView emailTextView = (TextView) subscriptionHeader.findViewById(R.id.emailTextView);
|
|
||||||
TextView userNameTextView = (TextView) subscriptionHeader.findViewById(R.id.userNameTextView);
|
|
||||||
|
|
||||||
if (InAppHelper.isSubscribedToLiveUpdates()) {
|
if (InAppHelper.isSubscribedToLiveUpdates()) {
|
||||||
statusTextView.setText(getString(R.string.osm_live_active));
|
statusTextView.setText(getString(R.string.osm_live_active));
|
||||||
|
statusIcon.setImageDrawable(getMyApplication().getIconsCache().getContentIcon(R.drawable.ic_action_done));
|
||||||
} else {
|
} else {
|
||||||
statusTextView.setText(getString(R.string.osm_live_not_active));
|
statusTextView.setText(getString(R.string.osm_live_not_active));
|
||||||
|
statusIcon.setImageDrawable(getMyApplication().getIconsCache().getContentIcon(R.drawable.ic_action_remove_dark));
|
||||||
}
|
}
|
||||||
|
|
||||||
OsmandSettings settings = getMyApplication().getSettings();
|
OsmandSettings settings = getMyApplication().getSettings();
|
||||||
|
@ -126,19 +141,39 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment {
|
||||||
}
|
}
|
||||||
regionNameTextView.setText(countryName);
|
regionNameTextView.setText(countryName);
|
||||||
|
|
||||||
emailTextView.setText(settings.BILLING_USER_EMAIL.get());
|
Button subscribeButton = (Button) subscriptionHeader.findViewById(R.id.subscribeButton);
|
||||||
userNameTextView.setText(settings.BILLING_USER_NAME.get());
|
subscribeButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
SubscriptionFragment subscriptionFragment = new SubscriptionFragment();
|
||||||
|
subscriptionFragment.show(getChildFragmentManager(), SubscriptionFragment.TAG);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
subscriptionBanner.setVisibility(View.GONE);
|
subscriptionBanner.setVisibility(View.GONE);
|
||||||
subscriptionInfo.setVisibility(View.VISIBLE);
|
subscriptionInfo.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
|
Button readMoreBtn = (Button) subscriptionHeader.findViewById(R.id.read_more_button);
|
||||||
|
readMoreBtn.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Uri uri = Uri.parse("http://osmand.net/osm_live.php");
|
||||||
|
Intent goToOsmLive = new Intent(Intent.ACTION_VIEW, uri);
|
||||||
|
startActivity(goToOsmLive);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Button subscriptionButton = (Button) subscriptionHeader.findViewById(R.id.subscription_button);
|
||||||
|
subscriptionButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
SubscriptionFragment subscriptionFragment = new SubscriptionFragment();
|
||||||
|
subscriptionFragment.show(getChildFragmentManager(), SubscriptionFragment.TAG);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
subscriptionBanner.setVisibility(View.VISIBLE);
|
subscriptionBanner.setVisibility(View.VISIBLE);
|
||||||
subscriptionInfo.setVisibility(View.GONE);
|
subscriptionInfo.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
listView.addHeaderView(subscriptionHeader);
|
|
||||||
|
|
||||||
loadLocalIndexesTask = new LoadLocalIndexTask(adapter, this).execute();
|
|
||||||
return view;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateSubscriptionBanner() {
|
public void updateSubscriptionBanner() {
|
||||||
|
@ -165,6 +200,34 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||||
|
if (getSettings().LIVE_UPDATES_PURCHASED.get()) {
|
||||||
|
ActionBar actionBar = getMyActivity().getSupportActionBar();
|
||||||
|
if (actionBar != null) {
|
||||||
|
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
|
||||||
|
}
|
||||||
|
|
||||||
|
SubMenu split = menu.addSubMenu(R.string.shared_string_more_actions);
|
||||||
|
split.setIcon(R.drawable.ic_overflow_menu_white);
|
||||||
|
MenuItemCompat.setShowAsAction(split.getItem(), MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
|
||||||
|
MenuItem item = split.add(0, SUBSCRIPTION_SETTINGS, 0, R.string.osm_live_subscription_settings);
|
||||||
|
MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
if (item.getItemId() == SUBSCRIPTION_SETTINGS) {
|
||||||
|
SubscriptionFragment subscriptionFragment = new SubscriptionFragment();
|
||||||
|
subscriptionFragment.setEditMode(true);
|
||||||
|
subscriptionFragment.show(getChildFragmentManager(), SubscriptionFragment.TAG);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
|
||||||
protected class LocalIndexesAdapter extends OsmandBaseExpandableListAdapter {
|
protected class LocalIndexesAdapter extends OsmandBaseExpandableListAdapter {
|
||||||
public static final int SHOULD_UPDATE_GROUP_POSITION = 0;
|
public static final int SHOULD_UPDATE_GROUP_POSITION = 0;
|
||||||
public static final int SHOULD_NOT_UPDATE_GROUP_POSITION = 1;
|
public static final int SHOULD_NOT_UPDATE_GROUP_POSITION = 1;
|
||||||
|
@ -382,6 +445,7 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment {
|
||||||
divider = view.findViewById(R.id.divider);
|
divider = view.findViewById(R.id.divider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public void bindLocalIndexInfo(final LocalIndexInfo item, boolean isLastChild) {
|
public void bindLocalIndexInfo(final LocalIndexInfo item, boolean isLastChild) {
|
||||||
OsmandApplication context = fragment.getMyActivity().getMyApplication();
|
OsmandApplication context = fragment.getMyActivity().getMyApplication();
|
||||||
final OsmandSettings.CommonPreference<Boolean> shouldUpdatePreference =
|
final OsmandSettings.CommonPreference<Boolean> shouldUpdatePreference =
|
||||||
|
@ -448,7 +512,7 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment {
|
||||||
extends AsyncTask<Void, LocalIndexInfo, List<LocalIndexInfo>>
|
extends AsyncTask<Void, LocalIndexInfo, List<LocalIndexInfo>>
|
||||||
implements AbstractLoadLocalIndexTask {
|
implements AbstractLoadLocalIndexTask {
|
||||||
|
|
||||||
private List<LocalIndexInfo> result;
|
//private List<LocalIndexInfo> result;
|
||||||
private LocalIndexesAdapter adapter;
|
private LocalIndexesAdapter adapter;
|
||||||
private LiveUpdatesFragment fragment;
|
private LiveUpdatesFragment fragment;
|
||||||
private LocalIndexHelper helper;
|
private LocalIndexHelper helper;
|
||||||
|
@ -484,7 +548,7 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(List<LocalIndexInfo> result) {
|
protected void onPostExecute(List<LocalIndexInfo> result) {
|
||||||
this.result = result;
|
//this.result = result;
|
||||||
adapter.sort();
|
adapter.sort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import android.app.Activity;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
@ -15,7 +16,9 @@ import android.widget.ImageButton;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import net.osmand.AndroidNetworkUtils;
|
||||||
import net.osmand.AndroidUtils;
|
import net.osmand.AndroidUtils;
|
||||||
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.OsmandSettings;
|
import net.osmand.plus.OsmandSettings;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
import net.osmand.plus.base.BaseOsmAndDialogFragment;
|
import net.osmand.plus.base.BaseOsmAndDialogFragment;
|
||||||
|
@ -25,40 +28,104 @@ import net.osmand.plus.liveupdates.CountrySelectionFragment.CountryItem;
|
||||||
import net.osmand.plus.liveupdates.CountrySelectionFragment.OnFragmentInteractionListener;
|
import net.osmand.plus.liveupdates.CountrySelectionFragment.OnFragmentInteractionListener;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class SubscriptionFragment extends BaseOsmAndDialogFragment implements InAppCallbacks, OnFragmentInteractionListener {
|
public class SubscriptionFragment extends BaseOsmAndDialogFragment implements InAppCallbacks, OnFragmentInteractionListener {
|
||||||
|
|
||||||
public static final String TAG = "SubscriptionFragment";
|
public static final String TAG = "SubscriptionFragment";
|
||||||
|
private static final String EDIT_MODE_ID = "edit_mode_id";
|
||||||
|
private static final String USER_NAME_ID = "user_name_id";
|
||||||
|
private static final String EMAIL_ID = "email_id";
|
||||||
|
private static final String COUNTRY_ITEM_ID = "country_id";
|
||||||
|
private static final String HIDE_USER_NAME_ID = "hide_user_name_id";
|
||||||
|
|
||||||
private InAppHelper inAppHelper;
|
private InAppHelper inAppHelper;
|
||||||
private OsmandSettings settings;
|
private OsmandSettings settings;
|
||||||
private ProgressDialog dlg;
|
private ProgressDialog dlg;
|
||||||
|
private boolean editMode;
|
||||||
|
|
||||||
private String userName;
|
private String prevEmail;
|
||||||
private String email;
|
|
||||||
private CountryItem selectedCountryItem;
|
private CountryItem selectedCountryItem;
|
||||||
|
|
||||||
private CountrySelectionFragment countrySelectionFragment = new CountrySelectionFragment();
|
private CountrySelectionFragment countrySelectionFragment = new CountrySelectionFragment();
|
||||||
|
|
||||||
|
public void setEditMode(boolean editMode) {
|
||||||
|
this.editMode = editMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
|
outState.putBoolean(EDIT_MODE_ID, editMode);
|
||||||
|
|
||||||
|
View view = getView();
|
||||||
|
if (view != null) {
|
||||||
|
EditText userNameEdit = (EditText) view.findViewById(R.id.userNameEdit);
|
||||||
|
outState.putString(USER_NAME_ID, userNameEdit.getText().toString());
|
||||||
|
EditText emailEdit = (EditText) view.findViewById(R.id.emailEdit);
|
||||||
|
outState.putString(EMAIL_ID, emailEdit.getText().toString());
|
||||||
|
CheckBox hideUserNameCheckbox = (CheckBox) view.findViewById(R.id.hideUserNameCheckbox);
|
||||||
|
outState.putBoolean(HIDE_USER_NAME_ID, hideUserNameCheckbox.isChecked());
|
||||||
|
if (selectedCountryItem != null) {
|
||||||
|
outState.putSerializable(COUNTRY_ITEM_ID, selectedCountryItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
settings = getMyApplication().getSettings();
|
if (savedInstanceState != null) {
|
||||||
inAppHelper = new InAppHelper(getMyApplication(), this);
|
editMode = savedInstanceState.getBoolean(EDIT_MODE_ID);
|
||||||
Activity activity = getActivity();
|
|
||||||
if (activity instanceof OsmLiveActivity) {
|
|
||||||
((OsmLiveActivity) activity).setInAppHelper(inAppHelper);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inAppHelper.start(false);
|
settings = getMyApplication().getSettings();
|
||||||
|
prevEmail = settings.BILLING_USER_EMAIL.get();
|
||||||
|
if (!editMode) {
|
||||||
|
inAppHelper = new InAppHelper(getMyApplication(), this);
|
||||||
|
Activity activity = getActivity();
|
||||||
|
if (activity instanceof OsmLiveActivity) {
|
||||||
|
((OsmLiveActivity) activity).setInAppHelper(inAppHelper);
|
||||||
|
}
|
||||||
|
inAppHelper.start(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
|
|
||||||
|
String userName = settings.BILLING_USER_NAME.get();
|
||||||
|
String email = settings.BILLING_USER_EMAIL.get();
|
||||||
|
String countryDownloadName = settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.get();
|
||||||
|
boolean hideUserName = settings.BILLING_HIDE_USER_NAME.get();
|
||||||
|
|
||||||
|
if (savedInstanceState != null) {
|
||||||
|
userName = savedInstanceState.getString(USER_NAME_ID);
|
||||||
|
email = savedInstanceState.getString(EMAIL_ID);
|
||||||
|
hideUserName = savedInstanceState.getBoolean(HIDE_USER_NAME_ID);
|
||||||
|
Object obj = savedInstanceState.getSerializable(COUNTRY_ITEM_ID);
|
||||||
|
if (obj instanceof CountryItem) {
|
||||||
|
selectedCountryItem = (CountryItem) obj;
|
||||||
|
countryDownloadName = selectedCountryItem.getDownloadName();
|
||||||
|
} else {
|
||||||
|
countryDownloadName = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
View view = inflater.inflate(R.layout.subscription_fragment, container, false);
|
View view = inflater.inflate(R.layout.subscription_fragment, container, false);
|
||||||
ImageButton closeButton = (ImageButton) view.findViewById(R.id.closeButton);
|
ImageButton closeButton = (ImageButton) view.findViewById(R.id.closeButton);
|
||||||
|
if (editMode) {
|
||||||
|
closeButton.setImageDrawable(getMyApplication().getIconsCache().getIcon(R.drawable.ic_action_mode_back));
|
||||||
|
} else {
|
||||||
|
closeButton.setImageDrawable(getMyApplication().getIconsCache().getIcon(R.drawable.ic_action_remove_dark));
|
||||||
|
}
|
||||||
closeButton.setOnClickListener(new View.OnClickListener() {
|
closeButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
|
@ -66,20 +133,24 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
userName = settings.BILLING_USER_NAME.get();
|
TextView title = (TextView) view.findViewById(R.id.titleTextView);
|
||||||
|
if (editMode) {
|
||||||
|
title.setText(getString(R.string.osm_live_subscription_settings));
|
||||||
|
} else {
|
||||||
|
title.setText(getString(R.string.osm_live_subscription));
|
||||||
|
}
|
||||||
|
|
||||||
final EditText userNameEdit = (EditText) view.findViewById(R.id.userNameEdit);
|
final EditText userNameEdit = (EditText) view.findViewById(R.id.userNameEdit);
|
||||||
if (!Algorithms.isEmpty(userName)) {
|
if (!Algorithms.isEmpty(userName)) {
|
||||||
userNameEdit.setText(userName);
|
userNameEdit.setText(userName);
|
||||||
}
|
}
|
||||||
|
|
||||||
email = settings.BILLING_USER_EMAIL.get();
|
|
||||||
final EditText emailEdit = (EditText) view.findViewById(R.id.emailEdit);
|
final EditText emailEdit = (EditText) view.findViewById(R.id.emailEdit);
|
||||||
if (!Algorithms.isEmpty(email)) {
|
if (!Algorithms.isEmpty(email)) {
|
||||||
emailEdit.setText(email);
|
emailEdit.setText(email);
|
||||||
}
|
}
|
||||||
|
|
||||||
countrySelectionFragment.initCountries(getMyApplication());
|
countrySelectionFragment.initCountries(getMyApplication());
|
||||||
String countryDownloadName = settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.get();
|
|
||||||
if (Algorithms.isEmpty(countryDownloadName)) {
|
if (Algorithms.isEmpty(countryDownloadName)) {
|
||||||
selectedCountryItem = countrySelectionFragment.getCountryItems().get(0);
|
selectedCountryItem = countrySelectionFragment.getCountryItems().get(0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -103,40 +174,100 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
updatePrice(view);
|
|
||||||
|
|
||||||
final Button subscribeButton = (Button) view.findViewById(R.id.subscribeButton);
|
|
||||||
final CheckBox hideUserNameCheckbox = (CheckBox) view.findViewById(R.id.hideUserNameCheckbox);
|
final CheckBox hideUserNameCheckbox = (CheckBox) view.findViewById(R.id.hideUserNameCheckbox);
|
||||||
boolean hideUserName = settings.BILLING_HIDE_USER_NAME.get();
|
|
||||||
hideUserNameCheckbox.setChecked(hideUserName);
|
hideUserNameCheckbox.setChecked(hideUserName);
|
||||||
subscribeButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (inAppHelper != null) {
|
|
||||||
userName = userNameEdit.getText().toString().trim();
|
|
||||||
email = emailEdit.getText().toString().trim();
|
|
||||||
String countryName = selectedCountryItem != null ? selectedCountryItem.getLocalName() : "";
|
|
||||||
String countryDownloadName = selectedCountryItem != null ? selectedCountryItem.getDownloadName() : "";
|
|
||||||
|
|
||||||
if (Algorithms.isEmpty(email) || !AndroidUtils.isValidEmail(email)) {
|
View editModeBottomView = view.findViewById(R.id.editModeBottomView);
|
||||||
getMyApplication().showToastMessage("Please enter valid E-mail address");
|
View purchaseCard = view.findViewById(R.id.purchaseCard);
|
||||||
return;
|
if (editMode) {
|
||||||
|
editModeBottomView.setVisibility(View.VISIBLE);
|
||||||
|
purchaseCard.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
Button saveChangesButton = (Button) view.findViewById(R.id.saveChangesButton);
|
||||||
|
saveChangesButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (applySettings(userNameEdit.getText().toString().trim(),
|
||||||
|
emailEdit.getText().toString().trim(), hideUserNameCheckbox.isChecked())) {
|
||||||
|
|
||||||
|
final Map<String, String> parameters = new HashMap<>();
|
||||||
|
parameters.put("visibleName", settings.BILLING_HIDE_USER_NAME.get() ? "" : settings.BILLING_USER_NAME.get());
|
||||||
|
parameters.put("preferredCountry", settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.get());
|
||||||
|
parameters.put("email", settings.BILLING_USER_EMAIL.get());
|
||||||
|
parameters.put("cemail", prevEmail);
|
||||||
|
parameters.put("userid", settings.BILLING_USER_ID.get());
|
||||||
|
|
||||||
|
showProgress();
|
||||||
|
|
||||||
|
AndroidNetworkUtils.sendRequestAsync(getMyApplication(),
|
||||||
|
"http://download.osmand.net/subscription/update.php",
|
||||||
|
parameters, "Sending data...", new AndroidNetworkUtils.OnRequestResultListener() {
|
||||||
|
@Override
|
||||||
|
public void onResult(String result) {
|
||||||
|
dismissProgress();
|
||||||
|
OsmandApplication app = getMyApplication();
|
||||||
|
if (result != null) {
|
||||||
|
try {
|
||||||
|
JSONObject obj = new JSONObject(result);
|
||||||
|
if (!obj.has("error")) {
|
||||||
|
String userId = obj.getString("userid");
|
||||||
|
app.getSettings().BILLING_USER_ID.set(userId);
|
||||||
|
String email = obj.getString("email");
|
||||||
|
app.getSettings().BILLING_USER_EMAIL.set(email);
|
||||||
|
String visibleName = obj.getString("visibleName");
|
||||||
|
if (!Algorithms.isEmpty(visibleName)) {
|
||||||
|
app.getSettings().BILLING_USER_NAME.set(visibleName);
|
||||||
|
app.getSettings().BILLING_HIDE_USER_NAME.set(false);
|
||||||
|
} else {
|
||||||
|
app.getSettings().BILLING_HIDE_USER_NAME.set(true);
|
||||||
|
}
|
||||||
|
String preferredCountry = obj.getString("preferredCountry");
|
||||||
|
app.getSettings().BILLING_USER_COUNTRY_DOWNLOAD_NAME.set(preferredCountry);
|
||||||
|
|
||||||
|
Fragment parent = getParentFragment();
|
||||||
|
if (parent != null && parent instanceof LiveUpdatesFragment) {
|
||||||
|
((LiveUpdatesFragment) parent).updateHeader();
|
||||||
|
}
|
||||||
|
|
||||||
|
dismiss();
|
||||||
|
} else {
|
||||||
|
app.showToastMessage("Error: " + obj.getString("error"));
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
app.showToastMessage(getString(R.string.shared_string_io_error));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
app.showToastMessage(getString(R.string.shared_string_io_error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (Algorithms.isEmpty(userName) && !hideUserNameCheckbox.isChecked()) {
|
|
||||||
getMyApplication().showToastMessage("Please enter Public Name");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
settings.BILLING_USER_NAME.set(userName);
|
|
||||||
settings.BILLING_USER_EMAIL.set(email);
|
|
||||||
settings.BILLING_USER_COUNTRY.set(countryName);
|
|
||||||
settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.set(countryDownloadName);
|
|
||||||
settings.BILLING_HIDE_USER_NAME.set(hideUserNameCheckbox.isChecked());
|
|
||||||
|
|
||||||
inAppHelper.purchaseLiveUpdates(getActivity(), email, userName, countryDownloadName);
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
} else {
|
||||||
|
editModeBottomView.setVisibility(View.GONE);
|
||||||
|
purchaseCard.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
updatePrice(view);
|
||||||
|
final Button subscribeButton = (Button) view.findViewById(R.id.subscribeButton);
|
||||||
|
subscribeButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (inAppHelper != null) {
|
||||||
|
if (applySettings(userNameEdit.getText().toString().trim(),
|
||||||
|
emailEdit.getText().toString().trim(), hideUserNameCheckbox.isChecked())) {
|
||||||
|
|
||||||
|
inAppHelper.purchaseLiveUpdates(getActivity(),
|
||||||
|
settings.BILLING_USER_EMAIL.get(),
|
||||||
|
settings.BILLING_USER_NAME.get(),
|
||||||
|
settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.get(),
|
||||||
|
settings.BILLING_HIDE_USER_NAME.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
setThemedDrawable((ImageView) view.findViewById(R.id.userNameIcon), R.drawable.ic_person);
|
setThemedDrawable((ImageView) view.findViewById(R.id.userNameIcon), R.drawable.ic_person);
|
||||||
setThemedDrawable((ImageView) view.findViewById(R.id.emailIcon), R.drawable.ic_action_message);
|
setThemedDrawable((ImageView) view.findViewById(R.id.emailIcon), R.drawable.ic_action_message);
|
||||||
|
@ -150,7 +281,9 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
inAppHelper.stop();
|
if (inAppHelper != null) {
|
||||||
|
inAppHelper.stop();
|
||||||
|
}
|
||||||
if (dlg != null && dlg.isShowing()) {
|
if (dlg != null && dlg.isShowing()) {
|
||||||
dlg.hide();
|
dlg.hide();
|
||||||
}
|
}
|
||||||
|
@ -160,6 +293,28 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean applySettings(String userName, String email, boolean hideUserName) {
|
||||||
|
String countryName = selectedCountryItem != null ? selectedCountryItem.getLocalName() : "";
|
||||||
|
String countryDownloadName = selectedCountryItem != null ? selectedCountryItem.getDownloadName() : "";
|
||||||
|
|
||||||
|
if (Algorithms.isEmpty(email) || !AndroidUtils.isValidEmail(email)) {
|
||||||
|
getMyApplication().showToastMessage(getString(R.string.osm_live_enter_email));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Algorithms.isEmpty(userName) && !hideUserName) {
|
||||||
|
getMyApplication().showToastMessage(getString(R.string.osm_live_enter_user_name));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
settings.BILLING_USER_NAME.set(userName);
|
||||||
|
settings.BILLING_USER_EMAIL.set(email);
|
||||||
|
settings.BILLING_USER_COUNTRY.set(countryName);
|
||||||
|
settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.set(countryDownloadName);
|
||||||
|
settings.BILLING_HIDE_USER_NAME.set(hideUserName);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(String error) {
|
public void onError(String error) {
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue