Merge pull request #11078 from osmandapp/osmand_live
Redesign OsmAnd Live
This commit is contained in:
commit
b107c430df
33 changed files with 2302 additions and 378 deletions
|
@ -1064,7 +1064,7 @@
|
|||
|
||||
<activity android:name="net.osmand.plus.activities.PrintDialogActivity" />
|
||||
<activity android:name=".liveupdates.OsmLiveActivity"
|
||||
android:label="@string/osm_live"/>
|
||||
android:label="@string/purchases"/>
|
||||
<activity android:name=".wikivoyage.explore.WikivoyageExploreActivity">
|
||||
|
||||
<intent-filter>
|
||||
|
|
46
OsmAnd/res/layout/bottom_sheet_button_with_icon_center.xml
Normal file
46
OsmAnd/res/layout/bottom_sheet_button_with_icon_center.xml
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?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:id="@+id/button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dialog_button_height"
|
||||
android:layout_marginStart="@dimen/content_padding"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:layout_marginEnd="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/button_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="UselessParent">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/button_icon"
|
||||
android:layout_width="@dimen/map_widget_icon"
|
||||
android:layout_height="@dimen/map_widget_icon"
|
||||
android:layout_marginEnd="@dimen/content_padding_small"
|
||||
android:layout_marginRight="@dimen/content_padding_small"
|
||||
android:tint="?attr/active_color_basic"
|
||||
tools:srcCompat="@drawable/ic_action_appearance" />
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/button_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/context_menu_controller_height"
|
||||
android:layout_marginRight="@dimen/context_menu_controller_height"
|
||||
android:letterSpacing="@dimen/description_letter_spacing"
|
||||
android:textColor="?attr/active_color_basic"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:text="Button" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -13,11 +13,11 @@
|
|||
android:layout_marginEnd="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding"
|
||||
android:minHeight="@dimen/bottom_sheet_list_item_height"
|
||||
android:paddingStart="@dimen/content_padding"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
tools:background="@drawable/rectangle_rounded_right"
|
||||
android:paddingEnd="@dimen/content_padding"
|
||||
android:paddingStart="@dimen/content_padding">
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
tools:background="@drawable/rectangle_rounded_right">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/title"
|
||||
|
@ -41,7 +41,8 @@
|
|||
android:background="@null"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
android:focusableInTouchMode="false" />
|
||||
android:focusableInTouchMode="false"
|
||||
android:saveEnabled="false" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="@dimen/bottom_sheet_selected_item_title_height"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
android:paddingStart="@dimen/content_padding"
|
||||
android:paddingEnd="@dimen/content_padding">
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingEnd="@dimen/content_padding"
|
||||
android:paddingRight="@dimen/content_padding">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/icon"
|
||||
|
@ -53,11 +52,12 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="@dimen/bottom_sheet_content_margin"
|
||||
android:layout_marginStart="@dimen/bottom_sheet_content_margin"
|
||||
android:layout_marginLeft="@dimen/bottom_sheet_content_margin"
|
||||
android:background="@null"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
android:focusableInTouchMode="false"/>
|
||||
android:focusableInTouchMode="false"
|
||||
android:saveEnabled="false" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:minHeight="@dimen/bottom_sheet_selected_item_title_height"
|
||||
android:paddingStart="@dimen/content_padding"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingEnd="@dimen/content_padding"
|
||||
android:paddingRight="@dimen/content_padding">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
style="@style/TextAppearance.ListItemTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
tools:text="Some title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/description"
|
||||
style="@style/TextAppearance.ContextMenuSubtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:letterSpacing="@dimen/description_letter_spacing"
|
||||
android:maxLines="1"
|
||||
tools:text="Some description" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="@dimen/standard_icon_size"
|
||||
android:layout_height="@dimen/standard_icon_size"
|
||||
android:layout_gravity="center_vertical"
|
||||
tools:src="@drawable/list_destination" />
|
||||
|
||||
</LinearLayout>
|
|
@ -1,8 +1,49 @@
|
|||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/activity_background_color"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/app_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dashboard_map_toolbar"
|
||||
android:background="?attr/pstsTabBackground"
|
||||
android:minHeight="@dimen/dashboard_map_toolbar"
|
||||
android:theme="?attr/toolbar_theme"
|
||||
app:contentInsetEnd="0dp"
|
||||
app:contentInsetLeft="@dimen/settings_divider_margin_start"
|
||||
app:contentInsetRight="0dp"
|
||||
app:contentInsetStart="@dimen/settings_divider_margin_start">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/toolbar_action"
|
||||
android:layout_width="@dimen/standard_icon_size"
|
||||
android:layout_height="@dimen/standard_icon_size"
|
||||
android:layout_gravity="end"
|
||||
android:layout_marginTop="@dimen/content_padding"
|
||||
android:layout_marginEnd="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding"
|
||||
android:layout_marginBottom="@dimen/content_padding"
|
||||
android:background="@null"
|
||||
android:contentDescription="@string/shared_string_help"
|
||||
tools:src="@drawable/ic_action_help" />
|
||||
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
|
||||
<include layout="@layout/preference_toolbar_switch" />
|
||||
|
||||
<include layout="@layout/list_item_import" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/swipe_refresh"
|
||||
|
@ -19,18 +60,8 @@
|
|||
android:groupIndicator="@null"
|
||||
android:headerDividersEnabled="false"
|
||||
android:orientation="vertical"
|
||||
tools:context=".liveupdates.LiveUpdatesFragment" />
|
||||
tools:context=".liveupdates.LiveUpdatesFragmentNew" />
|
||||
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp"
|
||||
android:layout_gravity="top"
|
||||
android:indeterminate="true"
|
||||
android:padding="0dp"
|
||||
android:visibility="invisible"/>
|
||||
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
57
OsmAnd/res/layout/list_group_title_with_right_descr.xml
Normal file
57
OsmAnd/res/layout/list_group_title_with_right_descr.xml
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/context_menu_action_buttons_height"
|
||||
android:clickable="false"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include layout="@layout/card_bottom_divider" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<include layout="@layout/card_top_divider" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/setting_list_item_small_height"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:background="?attr/bg_color"
|
||||
android:gravity="center_vertical|start"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/content_padding"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingTop="@dimen/content_padding_small"
|
||||
android:paddingEnd="@dimen/content_padding"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
android:paddingBottom="@dimen/content_padding_small_half">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/title"
|
||||
style="@style/TextAppearance.ListItemCategoryTitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
tools:text="@string/available_maps" />
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="@dimen/content_padding"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:paddingStart="@dimen/subHeaderMarginLeft"
|
||||
android:paddingLeft="@dimen/subHeaderMarginLeft"
|
||||
android:paddingEnd="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
tools:text="2/6"
|
||||
tools:textColor="@color/text_color_secondary_dark" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -13,6 +13,7 @@
|
|||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/item_import_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
android:layout_marginStart="@dimen/content_padding">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/text_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="@dimen/context_menu_action_buttons_height"
|
||||
|
|
95
OsmAnd/res/layout/list_item_triple_row_icon_and_menu.xml
Normal file
95
OsmAnd/res/layout/list_item_triple_row_icon_and_menu.xml
Normal file
|
@ -0,0 +1,95 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/bg_color"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="@dimen/setting_list_item_large_height"
|
||||
tools:layout_height="@dimen/list_item_triple_row_height">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="@dimen/standard_icon_size"
|
||||
android:layout_height="@dimen/standard_icon_size"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="@dimen/content_padding"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:layout_marginEnd="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding"
|
||||
tools:src="@drawable/ic_action_info_dark"
|
||||
tools:tint="@color/icon_color_osmand_light" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="@dimen/content_padding"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:textAppearance="@style/TextAppearance.ListItemTitle"
|
||||
tools:text="Title" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/sub_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:letterSpacing="@dimen/description_letter_spacing"
|
||||
android:lines="1"
|
||||
android:textColor="?attr/active_color_basic"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
tools:text="Sub" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:letterSpacing="@dimen/description_letter_spacing"
|
||||
android:lines="1"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
tools:text="Description" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/secondary_icon"
|
||||
android:layout_width="@dimen/standard_icon_size"
|
||||
android:layout_height="@dimen/standard_icon_size"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="@dimen/content_padding"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
app:srcCompat="@drawable/ic_action_additional_option"
|
||||
app:tint="?attr/default_icon_color" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/compound_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/content_padding"
|
||||
android:layout_marginLeft="@dimen/content_padding"
|
||||
android:layout_marginEnd="@dimen/content_padding"
|
||||
android:layout_marginRight="@dimen/content_padding"
|
||||
android:focusable="false"
|
||||
tools:checked="true" />
|
||||
|
||||
</LinearLayout>
|
|
@ -1,32 +1,26 @@
|
|||
<?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"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:descendantFocusability="blocksDescendants"
|
||||
android:minHeight="@dimen/list_item_height"
|
||||
android:paddingTop="@dimen/content_padding_half"
|
||||
android:paddingBottom="@dimen/content_padding_half"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/list_background_color"
|
||||
android:minHeight="@dimen/list_item_height"
|
||||
android:paddingLeft="@dimen/list_content_padding"
|
||||
android:paddingRight="@dimen/list_content_padding"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/list_content_padding"
|
||||
android:paddingEnd="@dimen/list_content_padding">
|
||||
android:paddingLeft="@dimen/list_content_padding"
|
||||
android:paddingTop="@dimen/content_padding"
|
||||
android:paddingEnd="@dimen/list_content_padding"
|
||||
android:paddingRight="@dimen/list_content_padding"
|
||||
android:paddingBottom="@dimen/content_padding">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/favorites_icon_right_margin"
|
||||
android:layout_marginRight="@dimen/favorites_icon_right_margin"
|
||||
android:paddingTop="6dp"
|
||||
android:tint="@color/map_widget_blue"
|
||||
osmand:srcCompat="@drawable/ic_action_osm_live"
|
||||
android:layout_marginEnd="@dimen/favorites_icon_right_margin" />
|
||||
osmand:srcCompat="@drawable/ic_action_subscription_osmand_live" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
|
@ -39,38 +33,64 @@
|
|||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/osm_live"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
android:text="@string/osm_live"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:textSize="@dimen/default_list_text_size" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:maxLines="25"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_sub_text_size"
|
||||
android:text="@string/osm_live_banner_desc"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="6dp"
|
||||
android:textColor="?attr/color_dialog_buttons"
|
||||
android:textAllCaps="true"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
android:text="@string/get_it"/>
|
||||
|
||||
</LinearLayout>
|
||||
android:letterSpacing="@dimen/description_letter_spacing"
|
||||
android:maxLines="25"
|
||||
android:text="@string/osm_live_banner_desc"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_desc_text_size" />
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/card_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="@dimen/content_padding_small"
|
||||
osmand:cardCornerRadius="3dp"
|
||||
osmand:cardElevation="0dp"
|
||||
tools:cardBackgroundColor="@color/active_buttons_and_links_trans_dark">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/card_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="@dimen/dialog_button_height"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/content_padding_small"
|
||||
android:paddingLeft="@dimen/content_padding_small"
|
||||
android:paddingEnd="@dimen/content_padding_half"
|
||||
android:paddingRight="@dimen/content_padding_half">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:letterSpacing="@dimen/description_letter_spacing"
|
||||
android:text="@string/get_it"
|
||||
android:textColor="?attr/colorPrimary"
|
||||
android:textSize="@dimen/default_desc_text_size" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/additional_button_icon"
|
||||
android:layout_width="@dimen/standard_icon_size"
|
||||
android:layout_height="@dimen/standard_icon_size"
|
||||
android:layout_marginStart="@dimen/content_padding_small"
|
||||
android:layout_marginLeft="@dimen/content_padding_small"
|
||||
android:tint="?attr/active_color_basic"
|
||||
osmand:srcCompat="@drawable/ic_arrow_forward" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -416,4 +416,6 @@
|
|||
|
||||
<dimen name="titleLineSpacingExtra">5sp</dimen>
|
||||
<dimen name="descriptionLineSpacingExtra">3sp</dimen>
|
||||
|
||||
<dimen name="list_item_triple_row_height">80dp</dimen>
|
||||
</resources>
|
|
@ -20,6 +20,16 @@
|
|||
<string name="copy_poi_name">Copy POI name</string>
|
||||
<string name="track_recording_will_be_continued">The recording will be continued.</string>
|
||||
<string name="select_category_descr">Select category or add new one</string>
|
||||
<string name="purchases">Purchases</string>
|
||||
<string name="live_update_delete_updates_msg">Are you sure you want to delete all %s live updates?</string>
|
||||
<string name="delete_updates">Delete updates</string>
|
||||
<string name="live_update_frequency_hour_variant">Map updates will be checked every hour. Next time%1$s in %2$s.</string>
|
||||
<string name="live_update_frequency_day_variant">Map updates will be checked every day. Next time%1$s in %2$s.</string>
|
||||
<string name="live_update_frequency_week_variant">Map updates will be checked every week. Next time%1$s in %2$s.</string>
|
||||
<string name="update_frequency">Update frequency</string>
|
||||
<string name="last_time_checked">Last time checked: %s</string>
|
||||
<string name="updated">Updated: %s</string>
|
||||
<string name="latest_openstreetmap_update">Latest OpenStreetMap update available:</string>
|
||||
<string name="map_widget_distance_by_tap">Distance by tap</string>
|
||||
<string name="quick_action_coordinates_widget_descr">A toggle to show or hide the Coordinates widget on the map.</string>
|
||||
<string name="routing_attr_height_obstacles_description">Routing could avoid strong uphills.</string>
|
||||
|
@ -2261,7 +2271,7 @@
|
|||
<string name="shared_string_add">Add</string>
|
||||
<string name="shared_string_add_to_favorites">Add to \'Favorites\'</string>
|
||||
<string name="shared_string_my_location">My Position</string>
|
||||
<string name="shared_string_my_places">My places</string>
|
||||
<string name="shared_string_my_places">My Places</string>
|
||||
<string name="shared_string_my_favorites">Favorites</string>
|
||||
<string name="shared_string_tracks">Tracks</string>
|
||||
<string name="shared_string_currently_recording_track">Currently recording track</string>
|
||||
|
|
|
@ -480,6 +480,16 @@ public class AndroidUtils {
|
|||
: ctx.getResources().getColor(R.color.text_color_secondary_light));
|
||||
}
|
||||
|
||||
@ColorRes
|
||||
public static int getPrimaryTextColorId(boolean nightMode) {
|
||||
return nightMode ? R.color.text_color_primary_dark : R.color.text_color_primary_light;
|
||||
}
|
||||
|
||||
@ColorRes
|
||||
public static int getSecondaryTextColorId(boolean nightMode) {
|
||||
return nightMode ? R.color.text_color_secondary_dark : R.color.text_color_secondary_light;
|
||||
}
|
||||
|
||||
public static int getTextMaxWidth(float textSize, List<String> titles) {
|
||||
int width = 0;
|
||||
for (String title : titles) {
|
||||
|
|
|
@ -94,8 +94,8 @@ import btools.routingapp.IBRouterService;
|
|||
|
||||
import static net.osmand.plus.AppVersionUpgradeOnInit.LAST_APP_VERSION;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.getPendingIntent;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceForLocalIndex;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLastCheck;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLiveUpdatesOn;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceTimeOfDayToUpdate;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceUpdateFrequency;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.runLiveUpdate;
|
||||
|
@ -716,7 +716,7 @@ public class AppInitializer implements IProgress {
|
|||
AlarmManager alarmMgr = (AlarmManager) app.getSystemService(Context.ALARM_SERVICE);
|
||||
for (LocalIndexInfo fm : fullMaps) {
|
||||
String fileName = fm.getFileName();
|
||||
if (!preferenceLiveUpdatesOn(fileName, settings).get()) {
|
||||
if (!preferenceForLocalIndex(fileName, settings).get()) {
|
||||
continue;
|
||||
}
|
||||
int updateFrequencyOrd = preferenceUpdateFrequency(fileName, settings).get();
|
||||
|
@ -725,7 +725,7 @@ public class AppInitializer implements IProgress {
|
|||
long lastCheck = preferenceLastCheck(fileName, settings).get();
|
||||
|
||||
if (System.currentTimeMillis() - lastCheck > updateFrequency.getTime() * 2) {
|
||||
runLiveUpdate(app, fileName, false);
|
||||
runLiveUpdate(app, fileName, false, null);
|
||||
PendingIntent alarmIntent = getPendingIntent(app, fileName);
|
||||
int timeOfDayOrd = preferenceTimeOfDayToUpdate(fileName, settings).get();
|
||||
LiveUpdatesHelper.TimeOfDay timeOfDayToUpdate =
|
||||
|
|
|
@ -8,7 +8,7 @@ import net.osmand.plus.activities.LocalIndexHelper.LocalIndexType;
|
|||
|
||||
import java.io.File;
|
||||
|
||||
public class LocalIndexInfo {
|
||||
public class LocalIndexInfo implements Comparable<LocalIndexInfo> {
|
||||
|
||||
private LocalIndexType type;
|
||||
private String description = "";
|
||||
|
@ -172,8 +172,8 @@ public class LocalIndexInfo {
|
|||
return type.getBasename(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public int compareTo(LocalIndexInfo o) {
|
||||
return getFileName().compareTo(o.getFileName());
|
||||
}
|
||||
}
|
|
@ -927,22 +927,6 @@ public class MapActivityActions implements DialogProvider {
|
|||
}
|
||||
}).createItem());
|
||||
|
||||
if (Version.isGooglePlayEnabled() || Version.isHuawei() || Version.isDeveloperVersion(app)) {
|
||||
optionsMenuHelper.addItem(new ItemBuilder().setTitleId(R.string.osm_live, mapActivity)
|
||||
.setId(DRAWER_OSMAND_LIVE_ID)
|
||||
.setIcon(R.drawable.ic_action_osm_live)
|
||||
.setListener(new ItemClickListener() {
|
||||
@Override
|
||||
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) {
|
||||
app.logEvent("drawer_osm_live_open");
|
||||
Intent intent = new Intent(mapActivity, OsmLiveActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
||||
mapActivity.startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
}).createItem());
|
||||
}
|
||||
|
||||
optionsMenuHelper.addItem(new ItemBuilder().setTitle(getString(R.string.shared_string_travel_guides) + " (Beta)")
|
||||
.setId(DRAWER_TRAVEL_GUIDES_ID)
|
||||
.setIcon(R.drawable.ic_action_travel)
|
||||
|
@ -1046,6 +1030,22 @@ public class MapActivityActions implements DialogProvider {
|
|||
}).createItem());
|
||||
*/
|
||||
|
||||
if (Version.isGooglePlayEnabled() || Version.isHuawei() || Version.isDeveloperVersion(app)) {
|
||||
optionsMenuHelper.addItem(new ItemBuilder().setTitleId(R.string.purchases, mapActivity)
|
||||
.setId(DRAWER_OSMAND_LIVE_ID)
|
||||
.setIcon(R.drawable.ic_action_purchases)
|
||||
.setListener(new ItemClickListener() {
|
||||
@Override
|
||||
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) {
|
||||
app.logEvent("drawer_osm_live_open");
|
||||
Intent intent = new Intent(mapActivity, OsmLiveActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
||||
mapActivity.startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
}).createItem());
|
||||
}
|
||||
|
||||
optionsMenuHelper.addItem(new ItemBuilder().setTitleId(R.string.shared_string_help, mapActivity)
|
||||
.setId(DRAWER_HELP_ID)
|
||||
.setIcon(R.drawable.ic_action_help)
|
||||
|
|
|
@ -3,8 +3,12 @@ package net.osmand.plus.download.ui;
|
|||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
|
@ -13,17 +17,31 @@ import android.view.View;
|
|||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.ColorRes;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.cardview.widget.CardView;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.view.MenuItemCompat;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.Collator;
|
||||
import net.osmand.OsmAndCollator;
|
||||
import net.osmand.map.OsmandRegions;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.activities.LocalIndexInfo;
|
||||
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||
import net.osmand.plus.liveupdates.LiveUpdatesClearDialogFragment.RefreshLiveUpdates;
|
||||
import net.osmand.plus.liveupdates.LiveUpdatesFragmentNew;
|
||||
import net.osmand.plus.liveupdates.LoadLiveMapsTask;
|
||||
import net.osmand.plus.liveupdates.LoadLiveMapsTask.LocalIndexInfoAdapter;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.base.OsmAndListFragment;
|
||||
|
@ -35,18 +53,25 @@ import net.osmand.plus.download.IndexItem;
|
|||
import net.osmand.plus.inapp.InAppPurchaseHelper;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class UpdatesIndexFragment extends OsmAndListFragment implements DownloadEvents {
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesFragmentNew.showUpdateDialog;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesFragmentNew.updateCountEnabled;
|
||||
|
||||
public class UpdatesIndexFragment extends OsmAndListFragment implements DownloadEvents, RefreshLiveUpdates {
|
||||
private static final int RELOAD_ID = 5;
|
||||
private UpdateIndexAdapter listAdapter;
|
||||
private String errorMessage;
|
||||
private OsmandSettings settings;
|
||||
private LoadLiveMapsTask loadLiveMapsTask;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
settings = getMyApplication().getSettings();
|
||||
}
|
||||
|
||||
|
||||
|
@ -67,6 +92,7 @@ public class UpdatesIndexFragment extends OsmAndListFragment implements Download
|
|||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
invalidateListView(activity);
|
||||
startLoadLiveMapsAsyncTask(getMyApplication());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,6 +104,7 @@ public class UpdatesIndexFragment extends OsmAndListFragment implements Download
|
|||
public void downloadHasFinished() {
|
||||
invalidateListView(getMyActivity());
|
||||
updateUpdateAllButton();
|
||||
startLoadLiveMapsAsyncTask(getMyApplication());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -92,25 +119,24 @@ public class UpdatesIndexFragment extends OsmAndListFragment implements Download
|
|||
}
|
||||
|
||||
public void invalidateListView(Activity a) {
|
||||
DownloadResources indexes = getMyApplication().getDownloadThread().getIndexes();
|
||||
final OsmandApplication app = getMyApplication();
|
||||
OsmandSettings settings = app.getSettings();
|
||||
DownloadResources indexes = app.getDownloadThread().getIndexes();
|
||||
List<IndexItem> indexItems = indexes.getItemsToUpdate();
|
||||
|
||||
final OsmandRegions osmandRegions =
|
||||
getMyApplication().getResourceManager().getOsmandRegions();
|
||||
OsmandSettings settings = getMyApplication().getSettings();
|
||||
final OsmandRegions osmandRegions = app.getResourceManager().getOsmandRegions();
|
||||
listAdapter = new UpdateIndexAdapter(a, R.layout.download_index_list_item, indexItems,
|
||||
!InAppPurchaseHelper.isSubscribedToLiveUpdates(getMyApplication()) || settings.SHOULD_SHOW_FREE_VERSION_BANNER.get());
|
||||
!InAppPurchaseHelper.isSubscribedToLiveUpdates(app) || settings.SHOULD_SHOW_FREE_VERSION_BANNER.get());
|
||||
final Collator collator = OsmAndCollator.primaryCollator();
|
||||
listAdapter.sort(new Comparator<IndexItem>() {
|
||||
@Override
|
||||
public int compare(IndexItem indexItem, IndexItem indexItem2) {
|
||||
return collator.compare(indexItem.getVisibleName(getMyApplication(), osmandRegions),
|
||||
indexItem2.getVisibleName(getMyApplication(), osmandRegions));
|
||||
return collator.compare(indexItem.getVisibleName(app, osmandRegions),
|
||||
indexItem2.getVisibleName(app, osmandRegions));
|
||||
}
|
||||
});
|
||||
setListAdapter(listAdapter);
|
||||
updateErrorMessage();
|
||||
|
||||
}
|
||||
|
||||
private void updateErrorMessage() {
|
||||
|
@ -153,26 +179,27 @@ public class UpdatesIndexFragment extends OsmAndListFragment implements Download
|
|||
for (IndexItem indexItem : indexItems) {
|
||||
downloadsSize += indexItem.getSize();
|
||||
}
|
||||
String updateAllText = getActivity().getString(
|
||||
String updateAllText = getString(
|
||||
R.string.update_all, String.valueOf(downloadsSize >> 20));
|
||||
updateAllButton.setText(updateAllText);
|
||||
updateAllButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
final DownloadActivity activity = getMyActivity();
|
||||
if (indexItems.size() > 3) {
|
||||
AlertDialog.Builder dialog = new AlertDialog.Builder(getMyActivity());
|
||||
AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
|
||||
dialog.setTitle(R.string.update_all_maps);
|
||||
dialog.setMessage(getString(R.string.update_all_maps_q, indexItems.size()));
|
||||
dialog.setNegativeButton(R.string.shared_string_cancel, null);
|
||||
dialog.setPositiveButton(R.string.shared_string_update, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
getMyActivity().startDownload(indexItems.toArray(new IndexItem[0]));
|
||||
activity.startDownload(indexItems.toArray(new IndexItem[0]));
|
||||
}
|
||||
});
|
||||
dialog.create().show();
|
||||
} else {
|
||||
getMyActivity().startDownload(indexItems.toArray(new IndexItem[0]));
|
||||
activity.startDownload(indexItems.toArray(new IndexItem[0]));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -185,12 +212,31 @@ public class UpdatesIndexFragment extends OsmAndListFragment implements Download
|
|||
updateUpdateAllButton();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
stopLoadLiveMapsAsyncTask();
|
||||
}
|
||||
|
||||
private void startLoadLiveMapsAsyncTask(OsmandApplication app) {
|
||||
loadLiveMapsTask = new LoadLiveMapsTask(listAdapter, app);
|
||||
loadLiveMapsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private void stopLoadLiveMapsAsyncTask() {
|
||||
if (loadLiveMapsTask != null && loadLiveMapsTask.getStatus() == AsyncTask.Status.RUNNING) {
|
||||
loadLiveMapsTask.cancel(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListItemClick(ListView l, View v, int position, long id) {
|
||||
if (listAdapter.isShowOsmLiveBanner() && position == 0) {
|
||||
if (position == 0) {
|
||||
DownloadActivity activity = getMyActivity();
|
||||
if (activity != null) {
|
||||
ChoosePlanDialogFragment.showOsmLiveInstance(activity.getSupportFragmentManager());
|
||||
if (!listAdapter.isShowOsmLivePurchaseBanner()) {
|
||||
LiveUpdatesFragmentNew.showInstance(activity.getSupportFragmentManager(), this);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final IndexItem e = (IndexItem) getListAdapter().getItem(position);
|
||||
|
@ -220,10 +266,6 @@ public class UpdatesIndexFragment extends OsmAndListFragment implements Download
|
|||
}
|
||||
}
|
||||
|
||||
public OsmandApplication getMyApplication() {
|
||||
return getMyActivity().getMyApplication();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == RELOAD_ID) {
|
||||
|
@ -234,75 +276,147 @@ public class UpdatesIndexFragment extends OsmAndListFragment implements Download
|
|||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private class UpdateIndexAdapter extends ArrayAdapter<IndexItem> {
|
||||
@Override
|
||||
public void onUpdateStates(Context context) {
|
||||
if (context instanceof OsmandApplication) {
|
||||
startLoadLiveMapsAsyncTask((OsmandApplication) context);
|
||||
}
|
||||
}
|
||||
|
||||
private class UpdateIndexAdapter extends ArrayAdapter<IndexItem> implements LocalIndexInfoAdapter {
|
||||
|
||||
static final int INDEX_ITEM = 0;
|
||||
static final int OSM_LIVE_BANNER = 1;
|
||||
|
||||
List<IndexItem> items;
|
||||
boolean showOsmLiveBanner;
|
||||
private final ArrayList<LocalIndexInfo> mapsList = new ArrayList<>();
|
||||
private final boolean showOsmLivePurchaseBanner;
|
||||
private TextView countView;
|
||||
private int countEnabled = 0;
|
||||
|
||||
public UpdateIndexAdapter(Context context, int resource, List<IndexItem> items, boolean showOsmLiveBanner) {
|
||||
super(context, resource, items);
|
||||
this.items = items;
|
||||
this.showOsmLiveBanner = showOsmLiveBanner;
|
||||
@Override
|
||||
public void addData(LocalIndexInfo info) {
|
||||
mapsList.add(info);
|
||||
}
|
||||
|
||||
public boolean isShowOsmLiveBanner() {
|
||||
return showOsmLiveBanner;
|
||||
@Override
|
||||
public void clearData() {
|
||||
mapsList.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataUpdated() {
|
||||
countEnabled = updateCountEnabled(countView, mapsList, settings);
|
||||
}
|
||||
|
||||
public UpdateIndexAdapter(Context context, int resource, List<IndexItem> items, boolean showOsmLivePurchaseBanner) {
|
||||
super(context, resource, items);
|
||||
this.items = items;
|
||||
this.showOsmLivePurchaseBanner = showOsmLivePurchaseBanner;
|
||||
}
|
||||
|
||||
public boolean isShowOsmLivePurchaseBanner() {
|
||||
return showOsmLivePurchaseBanner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return super.getCount() + (showOsmLiveBanner ? 1 : 0);
|
||||
return super.getCount() + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IndexItem getItem(int position) {
|
||||
if (showOsmLiveBanner && position == 0) {
|
||||
if (position == 0) {
|
||||
return null;
|
||||
} else {
|
||||
return super.getItem(position - (showOsmLiveBanner ? 1 : 0));
|
||||
return super.getItem(position - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPosition(IndexItem item) {
|
||||
return super.getPosition(item) + (showOsmLiveBanner ? 1 : 0);
|
||||
return super.getPosition(item) + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewTypeCount() {
|
||||
return showOsmLiveBanner ? 2 : 1;
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return showOsmLiveBanner && position == 0 ? OSM_LIVE_BANNER : INDEX_ITEM;
|
||||
return position == 0 ? OSM_LIVE_BANNER : INDEX_ITEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(final int position, final View convertView, final ViewGroup parent) {
|
||||
View v = convertView;
|
||||
View view = convertView;
|
||||
int viewType = getItemViewType(position);
|
||||
if (v == null) {
|
||||
if (viewType == INDEX_ITEM) {
|
||||
if (view == null) {
|
||||
LayoutInflater inflater = LayoutInflater.from(getMyActivity());
|
||||
v = inflater.inflate(R.layout.two_line_with_images_list_item, parent, false);
|
||||
v.setTag(new ItemViewHolder(v, getMyActivity()));
|
||||
if (viewType == INDEX_ITEM) {
|
||||
view = inflater.inflate(R.layout.two_line_with_images_list_item, parent, false);
|
||||
view.setTag(new ItemViewHolder(view, getMyActivity()));
|
||||
} else if (viewType == OSM_LIVE_BANNER) {
|
||||
LayoutInflater inflater = LayoutInflater.from(getMyActivity());
|
||||
v = inflater.inflate(R.layout.osm_live_banner_list_item, parent, false);
|
||||
OsmandApplication app = getMyApplication();
|
||||
boolean nightMode = !app.getSettings().isLightContent();
|
||||
if (showOsmLivePurchaseBanner) {
|
||||
view = inflater.inflate(R.layout.osm_live_banner_list_item, parent, false);
|
||||
ColorStateList stateList = AndroidUtils.createPressedColorStateList(app, nightMode,
|
||||
R.color.switch_button_active_light, R.color.switch_button_active_stroke_light,
|
||||
R.color.switch_button_active_dark, R.color.switch_button_active_stroke_dark);
|
||||
CardView cardView = ((CardView) view.findViewById(R.id.card_view));
|
||||
cardView.setCardBackgroundColor(stateList);
|
||||
cardView.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
ChoosePlanDialogFragment.showOsmLiveInstance(getMyActivity().getSupportFragmentManager());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
view = inflater.inflate(R.layout.bottom_sheet_item_with_descr_switch_and_additional_button_56dp, parent, false);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
view.setBackground(null);
|
||||
}
|
||||
AndroidUiHelper.setVisibility(View.GONE, view.findViewById(R.id.compound_button));
|
||||
((ImageView) view.findViewById(R.id.icon)).setImageResource(R.drawable.ic_action_subscription_osmand_live);
|
||||
TextView tvTitle = view.findViewById(R.id.title);
|
||||
tvTitle.setText(R.string.download_live_updates);
|
||||
AndroidUtils.setTextPrimaryColor(app, tvTitle, nightMode);
|
||||
countView = view.findViewById(R.id.description);
|
||||
AndroidUtils.setTextSecondaryColor(app, countView, nightMode);
|
||||
Drawable additionalIconDrawable = AppCompatResources.getDrawable(app, R.drawable.ic_action_update);
|
||||
UiUtilities.tintDrawable(additionalIconDrawable, ContextCompat.getColor(app, getDefaultIconColorId(nightMode)));
|
||||
((ImageView) view.findViewById(R.id.additional_button_icon)).setImageDrawable(additionalIconDrawable);
|
||||
LinearLayout additionalButton = view.findViewById(R.id.additional_button);
|
||||
TypedValue typedValue = new TypedValue();
|
||||
app.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, typedValue, true);
|
||||
additionalButton.setBackgroundResource(typedValue.resourceId);
|
||||
additionalButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (!listAdapter.isShowOsmLivePurchaseBanner()) {
|
||||
showUpdateDialog(getActivity(), getMyApplication().getSettings(),
|
||||
listAdapter.mapsList, listAdapter.countEnabled, null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (viewType == INDEX_ITEM) {
|
||||
ItemViewHolder holder = (ItemViewHolder) v.getTag();
|
||||
ItemViewHolder holder = (ItemViewHolder) view.getTag();
|
||||
holder.setShowRemoteDate(true);
|
||||
holder.setShowTypeInDesc(true);
|
||||
holder.setShowParentRegionName(true);
|
||||
holder.bindIndexItem(getItem(position));
|
||||
}
|
||||
return v;
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
||||
@ColorRes
|
||||
public static int getDefaultIconColorId(boolean nightMode) {
|
||||
return nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ public class LiveUpdatesAlarmReceiver extends BroadcastReceiver {
|
|||
final OsmandSettings settings = application.getSettings();
|
||||
|
||||
if (!preferenceDownloadViaWiFi(localIndexInfoFile, settings).get() || wifi.isWifiEnabled()) {
|
||||
new PerformLiveUpdateAsyncTask(context, localIndexInfoFile, false).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, fileName);
|
||||
new PerformLiveUpdateAsyncTask(context, localIndexInfoFile, false, null).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, fileName);
|
||||
} else {
|
||||
PerformLiveUpdateAsyncTask.tryRescheduleDownload(context, settings, localIndexInfoFile);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
package net.osmand.plus.liveupdates;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.text.SpannableString;
|
||||
import android.text.style.StyleSpan;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.UiUtilities.DialogButtonType;
|
||||
import net.osmand.plus.base.MenuBottomSheetDialogFragment;
|
||||
import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerSpaceItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.LongDescriptionItem;
|
||||
import net.osmand.plus.resources.IncrementalChangesManager;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import static net.osmand.AndroidUtils.getPrimaryTextColorId;
|
||||
import static net.osmand.AndroidUtils.getSecondaryTextColorId;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.getNameToDisplay;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLastCheck;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLatestUpdateAvailable;
|
||||
|
||||
public class LiveUpdatesClearDialogFragment extends MenuBottomSheetDialogFragment {
|
||||
|
||||
public static final String TAG = LiveUpdatesClearDialogFragment.class.getSimpleName();
|
||||
private static final Log LOG = PlatformUtil.getLog(LiveUpdatesClearDialogFragment.class);
|
||||
private static final String LOCAL_INDEX_FILE_NAME = "local_index_file_name";
|
||||
|
||||
private OsmandApplication app;
|
||||
private OsmandSettings settings;
|
||||
|
||||
private String fileName;
|
||||
|
||||
public static void showInstance(@NonNull FragmentManager fragmentManager, Fragment target, String fileName) {
|
||||
if (!fragmentManager.isStateSaved()) {
|
||||
LiveUpdatesClearDialogFragment fragment = new LiveUpdatesClearDialogFragment();
|
||||
fragment.setTargetFragment(target, 0);
|
||||
fragment.fileName = fileName;
|
||||
fragment.show(fragmentManager, TAG);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createMenuItems(Bundle savedInstanceState) {
|
||||
app = getMyApplication();
|
||||
settings = app.getSettings();
|
||||
|
||||
if (savedInstanceState != null && savedInstanceState.containsKey(LOCAL_INDEX_FILE_NAME)) {
|
||||
fileName = savedInstanceState.getString(LOCAL_INDEX_FILE_NAME);
|
||||
}
|
||||
|
||||
items.add(new SimpleBottomSheetItem.Builder()
|
||||
.setTitle(getString(R.string.delete_updates))
|
||||
.setTitleColorId(getPrimaryTextColorId(nightMode))
|
||||
.setLayoutId(R.layout.bottom_sheet_item_title)
|
||||
.create());
|
||||
|
||||
String nameToDisplay = getNameToDisplay(fileName, app);
|
||||
String text = getString(R.string.live_update_delete_updates_msg, nameToDisplay);
|
||||
SpannableString message = UiUtilities.createSpannableString(text, new StyleSpan(Typeface.BOLD), nameToDisplay);
|
||||
|
||||
items.add(new LongDescriptionItem.Builder()
|
||||
.setDescription(message)
|
||||
.setDescriptionColorId(getSecondaryTextColorId(nightMode))
|
||||
.setDescriptionMaxLines(5)
|
||||
.setLayoutId(R.layout.bottom_sheet_item_description_long)
|
||||
.create());
|
||||
|
||||
items.add(new DividerSpaceItem(app, getResources().getDimensionPixelSize(R.dimen.content_padding_small)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putString(LOCAL_INDEX_FILE_NAME, fileName);
|
||||
}
|
||||
|
||||
private void deleteUpdates() {
|
||||
IncrementalChangesManager changesManager = app.getResourceManager().getChangesManager();
|
||||
String fileNameWithoutExt = Algorithms.getFileNameWithoutExtension(fileName);
|
||||
changesManager.deleteUpdates(fileNameWithoutExt);
|
||||
preferenceLastCheck(fileName, settings).resetToDefault();
|
||||
preferenceLatestUpdateAvailable(fileName, settings).resetToDefault();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRightBottomButtonClick() {
|
||||
deleteUpdates();
|
||||
|
||||
Fragment fragment = getTargetFragment();
|
||||
if (fragment instanceof RefreshLiveUpdates) {
|
||||
((RefreshLiveUpdates) fragment).onUpdateStates(app);
|
||||
}
|
||||
|
||||
dismiss();
|
||||
}
|
||||
|
||||
public interface RefreshLiveUpdates {
|
||||
void onUpdateStates(Context context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDismissButtonTextId() {
|
||||
return R.string.shared_string_cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getRightBottomButtonTextId() {
|
||||
return R.string.shared_string_delete;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DialogButtonType getRightBottomButtonType() {
|
||||
return DialogButtonType.SECONDARY_HARMFUL;
|
||||
}
|
||||
|
||||
}
|
|
@ -4,7 +4,6 @@ import android.app.Activity;
|
|||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
@ -26,8 +25,6 @@ import android.widget.TextView;
|
|||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AlertDialog.Builder;
|
||||
import androidx.appcompat.widget.SwitchCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
@ -61,6 +58,7 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesFragmentNew.showUpdateDialog;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.DEFAULT_LAST_CHECK;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.TimeOfDay;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.UpdateFrequency;
|
||||
|
@ -71,7 +69,6 @@ import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLastCheck;
|
|||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLiveUpdatesOn;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceTimeOfDayToUpdate;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceUpdateFrequency;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.runLiveUpdate;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.setAlarmForPendingIntent;
|
||||
|
||||
public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppPurchaseListener {
|
||||
|
@ -131,7 +128,7 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppPurc
|
|||
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
adapter.showUpdateDialog();
|
||||
showUpdateDialog(getActivity(), getSettings(), adapter.dataShouldUpdate, adapter.dataShouldUpdate.size(), null);
|
||||
swipeRefresh.setRefreshing(false);
|
||||
}
|
||||
});
|
||||
|
@ -442,30 +439,7 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppPurc
|
|||
private void switchOnLiveUpdates(final OsmandSettings settings) {
|
||||
settings.IS_LIVE_UPDATES_ON.set(true);
|
||||
enableLiveUpdates(true);
|
||||
showUpdateDialog();
|
||||
}
|
||||
|
||||
private void showUpdateDialog() {
|
||||
if(dataShouldUpdate.size() > 0) {
|
||||
if (dataShouldUpdate.size() == 1) {
|
||||
runLiveUpdate(app, dataShouldUpdate.get(0).getFileName(), false);
|
||||
} else {
|
||||
Builder bld = new AlertDialog.Builder(ctx);
|
||||
bld.setMessage(R.string.update_all_maps_now);
|
||||
bld.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
for (LocalIndexInfo li : dataShouldUpdate) {
|
||||
runLiveUpdate(app, li.getFileName(), false);
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
bld.setNegativeButton(R.string.shared_string_no, null);
|
||||
bld.show();
|
||||
}
|
||||
}
|
||||
showUpdateDialog(getActivity(), getSettings(), adapter.dataShouldUpdate, adapter.dataShouldUpdate.size(), null);
|
||||
}
|
||||
|
||||
private void enableLiveUpdates(boolean enable) {
|
||||
|
@ -575,7 +549,7 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppPurc
|
|||
preferenceLiveUpdatesOn(item, fragment.getSettings());
|
||||
IncrementalChangesManager changesManager = context.getResourceManager().getChangesManager();
|
||||
|
||||
nameTextView.setText(getNameToDisplay(item, fragment.getMyActivity()));
|
||||
nameTextView.setText(getNameToDisplay(item, context));
|
||||
if (shouldUpdatePreference.get()) {
|
||||
final Integer frequencyId = preferenceUpdateFrequency(item, fragment.getSettings()).get();
|
||||
final Integer timeOfDateToUpdateId = preferenceTimeOfDayToUpdate(item, fragment.getSettings()).get();
|
||||
|
|
|
@ -0,0 +1,710 @@
|
|||
package net.osmand.plus.liveupdates;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.ExpandableListView;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.ColorRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.AppCompatImageView;
|
||||
import androidx.appcompat.widget.SwitchCompat;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.graphics.drawable.DrawableCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import net.osmand.AndroidNetworkUtils;
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.UiUtilities.CompoundButtonType;
|
||||
import net.osmand.plus.activities.LocalIndexInfo;
|
||||
import net.osmand.plus.activities.OsmandBaseExpandableListAdapter;
|
||||
import net.osmand.plus.base.BaseOsmAndDialogFragment;
|
||||
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||
import net.osmand.plus.helpers.FontCache;
|
||||
import net.osmand.plus.inapp.InAppPurchaseHelper;
|
||||
import net.osmand.plus.liveupdates.LiveUpdatesClearDialogFragment.RefreshLiveUpdates;
|
||||
import net.osmand.plus.liveupdates.LiveUpdatesHelper.TimeOfDay;
|
||||
import net.osmand.plus.liveupdates.LiveUpdatesHelper.UpdateFrequency;
|
||||
import net.osmand.plus.liveupdates.LiveUpdatesSettingsDialogFragmentNew.OnLiveUpdatesForLocalChange;
|
||||
import net.osmand.plus.liveupdates.LoadLiveMapsTask.LocalIndexInfoAdapter;
|
||||
import net.osmand.plus.liveupdates.PerformLiveUpdateAsyncTask.LiveUpdateListener;
|
||||
import net.osmand.plus.settings.backend.CommonPreference;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.widgets.TextViewEx;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import static net.osmand.AndroidUtils.getSecondaryTextColorId;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.formatShortDateTime;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.getNameToDisplay;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.getPendingIntent;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceForLocalIndex;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLastCheck;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLatestUpdateAvailable;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceTimeOfDayToUpdate;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceUpdateFrequency;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.runLiveUpdate;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.setAlarmForPendingIntent;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesSettingsDialogFragmentNew.getTertiaryTextColorId;
|
||||
import static net.osmand.plus.monitoring.TripRecordingActiveBottomSheet.getActiveTextColorId;
|
||||
import static net.osmand.plus.monitoring.TripRecordingActiveBottomSheet.getOsmandIconColorId;
|
||||
import static net.osmand.plus.monitoring.TripRecordingActiveBottomSheet.getSecondaryIconColorId;
|
||||
|
||||
public class LiveUpdatesFragmentNew extends BaseOsmAndDialogFragment implements OnLiveUpdatesForLocalChange {
|
||||
|
||||
public static final String URL = "https://osmand.net/api/osmlive_status";
|
||||
public static final String TAG = LiveUpdatesFragmentNew.class.getSimpleName();
|
||||
private final static Log LOG = PlatformUtil.getLog(LiveUpdatesFragmentNew.class);
|
||||
private static final String SUBSCRIPTION_URL = "https://osmand.net/features/subscription";
|
||||
|
||||
private OsmandApplication app;
|
||||
private OsmandSettings settings;
|
||||
private boolean nightMode;
|
||||
|
||||
private View toolbarSwitchContainer;
|
||||
private ExpandableListView listView;
|
||||
private TextViewEx descriptionTime;
|
||||
private LiveMapsAdapter adapter;
|
||||
|
||||
private GetLastUpdateDateTask getLastUpdateDateTask;
|
||||
private LoadLiveMapsTask loadLiveMapsTask;
|
||||
|
||||
private final LiveUpdateListener liveUpdateListener = new LiveUpdateListener() {
|
||||
@Override
|
||||
public void processFinish() {
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
};
|
||||
|
||||
public static void showInstance(@NonNull FragmentManager fragmentManager, Fragment target) {
|
||||
if (!fragmentManager.isStateSaved()) {
|
||||
LiveUpdatesFragmentNew fragment = new LiveUpdatesFragmentNew();
|
||||
fragment.setTargetFragment(target, 0);
|
||||
fragment.show(fragmentManager, TAG);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
app = getMyApplication();
|
||||
settings = getSettings();
|
||||
nightMode = isNightMode(false);
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_live_updates, container, false);
|
||||
|
||||
Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
|
||||
toolbar.setTitle(R.string.osm_live);
|
||||
int iconColorResId = nightMode ? R.color.active_buttons_and_links_text_dark : R.color.active_buttons_and_links_text_light;
|
||||
Drawable icBack = app.getUIUtilities().getIcon(AndroidUtils.getNavigationIconResId(app), iconColorResId);
|
||||
DrawableCompat.setTint(icBack, ContextCompat.getColor(app, iconColorResId));
|
||||
toolbar.setNavigationIcon(icBack);
|
||||
toolbar.setNavigationContentDescription(R.string.access_shared_string_navigate_up);
|
||||
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
ImageButton iconHelp = toolbar.findViewById(R.id.toolbar_action);
|
||||
Drawable helpDrawable = app.getUIUtilities().getIcon(R.drawable.ic_action_help, iconColorResId);
|
||||
iconHelp.setImageDrawable(helpDrawable);
|
||||
iconHelp.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(SUBSCRIPTION_URL));
|
||||
if (AndroidUtils.isIntentSafe(app, intent)) {
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
listView = (ExpandableListView) view.findViewById(android.R.id.list);
|
||||
adapter = new LiveMapsAdapter();
|
||||
listView.setAdapter(adapter);
|
||||
expandAllGroups();
|
||||
|
||||
View bottomShadowView = inflater.inflate(R.layout.card_bottom_divider, listView, false);
|
||||
listView.addFooterView(bottomShadowView);
|
||||
listView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
|
||||
@Override
|
||||
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
|
||||
if (InAppPurchaseHelper.isSubscribedToLiveUpdates(app) && settings.IS_LIVE_UPDATES_ON.get()) {
|
||||
if (getFragmentManager() != null) {
|
||||
LiveUpdatesSettingsDialogFragmentNew
|
||||
.showInstance(getFragmentManager(), LiveUpdatesFragmentNew.this,
|
||||
adapter.getChild(groupPosition, childPosition).getFileName());
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final SwipeRefreshLayout swipeRefresh = view.findViewById(R.id.swipe_refresh);
|
||||
int swipeColor = ContextCompat.getColor(app, nightMode ? R.color.osmand_orange_dark : R.color.osmand_orange);
|
||||
swipeRefresh.setColorSchemeColors(swipeColor);
|
||||
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
if (settings.IS_LIVE_UPDATES_ON.get()) {
|
||||
showUpdateDialog(getActivity(), settings, adapter.mapsList, adapter.countEnabled, liveUpdateListener);
|
||||
startUpdateDateAsyncTask();
|
||||
}
|
||||
swipeRefresh.setRefreshing(false);
|
||||
}
|
||||
});
|
||||
|
||||
toolbarSwitchContainer = view.findViewById(R.id.toolbar_switch_container);
|
||||
updateToolbarSwitch(settings.IS_LIVE_UPDATES_ON.get());
|
||||
|
||||
View timeContainer = view.findViewById(R.id.item_import_container);
|
||||
AndroidUtils.setListItemBackground(app, timeContainer, nightMode);
|
||||
|
||||
AppCompatImageView descriptionIcon = timeContainer.findViewById(R.id.icon);
|
||||
Drawable icon = UiUtilities.createTintedDrawable(app, R.drawable.ic_action_time,
|
||||
ContextCompat.getColor(app, nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light));
|
||||
descriptionIcon.setImageDrawable(icon);
|
||||
|
||||
TextViewEx title = timeContainer.findViewById(R.id.title);
|
||||
AndroidUtils.setTextSecondaryColor(app, title, nightMode);
|
||||
title.setText(R.string.latest_openstreetmap_update);
|
||||
title.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.default_desc_text_size));
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
title.setLetterSpacing(AndroidUtils.getFloatValueFromRes(app, R.dimen.description_letter_spacing));
|
||||
}
|
||||
|
||||
descriptionTime = timeContainer.findViewById(R.id.sub_title);
|
||||
AndroidUtils.setTextPrimaryColor(app, descriptionTime, nightMode);
|
||||
Typeface typeface = FontCache.getFont(app, getString(R.string.font_roboto_medium));
|
||||
descriptionTime.setTypeface(typeface);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
descriptionTime.setLetterSpacing(AndroidUtils.getFloatValueFromRes(app, R.dimen.description_letter_spacing));
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
startUpdateDateAsyncTask();
|
||||
startLoadLiveMapsAsyncTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
stopUpdateDateAsyncTask();
|
||||
stopLoadLiveMapsAsyncTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismiss(@NonNull DialogInterface dialog) {
|
||||
super.onDismiss(dialog);
|
||||
Fragment target = getTargetFragment();
|
||||
if (target instanceof RefreshLiveUpdates) {
|
||||
((RefreshLiveUpdates) target).onUpdateStates(app);
|
||||
}
|
||||
}
|
||||
|
||||
private void startUpdateDateAsyncTask() {
|
||||
getLastUpdateDateTask = new GetLastUpdateDateTask(this);
|
||||
getLastUpdateDateTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private void stopUpdateDateAsyncTask() {
|
||||
if (getLastUpdateDateTask != null) {
|
||||
getLastUpdateDateTask.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void startLoadLiveMapsAsyncTask() {
|
||||
if (loadLiveMapsTask == null) {
|
||||
loadLiveMapsTask = new LoadLiveMapsTask(adapter, app);
|
||||
loadLiveMapsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
}
|
||||
|
||||
private void stopLoadLiveMapsAsyncTask() {
|
||||
if (loadLiveMapsTask != null && loadLiveMapsTask.getStatus() == AsyncTask.Status.RUNNING) {
|
||||
loadLiveMapsTask.cancel(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateToolbarSwitch(final boolean isChecked) {
|
||||
int switchColor = ContextCompat.getColor(app,
|
||||
isChecked ? getActiveTextColorId(nightMode) : getSecondaryTextColorId(nightMode));
|
||||
AndroidUtils.setBackground(toolbarSwitchContainer, new ColorDrawable(switchColor));
|
||||
|
||||
SwitchCompat switchView = toolbarSwitchContainer.findViewById(R.id.switchWidget);
|
||||
switchView.setChecked(isChecked);
|
||||
UiUtilities.setupCompoundButton(switchView, nightMode, CompoundButtonType.TOOLBAR);
|
||||
|
||||
toolbarSwitchContainer.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
boolean visible = !isChecked;
|
||||
if (visible) {
|
||||
if (InAppPurchaseHelper.isSubscribedToLiveUpdates(app)) {
|
||||
switchOnLiveUpdates();
|
||||
updateToolbarSwitch(true);
|
||||
} else {
|
||||
app.showToastMessage(getString(R.string.osm_live_ask_for_purchase));
|
||||
updateToolbarSwitch(false);
|
||||
}
|
||||
} else {
|
||||
settings.IS_LIVE_UPDATES_ON.set(false);
|
||||
enableLiveUpdates(false);
|
||||
updateToolbarSwitch(false);
|
||||
}
|
||||
updateList();
|
||||
}
|
||||
});
|
||||
|
||||
TextView title = toolbarSwitchContainer.findViewById(R.id.switchButtonText);
|
||||
title.setText(isChecked ? R.string.shared_string_enabled : R.string.shared_string_disabled);
|
||||
}
|
||||
|
||||
private void switchOnLiveUpdates() {
|
||||
settings.IS_LIVE_UPDATES_ON.set(true);
|
||||
enableLiveUpdates(true);
|
||||
showUpdateDialog(getMyActivity(), settings, adapter.mapsList, adapter.countEnabled, liveUpdateListener);
|
||||
startUpdateDateAsyncTask();
|
||||
}
|
||||
|
||||
public static void showUpdateDialog(final Activity context, final OsmandSettings settings,
|
||||
final ArrayList<LocalIndexInfo> mapsList, int countEnabled,
|
||||
@Nullable final LiveUpdateListener listener) {
|
||||
if (!Algorithms.isEmpty(mapsList)) {
|
||||
if (countEnabled == 1) {
|
||||
LocalIndexInfo li = mapsList.get(0);
|
||||
runLiveUpdate(context, li.getFileName(), false, listener);
|
||||
} else if (countEnabled > 1) {
|
||||
AlertDialog.Builder bld = new AlertDialog.Builder(context);
|
||||
bld.setMessage(R.string.update_all_maps_now);
|
||||
bld.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
for (LocalIndexInfo li : mapsList) {
|
||||
CommonPreference<Boolean> localUpdateOn = preferenceForLocalIndex(li.getFileName(), settings);
|
||||
if (localUpdateOn.get()) {
|
||||
runLiveUpdate(context, li.getFileName(), false, listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
bld.setNegativeButton(R.string.shared_string_no, null);
|
||||
bld.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void enableLiveUpdates(boolean enable) {
|
||||
if (!Algorithms.isEmpty(adapter.mapsList)) {
|
||||
AlarmManager alarmMgr = (AlarmManager) app.getSystemService(Context.ALARM_SERVICE);
|
||||
for (LocalIndexInfo li : adapter.mapsList) {
|
||||
CommonPreference<Boolean> localUpdateOn = preferenceForLocalIndex(li.getFileName(), settings);
|
||||
if (localUpdateOn.get()) {
|
||||
String fileName = li.getFileName();
|
||||
PendingIntent alarmIntent = getPendingIntent(app, fileName);
|
||||
if (enable) {
|
||||
final CommonPreference<Integer> updateFrequencyPreference =
|
||||
preferenceUpdateFrequency(fileName, settings);
|
||||
final CommonPreference<Integer> timeOfDayPreference =
|
||||
preferenceTimeOfDayToUpdate(fileName, settings);
|
||||
UpdateFrequency updateFrequency = UpdateFrequency.values()[updateFrequencyPreference.get()];
|
||||
TimeOfDay timeOfDayToUpdate = TimeOfDay.values()[timeOfDayPreference.get()];
|
||||
setAlarmForPendingIntent(alarmIntent, alarmMgr, updateFrequency, timeOfDayToUpdate);
|
||||
} else {
|
||||
alarmMgr.cancel(alarmIntent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void expandAllGroups() {
|
||||
for (int i = 0; i < adapter.getGroupCount(); i++) {
|
||||
listView.expandGroup(i);
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyLiveUpdatesChanged() {
|
||||
if (getActivity() != null) {
|
||||
runSort();
|
||||
}
|
||||
}
|
||||
|
||||
public static int updateCountEnabled(TextView countView, ArrayList<LocalIndexInfo> mapsList, OsmandSettings settings) {
|
||||
int countEnabled = 0;
|
||||
if (countView != null) {
|
||||
for (LocalIndexInfo map : mapsList) {
|
||||
CommonPreference<Boolean> preference = preferenceForLocalIndex(map.getFileName(), settings);
|
||||
if (preference.get()) {
|
||||
countEnabled++;
|
||||
}
|
||||
}
|
||||
String countText = countEnabled + "/" + mapsList.size();
|
||||
countView.setText(countText);
|
||||
}
|
||||
return countEnabled;
|
||||
}
|
||||
|
||||
protected class LiveMapsAdapter extends OsmandBaseExpandableListAdapter implements LocalIndexInfoAdapter {
|
||||
private final ArrayList<LocalIndexInfo> mapsList = new ArrayList<>();
|
||||
private int countEnabled = 0;
|
||||
private TextViewEx countView;
|
||||
|
||||
@Override
|
||||
public void addData(LocalIndexInfo info) {
|
||||
mapsList.add(info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearData() {
|
||||
mapsList.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataUpdated() {
|
||||
sort();
|
||||
countEnabled = updateCountEnabled(countView, mapsList, settings);
|
||||
}
|
||||
|
||||
public void sort() {
|
||||
Collections.sort(mapsList);
|
||||
Collections.sort(mapsList, new Comparator<LocalIndexInfo>() {
|
||||
@Override
|
||||
public int compare(LocalIndexInfo o1, LocalIndexInfo o2) {
|
||||
CommonPreference<Boolean> preference1 = preferenceForLocalIndex(o1.getFileName(), getSettings());
|
||||
CommonPreference<Boolean> preference2 = preferenceForLocalIndex(o2.getFileName(), getSettings());
|
||||
return preference2.get().compareTo(preference1.get());
|
||||
}
|
||||
});
|
||||
notifyDataSetInvalidated();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalIndexInfo getChild(int groupPosition, int childPosition) {
|
||||
return mapsList.get(childPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getChildId(int groupPosition, int childPosition) {
|
||||
return groupPosition * 10000 + childPosition; // it would be unusable to have 10000 local indexes
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getChildView(final int groupPosition, final int childPosition,
|
||||
boolean isLastChild, View convertView, ViewGroup parent) {
|
||||
LayoutInflater inflater = UiUtilities.getInflater(app, nightMode);
|
||||
convertView = inflater.inflate(R.layout.list_item_triple_row_icon_and_menu, parent, false);
|
||||
LiveMapsViewHolder viewHolder = new LiveMapsViewHolder(convertView);
|
||||
convertView.setTag(viewHolder);
|
||||
viewHolder.bindLocalIndexInfo(getChild(groupPosition, childPosition).getFileName());
|
||||
return convertView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
|
||||
View view = convertView;
|
||||
if (view == null) {
|
||||
LayoutInflater inflater = UiUtilities.getInflater(app, nightMode);
|
||||
view = inflater.inflate(R.layout.list_group_title_with_right_descr, parent, false);
|
||||
}
|
||||
view.setOnClickListener(null);
|
||||
View topShadowView = view.findViewById(R.id.bottomShadowView);
|
||||
if (groupPosition == 0) {
|
||||
topShadowView.setVisibility(View.GONE);
|
||||
} else {
|
||||
topShadowView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
TextViewEx titleView = ((TextViewEx) view.findViewById(R.id.title));
|
||||
titleView.setText(getGroup(groupPosition));
|
||||
|
||||
countView = ((TextViewEx) view.findViewById(R.id.description));
|
||||
AndroidUtils.setTextSecondaryColor(app, countView, nightMode);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildrenCount(int groupPosition) {
|
||||
return mapsList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGroup(int groupPosition) {
|
||||
return getString(R.string.available_maps);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGroupCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getGroupId(int groupPosition) {
|
||||
return groupPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStableIds() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChildSelectable(int groupPosition, int childPosition) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class LiveMapsViewHolder {
|
||||
private final ImageView statusIcon;
|
||||
private final TextView title;
|
||||
private final TextView subTitle;
|
||||
private final TextView description;
|
||||
private final CompoundButton option;
|
||||
|
||||
private LiveMapsViewHolder(View view) {
|
||||
statusIcon = (AppCompatImageView) view.findViewById(R.id.icon);
|
||||
title = (TextView) view.findViewById(R.id.title);
|
||||
subTitle = (TextView) view.findViewById(R.id.sub_title);
|
||||
description = (TextView) view.findViewById(R.id.description);
|
||||
option = (CompoundButton) view.findViewById(R.id.compound_button);
|
||||
}
|
||||
|
||||
public void bindLocalIndexInfo(@NonNull final String item) {
|
||||
boolean liveUpdateOn = settings.IS_LIVE_UPDATES_ON.get();
|
||||
CommonPreference<Boolean> localUpdateOn = preferenceForLocalIndex(item, settings);
|
||||
// IncrementalChangesManager changesManager = app.getResourceManager().getChangesManager();
|
||||
option.setChecked(localUpdateOn.get());
|
||||
if (!liveUpdateOn && localUpdateOn.get()) {
|
||||
UiUtilities.setupCompoundButton(nightMode, ContextCompat.getColor(app, getTertiaryTextColorId(nightMode)), option);
|
||||
} else {
|
||||
UiUtilities.setupCompoundButton(option, nightMode, CompoundButtonType.GLOBAL);
|
||||
}
|
||||
|
||||
title.setText(getNameToDisplay(item, app));
|
||||
|
||||
AndroidUiHelper.updateVisibility(subTitle, localUpdateOn.get());
|
||||
if (localUpdateOn.get()) {
|
||||
int frequencyId = preferenceUpdateFrequency(item, settings).get();
|
||||
final UpdateFrequency frequency = UpdateFrequency.values()[frequencyId];
|
||||
String subTitleText = getString(frequency.getLocalizedId());
|
||||
/*int timeOfDateToUpdateId = preferenceTimeOfDayToUpdate(item, settings).get();
|
||||
final TimeOfDay timeOfDay = TimeOfDay.values()[timeOfDateToUpdateId];
|
||||
if (frequency != UpdateFrequency.HOURLY) {
|
||||
subTitleText += " • " + getString(timeOfDay.getLocalizedId());
|
||||
}*/
|
||||
subTitle.setText(subTitleText);
|
||||
subTitle.setTextColor(ContextCompat.getColor(app, liveUpdateOn ? getActiveTextColorId(nightMode) : getSecondaryTextColorId(nightMode)));
|
||||
Typeface typeface = FontCache.getFont(app, getString(R.string.font_roboto_medium));
|
||||
subTitle.setTypeface(typeface);
|
||||
}
|
||||
|
||||
Drawable statusDrawable = ContextCompat.getDrawable(app, R.drawable.ic_map);
|
||||
int resColorId = !localUpdateOn.get() ? getSecondaryIconColorId(nightMode) :
|
||||
!liveUpdateOn ? getDefaultIconColorId(nightMode) : getOsmandIconColorId(nightMode);
|
||||
int statusColor = ContextCompat.getColor(app, resColorId);
|
||||
if (statusDrawable != null) {
|
||||
DrawableCompat.setTint(statusDrawable, statusColor);
|
||||
}
|
||||
statusIcon.setImageDrawable(statusDrawable);
|
||||
|
||||
description.setText(getLastCheckString(item, app));
|
||||
|
||||
if (InAppPurchaseHelper.isSubscribedToLiveUpdates(app)) {
|
||||
option.setEnabled(liveUpdateOn);
|
||||
option.setOnCheckedChangeListener(new SwitchCompat.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
onUpdateLocalIndex(item, isChecked, null);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
option.setEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class GetLastUpdateDateTask extends AsyncTask<Void, Void, String> {
|
||||
|
||||
private final OsmandApplication app;
|
||||
private final WeakReference<LiveUpdatesFragmentNew> fragment;
|
||||
|
||||
GetLastUpdateDateTask(LiveUpdatesFragmentNew fragment) {
|
||||
this.fragment = new WeakReference<>(fragment);
|
||||
app = fragment.getMyApplication();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doInBackground(Void... params) {
|
||||
try {
|
||||
return AndroidNetworkUtils.sendRequest(app, URL, null,
|
||||
"Requesting map updates info...", false, false);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error: " + "Requesting map updates info error", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String response) {
|
||||
LiveUpdatesFragmentNew f = fragment.get();
|
||||
if (response != null && f != null) {
|
||||
TextViewEx descriptionTime = f.descriptionTime;
|
||||
if (descriptionTime != null) {
|
||||
SimpleDateFormat source = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US);
|
||||
source.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
SimpleDateFormat dest = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US);
|
||||
dest.setTimeZone(TimeZone.getDefault());
|
||||
try {
|
||||
LOG.debug("response = " + response);
|
||||
Date parsed = source.parse(response);
|
||||
if (parsed != null) {
|
||||
long dateTime = parsed.getTime();
|
||||
LOG.debug("dateTime = " + dateTime);
|
||||
descriptionTime.setText(dest.format(parsed));
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
LOG.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static String getLastCheckString(String fileName, OsmandApplication app) {
|
||||
return getLastCheckString(fileName, app, false);
|
||||
}
|
||||
|
||||
protected static String getLastCheckString(String fileName, OsmandApplication app, boolean lastTimeChecked) {
|
||||
OsmandSettings settings = app.getSettings();
|
||||
|
||||
final long lastUpdate = preferenceLatestUpdateAvailable(fileName, settings).get();
|
||||
String lastUpdateString = formatShortDateTime(app, lastUpdate);
|
||||
String description = app.getString(R.string.updated, lastUpdateString);
|
||||
|
||||
if (lastTimeChecked) {
|
||||
final long lastCheck = preferenceLastCheck(fileName, settings).get();
|
||||
String lastCheckString = formatShortDateTime(app, lastCheck);
|
||||
if (!lastUpdateString.equals(app.getString(R.string.shared_string_never))) {
|
||||
description = description.concat("\n" + app.getString(R.string.last_time_checked, lastCheckString));
|
||||
}
|
||||
}
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onUpdateLocalIndex(String fileName, boolean newValue, final Runnable callback) {
|
||||
|
||||
int frequencyId = preferenceUpdateFrequency(fileName, settings).get();
|
||||
int timeOfDateToUpdateId = preferenceTimeOfDayToUpdate(fileName, settings).get();
|
||||
final AlarmManager alarmManager = (AlarmManager) app.getSystemService(Context.ALARM_SERVICE);
|
||||
final PendingIntent alarmIntent = getPendingIntent(app, fileName);
|
||||
|
||||
final CommonPreference<Boolean> liveUpdatePreference = preferenceForLocalIndex(fileName, settings);
|
||||
liveUpdatePreference.set(newValue);
|
||||
if (settings.IS_LIVE_UPDATES_ON.get() && liveUpdatePreference.get()) {
|
||||
runLiveUpdate(getActivity(), fileName, true, new LiveUpdateListener() {
|
||||
@Override
|
||||
public void processFinish() {
|
||||
runSort();
|
||||
if (callback != null) {
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
UpdateFrequency updateFrequency = UpdateFrequency.values()[frequencyId];
|
||||
TimeOfDay timeOfDayToUpdate = TimeOfDay.values()[timeOfDateToUpdateId];
|
||||
setAlarmForPendingIntent(alarmIntent, alarmManager, updateFrequency, timeOfDayToUpdate);
|
||||
} else {
|
||||
alarmManager.cancel(alarmIntent);
|
||||
runSort();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forceUpdateLocal(String fileName, boolean userRequested, final Runnable callback) {
|
||||
if (settings.IS_LIVE_UPDATES_ON.get()) {
|
||||
runLiveUpdate(getActivity(), fileName, userRequested, new LiveUpdateListener() {
|
||||
@Override
|
||||
public void processFinish() {
|
||||
updateList();
|
||||
if (callback != null) {
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runSort() {
|
||||
if (adapter != null) {
|
||||
adapter.onDataUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateList() {
|
||||
if (adapter != null) {
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@ColorRes
|
||||
public static int getDefaultIconColorId(boolean nightMode) {
|
||||
return nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light;
|
||||
}
|
||||
|
||||
}
|
|
@ -5,18 +5,22 @@ import android.app.PendingIntent;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.text.format.DateUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.liveupdates.PerformLiveUpdateAsyncTask.LiveUpdateListener;
|
||||
import net.osmand.plus.settings.backend.CommonPreference;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.activities.OsmandActionBarActivity;
|
||||
import net.osmand.plus.helpers.FileNameTranslationHelper;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Calendar;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class LiveUpdatesHelper {
|
||||
private static final String UPDATE_TIMES_POSTFIX = "_update_times";
|
||||
|
@ -25,6 +29,7 @@ public class LiveUpdatesHelper {
|
|||
private static final String LIVE_UPDATES_ON_POSTFIX = "_live_updates_on";
|
||||
private static final String LAST_UPDATE_ATTEMPT_ON_POSTFIX = "_last_update_attempt";
|
||||
public static final String LOCAL_INDEX_INFO = "local_index_info";
|
||||
public static final String LIVE_UPDATES_LAST_AVAILABLE = "live_updates_last_available";
|
||||
|
||||
|
||||
private static final int MORNING_UPDATE_TIME = 8;
|
||||
|
@ -45,6 +50,7 @@ public class LiveUpdatesHelper {
|
|||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
public static CommonPreference<Boolean> preferenceForLocalIndex(
|
||||
String fileName, OsmandSettings settings) {
|
||||
final String settingId = fileName + LIVE_UPDATES_ON_POSTFIX;
|
||||
|
@ -81,9 +87,19 @@ public class LiveUpdatesHelper {
|
|||
return checkPref(settings.registerLongPreference(settingId, DEFAULT_LAST_CHECK));
|
||||
}
|
||||
|
||||
public static String getNameToDisplay(String fileName, OsmandActionBarActivity activity) {
|
||||
return FileNameTranslationHelper.getFileName(activity,
|
||||
activity.getMyApplication().getResourceManager().getOsmandRegions(),
|
||||
public static CommonPreference<Long> preferenceLatestUpdateAvailable(
|
||||
String fileName, OsmandSettings settings) {
|
||||
final String settingId = fileName + LIVE_UPDATES_LAST_AVAILABLE;
|
||||
return checkPref(settings.registerLongPreference(settingId, DEFAULT_LAST_CHECK));
|
||||
}
|
||||
|
||||
public static CommonPreference<Long> preferenceLatestUpdateAvailable(OsmandSettings settings) {
|
||||
return checkPref(settings.registerLongPreference(LIVE_UPDATES_LAST_AVAILABLE, DEFAULT_LAST_CHECK));
|
||||
}
|
||||
|
||||
public static String getNameToDisplay(String fileName, OsmandApplication context) {
|
||||
return FileNameTranslationHelper.getFileName(context,
|
||||
context.getResourceManager().getOsmandRegions(),
|
||||
fileName);
|
||||
}
|
||||
|
||||
|
@ -93,6 +109,70 @@ public class LiveUpdatesHelper {
|
|||
return dateFormat.format(dateTime) + " " + timeFormat.format(dateTime);
|
||||
}
|
||||
|
||||
public static boolean isCurrentYear(long dateTime) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(dateTime);
|
||||
return calendar.get(Calendar.YEAR) == Calendar.getInstance().get(Calendar.YEAR);
|
||||
}
|
||||
|
||||
public static String formatShortDateTime(Context ctx, long dateTime) {
|
||||
if (dateTime == DEFAULT_LAST_CHECK) {
|
||||
return ctx.getResources().getString(R.string.shared_string_never);
|
||||
} else {
|
||||
String date, times;
|
||||
if (DateUtils.isToday(dateTime)) {
|
||||
date = ctx.getResources().getString(R.string.today);
|
||||
} else {
|
||||
int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_MONTH;
|
||||
if (isCurrentYear(dateTime)) {
|
||||
flags = flags | DateUtils.FORMAT_NO_YEAR;
|
||||
}
|
||||
date = DateUtils.formatDateTime(ctx, dateTime, flags);
|
||||
}
|
||||
times = DateUtils.formatDateTime(ctx, dateTime, DateUtils.FORMAT_SHOW_TIME);
|
||||
String pattern = ctx.getString(R.string.ltr_or_rtl_combine_via_dash);
|
||||
return String.format(pattern, date, times);
|
||||
}
|
||||
}
|
||||
|
||||
public static String formatHelpDateTime(Context ctx, UpdateFrequency updateFrequency, TimeOfDay timeOfDay, long lastDateTime) {
|
||||
if (lastDateTime == DEFAULT_LAST_CHECK) {
|
||||
lastDateTime = System.currentTimeMillis();
|
||||
}
|
||||
switch (updateFrequency) {
|
||||
case DAILY: {
|
||||
return helpDateTimeBuilder(ctx, R.string.live_update_frequency_day_variant, lastDateTime, 1, TimeUnit.DAYS, timeOfDay);
|
||||
}
|
||||
case WEEKLY: {
|
||||
return helpDateTimeBuilder(ctx, R.string.live_update_frequency_week_variant, lastDateTime, 7, TimeUnit.DAYS, timeOfDay);
|
||||
}
|
||||
default:
|
||||
case HOURLY: {
|
||||
return helpDateTimeBuilder(ctx, R.string.live_update_frequency_hour_variant, lastDateTime, 1, TimeUnit.HOURS, timeOfDay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String helpDateTimeBuilder(Context ctx, int stringResId, long lastDateTime, long sourceDuration, TimeUnit sourceUnit, TimeOfDay timeOfDay) {
|
||||
long nextDateTime = lastDateTime + TimeUnit.MILLISECONDS.convert(sourceDuration, sourceUnit);
|
||||
|
||||
if (sourceUnit != TimeUnit.HOURS) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(nextDateTime);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, timeOfDay == TimeOfDay.MORNING ? MORNING_UPDATE_TIME : NIGHT_UPDATE_TIME);
|
||||
nextDateTime = calendar.getTimeInMillis();
|
||||
}
|
||||
|
||||
int flagsBase = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_MONTH;
|
||||
int flagsBaseNoYear = flagsBase | DateUtils.FORMAT_NO_YEAR;
|
||||
int flagsTime = DateUtils.FORMAT_SHOW_TIME;
|
||||
|
||||
String date = DateUtils.formatDateTime(ctx, nextDateTime, isCurrentYear(nextDateTime) ? flagsBaseNoYear : flagsBase);
|
||||
String time = DateUtils.formatDateTime(ctx, nextDateTime, flagsTime);
|
||||
|
||||
return ctx.getResources().getString(stringResId, DateUtils.isToday(nextDateTime) ? "" : " " + date, time);
|
||||
}
|
||||
|
||||
public static PendingIntent getPendingIntent(@NonNull Context context,
|
||||
@NonNull String fileName) {
|
||||
Intent intent = new Intent(context, LiveUpdatesAlarmReceiver.class);
|
||||
|
@ -168,13 +248,14 @@ public class LiveUpdatesHelper {
|
|||
public int getLocalizedId() {
|
||||
return localizedId;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
}
|
||||
|
||||
public static void runLiveUpdate(Context context, final String fileName, boolean userRequested) {
|
||||
public static void runLiveUpdate(Context context, final String fileName, boolean userRequested, @Nullable final LiveUpdateListener listener) {
|
||||
final String fnExt = Algorithms.getFileNameWithoutExtension(new File(fileName));
|
||||
new PerformLiveUpdateAsyncTask(context, fileName, userRequested).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, fnExt);
|
||||
new PerformLiveUpdateAsyncTask(context, fileName, userRequested, listener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, fnExt);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ public class LiveUpdatesSettingsDialogFragment extends DialogFragment {
|
|||
final View updateTimesOfDayLayout = view.findViewById(R.id.updateTimesOfDayLayout);
|
||||
sizeTextView = (TextView) view.findViewById(R.id.sizeTextView);
|
||||
|
||||
regionNameTextView.setText(getNameToDisplay(fileName, getMyActivity()));
|
||||
regionNameTextView.setText(getNameToDisplay(fileName, getMyActivity().getMyApplication()));
|
||||
fileNameWithoutExtension = Algorithms.getFileNameWithoutExtension(new File(fileName));
|
||||
final IncrementalChangesManager changesManager = getMyApplication().getResourceManager().getChangesManager();
|
||||
final long timestamp = changesManager.getTimestamp(fileNameWithoutExtension);
|
||||
|
@ -167,7 +167,7 @@ public class LiveUpdatesSettingsDialogFragment extends DialogFragment {
|
|||
timeOfDayPreference.set(timeOfDayInt);
|
||||
|
||||
if (liveUpdatesSwitch.isChecked() && getSettings().IS_LIVE_UPDATES_ON.get()) {
|
||||
runLiveUpdate(getActivity(), fileName, false);
|
||||
runLiveUpdate(getActivity(), fileName, false, null);
|
||||
UpdateFrequency updateFrequency = UpdateFrequency.values()[updateFrequencyInt];
|
||||
TimeOfDay timeOfDayToUpdate = TimeOfDay.values()[timeOfDayInt];
|
||||
setAlarmForPendingIntent(alarmIntent, alarmMgr, updateFrequency, timeOfDayToUpdate);
|
||||
|
@ -194,7 +194,7 @@ public class LiveUpdatesSettingsDialogFragment extends DialogFragment {
|
|||
if (!getSettings().isInternetConnectionAvailable()) {
|
||||
getMyApplication().showShortToastMessage(R.string.no_internet_connection);
|
||||
} else {
|
||||
runLiveUpdate(getActivity(), fileName, true);
|
||||
runLiveUpdate(getActivity(), fileName, true, null);
|
||||
final IncrementalChangesManager changesManager = getMyApplication().getResourceManager().getChangesManager();
|
||||
sizeTextView.setText(getUpdatesSize(getMyActivity(), fileNameWithoutExtension, changesManager));
|
||||
dialog.dismiss();
|
||||
|
|
|
@ -0,0 +1,548 @@
|
|||
package net.osmand.plus.liveupdates;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.text.SpannableString;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.ColorRes;
|
||||
import androidx.annotation.DimenRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.appcompat.widget.AppCompatImageView;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.base.MenuBottomSheetDialogFragment;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithCompoundButton;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription;
|
||||
import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerSpaceItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.ShortDescriptionItem;
|
||||
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||
import net.osmand.plus.helpers.FontCache;
|
||||
import net.osmand.plus.liveupdates.LiveUpdatesClearDialogFragment.RefreshLiveUpdates;
|
||||
import net.osmand.plus.liveupdates.LiveUpdatesHelper.TimeOfDay;
|
||||
import net.osmand.plus.liveupdates.LiveUpdatesHelper.UpdateFrequency;
|
||||
import net.osmand.plus.resources.IncrementalChangesManager;
|
||||
import net.osmand.plus.settings.backend.CommonPreference;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.widgets.MultiStateToggleButton;
|
||||
import net.osmand.plus.widgets.MultiStateToggleButton.OnRadioItemClickListener;
|
||||
import net.osmand.plus.widgets.MultiStateToggleButton.RadioItem;
|
||||
import net.osmand.plus.widgets.TextViewEx;
|
||||
import net.osmand.plus.widgets.style.CustomTypefaceSpan;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static net.osmand.AndroidUtils.getPrimaryTextColorId;
|
||||
import static net.osmand.AndroidUtils.getSecondaryTextColorId;
|
||||
import static net.osmand.plus.UiUtilities.CompoundButtonType.TOOLBAR;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.formatHelpDateTime;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.formatShortDateTime;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.getNameToDisplay;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceDownloadViaWiFi;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceForLocalIndex;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLastCheck;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLatestUpdateAvailable;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceTimeOfDayToUpdate;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceUpdateFrequency;
|
||||
import static net.osmand.plus.settings.bottomsheets.BooleanPreferenceBottomSheet.getCustomButtonView;
|
||||
import static net.osmand.plus.settings.bottomsheets.BooleanPreferenceBottomSheet.updateCustomButtonView;
|
||||
|
||||
public class LiveUpdatesSettingsDialogFragmentNew extends MenuBottomSheetDialogFragment implements RefreshLiveUpdates {
|
||||
|
||||
public static final String TAG = LiveUpdatesSettingsDialogFragmentNew.class.getSimpleName();
|
||||
private static final Log LOG = PlatformUtil.getLog(LiveUpdatesSettingsDialogFragmentNew.class);
|
||||
private static final String LOCAL_INDEX_FILE_NAME = "local_index_file_name";
|
||||
|
||||
private OsmandApplication app;
|
||||
private OsmandSettings settings;
|
||||
private OnLiveUpdatesForLocalChange onLiveUpdatesForLocalChange;
|
||||
private MultiStateToggleButton frequencyToggleButton;
|
||||
private MultiStateToggleButton timeOfDayToggleButton;
|
||||
|
||||
private String fileName;
|
||||
private int indexLastCheckItem = -1;
|
||||
private int indexSwitchLiveUpdateItem = -1;
|
||||
private int indexFrequencyHelpMessageItem = -1;
|
||||
private int indexClearItem = -1;
|
||||
private int indexViaWiFiItem = -1;
|
||||
|
||||
public static void showInstance(@NonNull FragmentManager fragmentManager, Fragment target, String fileName) {
|
||||
if (!fragmentManager.isStateSaved()) {
|
||||
LiveUpdatesSettingsDialogFragmentNew fragment = new LiveUpdatesSettingsDialogFragmentNew();
|
||||
fragment.setTargetFragment(target, 0);
|
||||
fragment.fileName = fileName;
|
||||
fragment.show(fragmentManager, TAG);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createMenuItems(Bundle savedInstanceState) {
|
||||
app = getMyApplication();
|
||||
settings = app.getSettings();
|
||||
LayoutInflater inflater = UiUtilities.getInflater(app, nightMode);
|
||||
if (getTargetFragment() instanceof OnLiveUpdatesForLocalChange) {
|
||||
onLiveUpdatesForLocalChange = (OnLiveUpdatesForLocalChange) getTargetFragment();
|
||||
}
|
||||
if (savedInstanceState != null && savedInstanceState.containsKey(LOCAL_INDEX_FILE_NAME)) {
|
||||
fileName = savedInstanceState.getString(LOCAL_INDEX_FILE_NAME);
|
||||
}
|
||||
CommonPreference<Boolean> localUpdatePreference = preferenceForLocalIndex(fileName, settings);
|
||||
CommonPreference<Boolean> downloadViaWiFiPreference = preferenceDownloadViaWiFi(fileName, settings);
|
||||
CommonPreference<Integer> frequencyPreference = preferenceUpdateFrequency(fileName, settings);
|
||||
CommonPreference<Integer> timeOfDayPreference = preferenceTimeOfDayToUpdate(fileName, settings);
|
||||
int dp12 = getDimen(R.dimen.content_padding_small);
|
||||
int dp16 = getDimen(R.dimen.content_padding);
|
||||
int dp40 = getDimen(R.dimen.list_header_height);
|
||||
int dp48 = getDimen(R.dimen.context_menu_buttons_bottom_height);
|
||||
|
||||
items.add(new SimpleBottomSheetItem.Builder()
|
||||
.setTitle(getNameToDisplay(fileName, app))
|
||||
.setTitleColorId(getPrimaryTextColorId(nightMode))
|
||||
.setLayoutId(R.layout.bottom_sheet_item_title_big)
|
||||
.create());
|
||||
|
||||
items.add(new ShortDescriptionItem.Builder()
|
||||
.setDescription(getLastCheckString())
|
||||
.setDescriptionColorId(getSecondaryTextColorId(nightMode))
|
||||
.setDescriptionMaxLines(2)
|
||||
.setLayoutId(R.layout.bottom_sheet_item_description)
|
||||
.create());
|
||||
indexLastCheckItem = items.size() - 1;
|
||||
|
||||
View itemLiveUpdate = getCustomButtonView(app, null, localUpdatePreference.get(), nightMode);
|
||||
View itemLiveUpdateButton = itemLiveUpdate.findViewById(R.id.button_container);
|
||||
CompoundButton button = (CompoundButton) itemLiveUpdateButton.findViewById(R.id.compound_button);
|
||||
UiUtilities.setupCompoundButton(button, nightMode, TOOLBAR);
|
||||
itemLiveUpdateButton.setMinimumHeight(getDimen(R.dimen.bottom_sheet_selected_item_title_height));
|
||||
items.add(new BottomSheetItemWithCompoundButton.Builder()
|
||||
.setChecked(localUpdatePreference.get())
|
||||
.setTitle(getStateText(localUpdatePreference.get()))
|
||||
.setTitleColorId(getActiveTabTextColorId(nightMode))
|
||||
.setCustomView(itemLiveUpdate)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (indexSwitchLiveUpdateItem != -1) {
|
||||
BottomSheetItemWithCompoundButton button = (BottomSheetItemWithCompoundButton) items.get(indexSwitchLiveUpdateItem);
|
||||
button.setChecked(!button.isChecked());
|
||||
if (onLiveUpdatesForLocalChange != null
|
||||
&& onLiveUpdatesForLocalChange.onUpdateLocalIndex(fileName, button.isChecked(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateLastCheck();
|
||||
updateFrequencyHelpMessage();
|
||||
updateFileSize();
|
||||
}
|
||||
})) {
|
||||
if (indexSwitchLiveUpdateItem != -1 && items.size() > 0) {
|
||||
button.setTitle(getStateText(button.isChecked()));
|
||||
updateCustomButtonView(app, null, button.getView(), button.isChecked(), nightMode);
|
||||
}
|
||||
CommonPreference<Boolean> localUpdatePreference = preferenceForLocalIndex(fileName, settings);
|
||||
frequencyToggleButton.updateView(localUpdatePreference.get());
|
||||
timeOfDayToggleButton.updateView(localUpdatePreference.get());
|
||||
setStateViaWiFiButton(localUpdatePreference);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.create());
|
||||
indexSwitchLiveUpdateItem = items.size() - 1;
|
||||
|
||||
TextViewEx frequencyTitle = (TextViewEx) inflater.inflate(R.layout.bottom_sheet_item_title, null);
|
||||
frequencyTitle.setHeight(dp48);
|
||||
frequencyTitle.setMinimumHeight(dp48);
|
||||
frequencyTitle.setText(R.string.update_frequency);
|
||||
AndroidUtils.setPadding(frequencyTitle, frequencyTitle.getPaddingLeft(), 0, frequencyTitle.getPaddingRight(), 0);
|
||||
AndroidUtils.setTextPrimaryColor(app, frequencyTitle, nightMode);
|
||||
items.add(new BaseBottomSheetItem.Builder()
|
||||
.setCustomView(frequencyTitle)
|
||||
.create());
|
||||
|
||||
LinearLayout itemFrequencyButtons = (LinearLayout) inflater.inflate(R.layout.custom_radio_buttons, null);
|
||||
LinearLayout.MarginLayoutParams itemFrequencyParams = new LinearLayout.MarginLayoutParams(LinearLayout.MarginLayoutParams.MATCH_PARENT, LinearLayout.MarginLayoutParams.WRAP_CONTENT);
|
||||
AndroidUtils.setMargins(itemFrequencyParams, dp16, 0, dp16, dp12);
|
||||
itemFrequencyButtons.setLayoutParams(itemFrequencyParams);
|
||||
|
||||
String hourly = getString(R.string.hourly);
|
||||
String daily = getString(R.string.daily);
|
||||
String weekly = getString(R.string.weekly);
|
||||
RadioItem hourlyButton = new RadioItem(hourly);
|
||||
RadioItem dailyButton = new RadioItem(daily);
|
||||
RadioItem weeklyButton = new RadioItem(weekly);
|
||||
frequencyToggleButton = new MultiStateToggleButton(app, itemFrequencyButtons, nightMode);
|
||||
frequencyToggleButton.setItems(hourlyButton, dailyButton, weeklyButton);
|
||||
setSelectedRadioItem(frequencyToggleButton, frequencyPreference.get(), hourlyButton, dailyButton, weeklyButton);
|
||||
frequencyToggleButton.updateView(localUpdatePreference.get());
|
||||
|
||||
items.add(new BaseBottomSheetItem.Builder()
|
||||
.setCustomView(itemFrequencyButtons)
|
||||
.create());
|
||||
|
||||
TextViewEx timeOfDayTitle = (TextViewEx) inflater.inflate(R.layout.bottom_sheet_item_title, null);
|
||||
timeOfDayTitle.setHeight(dp40);
|
||||
timeOfDayTitle.setMinimumHeight(dp40);
|
||||
timeOfDayTitle.setText(R.string.update_time);
|
||||
AndroidUtils.setPadding(timeOfDayTitle, timeOfDayTitle.getPaddingLeft(), 0, timeOfDayTitle.getPaddingRight(), 0);
|
||||
AndroidUtils.setTextPrimaryColor(app, timeOfDayTitle, nightMode);
|
||||
items.add(new BaseBottomSheetItem.Builder()
|
||||
.setCustomView(timeOfDayTitle)
|
||||
.create());
|
||||
|
||||
LinearLayout itemTimeOfDayButtons = (LinearLayout) inflater.inflate(R.layout.custom_radio_buttons, null);
|
||||
LinearLayout.MarginLayoutParams itemTimeOfDayParams = new LinearLayout.MarginLayoutParams(LinearLayout.MarginLayoutParams.MATCH_PARENT, LinearLayout.MarginLayoutParams.WRAP_CONTENT);
|
||||
AndroidUtils.setMargins(itemTimeOfDayParams, dp16, 0, dp16, getDimen(R.dimen.context_menu_padding_margin_medium));
|
||||
itemTimeOfDayButtons.setLayoutParams(itemTimeOfDayParams);
|
||||
|
||||
String morning = getString(R.string.morning);
|
||||
String night = getString(R.string.night);
|
||||
RadioItem morningButton = new RadioItem(morning);
|
||||
RadioItem nightButton = new RadioItem(night);
|
||||
timeOfDayToggleButton = new MultiStateToggleButton(app, itemTimeOfDayButtons, nightMode);
|
||||
timeOfDayToggleButton.setItems(morningButton, nightButton);
|
||||
setSelectedRadioItem(timeOfDayToggleButton, timeOfDayPreference.get(), morningButton, nightButton);
|
||||
timeOfDayToggleButton.updateView(localUpdatePreference.get());
|
||||
refreshTimeOfDayLayout(frequencyPreference.get(), itemTimeOfDayButtons, timeOfDayTitle);
|
||||
|
||||
hourlyButton.setOnClickListener(getFrequencyButtonListener(UpdateFrequency.HOURLY, itemTimeOfDayButtons, timeOfDayTitle));
|
||||
dailyButton.setOnClickListener(getFrequencyButtonListener(UpdateFrequency.DAILY, itemTimeOfDayButtons, timeOfDayTitle));
|
||||
weeklyButton.setOnClickListener(getFrequencyButtonListener(UpdateFrequency.WEEKLY, itemTimeOfDayButtons, timeOfDayTitle));
|
||||
morningButton.setOnClickListener(getTimeOfDayButtonListener(TimeOfDay.MORNING));
|
||||
nightButton.setOnClickListener(getTimeOfDayButtonListener(TimeOfDay.NIGHT));
|
||||
|
||||
items.add(new BaseBottomSheetItem.Builder()
|
||||
.setCustomView(itemTimeOfDayButtons)
|
||||
.create()
|
||||
);
|
||||
|
||||
items.add(new ShortDescriptionItem.Builder()
|
||||
.setDescription(getFrequencyHelpMessage())
|
||||
.setDescriptionColorId(getSecondaryTextColorId(nightMode))
|
||||
.setLayoutId(R.layout.bottom_sheet_item_description)
|
||||
.create());
|
||||
indexFrequencyHelpMessageItem = items.size() - 1;
|
||||
|
||||
LinearLayout itemUpdateNowButton = (LinearLayout) inflater.inflate(R.layout.bottom_sheet_button_with_icon_center, null);
|
||||
LinearLayout.MarginLayoutParams itemUpdateNowParams = new LinearLayout.MarginLayoutParams(
|
||||
LinearLayout.MarginLayoutParams.MATCH_PARENT, getDimen(R.dimen.measurement_tool_button_height));
|
||||
AndroidUtils.setMargins(itemUpdateNowParams, dp12, dp12, dp16, dp12);
|
||||
itemUpdateNowButton.setLayoutParams(itemUpdateNowParams);
|
||||
((AppCompatImageView) itemUpdateNowButton.findViewById(R.id.button_icon)).setImageDrawable(
|
||||
ContextCompat.getDrawable(app, R.drawable.ic_action_update));
|
||||
UiUtilities.setupDialogButton(nightMode, itemUpdateNowButton, UiUtilities.DialogButtonType.SECONDARY, getString(R.string.update_now));
|
||||
itemUpdateNowButton.setMinimumHeight(AndroidUtils.dpToPx(app, app.getResources().getDimension(R.dimen.dialog_button_height)));
|
||||
|
||||
items.add(new BaseBottomSheetItem.Builder()
|
||||
.setCustomView(itemUpdateNowButton)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (!settings.isInternetConnectionAvailable()) {
|
||||
app.showShortToastMessage(R.string.no_internet_connection);
|
||||
} else {
|
||||
if (onLiveUpdatesForLocalChange != null) {
|
||||
onLiveUpdatesForLocalChange.forceUpdateLocal(fileName, true, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateLastCheck();
|
||||
updateFrequencyHelpMessage();
|
||||
updateFileSize();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.create());
|
||||
|
||||
items.add(createDividerItem());
|
||||
|
||||
int iconDeleteColor = ContextCompat.getColor(app, R.color.color_osm_edit_delete);
|
||||
Drawable iconDelete = AppCompatResources.getDrawable(app, R.drawable.ic_action_delete_dark);
|
||||
|
||||
items.add(
|
||||
new BottomSheetItemWithDescription.Builder()
|
||||
.setDescription(getUpdatesSizeStr())
|
||||
.setIcon(UiUtilities.tintDrawable(iconDelete, iconDeleteColor))
|
||||
.setTitle(getString(R.string.updates_size))
|
||||
.setLayoutId(R.layout.bottom_sheet_item_with_descr_icon_right)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (getUpdatesSize() > 0) {
|
||||
if (getFragmentManager() != null) {
|
||||
LiveUpdatesClearDialogFragment
|
||||
.showInstance(getFragmentManager(),
|
||||
LiveUpdatesSettingsDialogFragmentNew.this, fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.create()
|
||||
);
|
||||
indexClearItem = items.size() - 1;
|
||||
|
||||
items.add(createDividerItem());
|
||||
|
||||
items.add(
|
||||
new BottomSheetItemWithCompoundButton.Builder()
|
||||
.setChecked(downloadViaWiFiPreference.get())
|
||||
.setDescription(getStateText(downloadViaWiFiPreference.get()))
|
||||
.setIconHidden(true)
|
||||
.setTitle(getString(R.string.only_download_over_wifi))
|
||||
.setLayoutId(R.layout.bottom_sheet_item_with_descr_and_switch_56dp)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (preferenceForLocalIndex(fileName, settings).get() && indexViaWiFiItem != -1 && items.size() > 0) {
|
||||
BottomSheetItemWithCompoundButton button = (BottomSheetItemWithCompoundButton) items.get(indexViaWiFiItem);
|
||||
button.setChecked(!button.isChecked());
|
||||
button.setDescription(getStateText(button.isChecked()));
|
||||
preferenceDownloadViaWiFi(fileName, settings).set(button.isChecked());
|
||||
}
|
||||
}
|
||||
})
|
||||
.create()
|
||||
);
|
||||
indexViaWiFiItem = items.size() - 1;
|
||||
|
||||
items.add(new DividerSpaceItem(app, getDimen(R.dimen.context_menu_padding_margin_large)));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
|
||||
View view = super.onCreateView(inflater, parent, savedInstanceState);
|
||||
CommonPreference<Boolean> localUpdatePreference = preferenceForLocalIndex(fileName, settings);
|
||||
setStateViaWiFiButton(localUpdatePreference);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putString(LOCAL_INDEX_FILE_NAME, fileName);
|
||||
}
|
||||
|
||||
private void setStateViaWiFiButton(CommonPreference<Boolean> localUpdatePreference) {
|
||||
if (indexViaWiFiItem != -1 && items.size() > 0) {
|
||||
BottomSheetItemWithCompoundButton button = (BottomSheetItemWithCompoundButton) items.get(indexViaWiFiItem);
|
||||
if (button.getView() != null) {
|
||||
TextView title = button.getView().findViewById(R.id.title);
|
||||
TextView description = button.getView().findViewById(R.id.description);
|
||||
CompoundButton compoundButton = button.getView().findViewById(R.id.compound_button);
|
||||
if (localUpdatePreference.get()) {
|
||||
AndroidUtils.setTextPrimaryColor(app, title, nightMode);
|
||||
AndroidUtils.setTextSecondaryColor(app, description, nightMode);
|
||||
compoundButton.setEnabled(true);
|
||||
} else {
|
||||
AndroidUtils.setTextSecondaryColor(app, title, nightMode);
|
||||
description.setTextColor(ContextCompat.getColor(app, getTertiaryTextColorId(nightMode)));
|
||||
compoundButton.setEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLastCheck() {
|
||||
if (indexLastCheckItem != -1 && items.size() > 0) {
|
||||
((BottomSheetItemWithDescription) items.get(indexLastCheckItem))
|
||||
.setDescription(getLastCheckString());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateFrequencyHelpMessage() {
|
||||
if (indexFrequencyHelpMessageItem != -1 && items.size() > 0) {
|
||||
((BottomSheetItemWithDescription) items.get(indexFrequencyHelpMessageItem))
|
||||
.setDescription(getFrequencyHelpMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateFileSize() {
|
||||
if (indexClearItem != -1 && items.size() > 0) {
|
||||
((BottomSheetItemWithDescription) items.get(indexClearItem))
|
||||
.setDescription(getUpdatesSizeStr());
|
||||
}
|
||||
}
|
||||
|
||||
protected SpannableString getLastCheckString() {
|
||||
final long lastUpdate = preferenceLatestUpdateAvailable(fileName, settings).get();
|
||||
String updatedTimeStr = getString(R.string.updated, formatShortDateTime(app, lastUpdate));
|
||||
if (!updatedTimeStr.contains(getString(R.string.shared_string_never))) {
|
||||
final long lastCheck = preferenceLastCheck(fileName, settings).get();
|
||||
String lastCheckStr = getString(R.string.last_time_checked, formatShortDateTime(app, lastCheck));
|
||||
updatedTimeStr = updatedTimeStr.concat("\n").concat(lastCheckStr);
|
||||
SpannableString spanStr = new SpannableString(updatedTimeStr);
|
||||
Typeface typeface = FontCache.getRobotoMedium(getContext());
|
||||
int start = updatedTimeStr.indexOf(" — ");
|
||||
if (start != -1) {
|
||||
int end = updatedTimeStr.indexOf(lastCheckStr) - 1;
|
||||
spanStr.setSpan(new CustomTypefaceSpan(typeface), start, end, 0);
|
||||
start = updatedTimeStr.lastIndexOf(" — ");
|
||||
if (start != -1) {
|
||||
end = updatedTimeStr.length();
|
||||
spanStr.setSpan(new CustomTypefaceSpan(typeface), start, end, 0);
|
||||
}
|
||||
}
|
||||
return spanStr;
|
||||
}
|
||||
return new SpannableString(updatedTimeStr);
|
||||
}
|
||||
|
||||
protected String getFrequencyHelpMessage() {
|
||||
CommonPreference<Integer> updateFrequency = preferenceUpdateFrequency(fileName, settings);
|
||||
CommonPreference<Integer> timeOfDayToUpdate = preferenceTimeOfDayToUpdate(fileName, settings);
|
||||
final long lastUpdate = preferenceLatestUpdateAvailable(fileName, settings).get();
|
||||
return formatHelpDateTime(app, UpdateFrequency.values()[updateFrequency.get()], TimeOfDay.values()[timeOfDayToUpdate.get()], lastUpdate);
|
||||
}
|
||||
|
||||
private long getUpdatesSize() {
|
||||
IncrementalChangesManager changesManager = app.getResourceManager().getChangesManager();
|
||||
String fileNameWithoutExt = Algorithms.getFileNameWithoutExtension(fileName);
|
||||
return changesManager.getUpdatesSize(fileNameWithoutExt);
|
||||
}
|
||||
|
||||
private String getUpdatesSizeStr() {
|
||||
long updatesSize = getUpdatesSize();
|
||||
return updatesSize > 0
|
||||
? AndroidUtils.formatSize(app, updatesSize)
|
||||
: getString(R.string.ltr_or_rtl_combine_via_space, "0.0", "kB");
|
||||
}
|
||||
|
||||
|
||||
private BaseBottomSheetItem createDividerItem() {
|
||||
DividerItem dividerItem = new DividerItem(app);
|
||||
int start = app.getResources().getDimensionPixelSize(R.dimen.content_padding);
|
||||
int vertical = getResources().getDimensionPixelSize(R.dimen.content_padding_small_half);
|
||||
dividerItem.setMargins(start, vertical, 0, vertical);
|
||||
return dividerItem;
|
||||
}
|
||||
|
||||
private void setSelectedRadioItem(MultiStateToggleButton toggleButton, int position, RadioItem... buttons) {
|
||||
toggleButton.setSelectedItem(buttons[position]);
|
||||
}
|
||||
|
||||
private void refreshTimeOfDayLayout(int position, View... timeOfDayLayouts) {
|
||||
switch (UpdateFrequency.values()[position]) {
|
||||
case HOURLY:
|
||||
for (View timeOfDayLayout : timeOfDayLayouts) {
|
||||
AndroidUiHelper.updateVisibility(timeOfDayLayout, false);
|
||||
}
|
||||
break;
|
||||
case DAILY:
|
||||
case WEEKLY:
|
||||
for (View timeOfDayLayout : timeOfDayLayouts) {
|
||||
AndroidUiHelper.updateVisibility(timeOfDayLayout, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private OnRadioItemClickListener getFrequencyButtonListener(@NonNull final UpdateFrequency type, final View... timeOfDayLayouts) {
|
||||
return new OnRadioItemClickListener() {
|
||||
@Override
|
||||
public boolean onRadioItemClick(RadioItem radioItem, View view) {
|
||||
final CommonPreference<Integer> frequencyPreference = preferenceUpdateFrequency(fileName, settings);
|
||||
setOnRadioItemClick(frequencyPreference, type.ordinal(), timeOfDayLayouts);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private OnRadioItemClickListener getTimeOfDayButtonListener(@NonNull final TimeOfDay type) {
|
||||
return new OnRadioItemClickListener() {
|
||||
@Override
|
||||
public boolean onRadioItemClick(RadioItem radioItem, View view) {
|
||||
final CommonPreference<Integer> timeOfDayPreference = preferenceTimeOfDayToUpdate(fileName, settings);
|
||||
setOnRadioItemClick(timeOfDayPreference, type.ordinal());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void setOnRadioItemClick(CommonPreference<Integer> preference, int newValue, View... timeOfDayLayouts) {
|
||||
CommonPreference<Boolean> liveUpdatePreference = preferenceForLocalIndex(fileName, settings);
|
||||
if (liveUpdatePreference.get()) {
|
||||
preference.set(newValue);
|
||||
if (!Algorithms.isEmpty(Arrays.asList(timeOfDayLayouts))) {
|
||||
refreshTimeOfDayLayout(newValue, timeOfDayLayouts);
|
||||
}
|
||||
updateFrequencyHelpMessage();
|
||||
OnLiveUpdatesForLocalChange confirmationInterface = (OnLiveUpdatesForLocalChange) getTargetFragment();
|
||||
if (confirmationInterface != null) {
|
||||
confirmationInterface.updateList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateStates(Context context) {
|
||||
final OnLiveUpdatesForLocalChange confirmationInterface = (OnLiveUpdatesForLocalChange) getTargetFragment();
|
||||
if (confirmationInterface != null) {
|
||||
confirmationInterface.updateList();
|
||||
}
|
||||
updateLastCheck();
|
||||
updateFileSize();
|
||||
}
|
||||
|
||||
public interface OnLiveUpdatesForLocalChange {
|
||||
|
||||
boolean onUpdateLocalIndex(String fileName, boolean newValue, Runnable callback);
|
||||
|
||||
void forceUpdateLocal(String fileName, boolean userRequested, Runnable callback);
|
||||
|
||||
void runSort();
|
||||
|
||||
void updateList();
|
||||
}
|
||||
|
||||
public int getDimen(@DimenRes int id) {
|
||||
return getResources().getDimensionPixelSize(id);
|
||||
}
|
||||
|
||||
public String getStateText(boolean isEnabled) {
|
||||
return getString(isEnabled ? R.string.shared_string_enabled : R.string.shared_string_disabled);
|
||||
}
|
||||
|
||||
@ColorRes
|
||||
public static int getActiveTabTextColorId(boolean nightMode) {
|
||||
return nightMode ? R.color.text_color_tab_active_dark : R.color.text_color_tab_active_light;
|
||||
}
|
||||
|
||||
@ColorRes
|
||||
public static int getActivePrimaryColorId(boolean nightMode) {
|
||||
return nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light;
|
||||
}
|
||||
|
||||
@ColorRes
|
||||
public static int getTertiaryTextColorId(boolean nightMode) {
|
||||
return nightMode ? R.color.text_color_tertiary_dark : R.color.text_color_tertiary_light;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDismissButtonTextId() {
|
||||
return R.string.shared_string_close;
|
||||
}
|
||||
|
||||
}
|
62
OsmAnd/src/net/osmand/plus/liveupdates/LoadLiveMapsTask.java
Normal file
62
OsmAnd/src/net/osmand/plus/liveupdates/LoadLiveMapsTask.java
Normal file
|
@ -0,0 +1,62 @@
|
|||
package net.osmand.plus.liveupdates;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.activities.LocalIndexHelper;
|
||||
import net.osmand.plus.activities.LocalIndexInfo;
|
||||
import net.osmand.plus.download.ui.AbstractLoadLocalIndexTask;
|
||||
|
||||
public class LoadLiveMapsTask
|
||||
extends AsyncTask<Void, LocalIndexInfo, Void>
|
||||
implements AbstractLoadLocalIndexTask {
|
||||
|
||||
public interface LocalIndexInfoAdapter {
|
||||
void addData(LocalIndexInfo localIndexInfo);
|
||||
|
||||
void clearData();
|
||||
|
||||
void onDataUpdated();
|
||||
}
|
||||
|
||||
private final LocalIndexInfoAdapter adapter;
|
||||
private final LocalIndexHelper helper;
|
||||
|
||||
public LoadLiveMapsTask(LocalIndexInfoAdapter adapter, OsmandApplication app) {
|
||||
this.adapter = adapter;
|
||||
helper = new LocalIndexHelper(app);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
adapter.clearData();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
helper.getLocalFullMaps(this);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFile(LocalIndexInfo... loaded) {
|
||||
publishProgress(loaded);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(LocalIndexInfo... values) {
|
||||
String fileNameL;
|
||||
for (LocalIndexInfo localIndexInfo : values) {
|
||||
fileNameL = localIndexInfo.getFileName().toLowerCase();
|
||||
if (localIndexInfo.getType() == LocalIndexHelper.LocalIndexType.MAP_DATA
|
||||
&& !fileNameL.contains("world") && !fileNameL.startsWith("depth_")) {
|
||||
adapter.addData(localIndexInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
adapter.onDataUpdated();
|
||||
}
|
||||
}
|
|
@ -2,12 +2,10 @@ package net.osmand.plus.liveupdates;
|
|||
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
@ -16,33 +14,22 @@ import androidx.viewpager.widget.ViewPager;
|
|||
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
|
||||
import net.osmand.AndroidNetworkUtils;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.chooseplan.ChoosePlanDialogFragment;
|
||||
import net.osmand.plus.chooseplan.ChoosePlanDialogFragment.ChoosePlanDialogListener;
|
||||
import net.osmand.plus.download.AbstractDownloadActivity;
|
||||
import net.osmand.plus.download.DownloadIndexesThread.DownloadEvents;
|
||||
import net.osmand.plus.inapp.InAppPurchaseHelper;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class OsmLiveActivity extends AbstractDownloadActivity implements DownloadEvents, ChoosePlanDialogListener {
|
||||
public class OsmLiveActivity extends AbstractDownloadActivity implements ChoosePlanDialogListener {
|
||||
private final static Log LOG = PlatformUtil.getLog(OsmLiveActivity.class);
|
||||
public final static String SHOW_SETTINGS_ONLY_INTENT_PARAM = "show_settings_only_intent_param";
|
||||
|
||||
private LiveUpdatesFragmentPagerAdapter pagerAdapter;
|
||||
private boolean showSettingOnly;
|
||||
private GetLastUpdateDateTask getLastUpdateDateTask;
|
||||
private static final String URL = "https://osmand.net/api/osmlive_status";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -67,9 +54,6 @@ public class OsmLiveActivity extends AbstractDownloadActivity implements Downloa
|
|||
tabLayout.setupWithViewPager(viewPager);
|
||||
if (showSettingOnly) {
|
||||
tabLayout.setVisibility(View.GONE);
|
||||
} else {
|
||||
getLastUpdateDateTask = new GetLastUpdateDateTask(this);
|
||||
getLastUpdateDateTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
boolean nightMode = !app.getSettings().isLightContent();
|
||||
|
@ -99,20 +83,6 @@ public class OsmLiveActivity extends AbstractDownloadActivity implements Downloa
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
getMyApplication().getDownloadThread().resetUiActivity(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (getLastUpdateDateTask != null) {
|
||||
getLastUpdateDateTask.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
|
@ -132,64 +102,9 @@ public class OsmLiveActivity extends AbstractDownloadActivity implements Downloa
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void newDownloadIndexes() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void downloadInProgress() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void downloadHasFinished() {
|
||||
((LiveUpdatesFragment) pagerAdapter.fragments[0]).notifyLiveUpdatesChanged();
|
||||
}
|
||||
|
||||
private static class GetLastUpdateDateTask extends AsyncTask<Void, Void, String> {
|
||||
|
||||
private OsmandApplication app;
|
||||
private WeakReference<OsmLiveActivity> activity;
|
||||
|
||||
GetLastUpdateDateTask(OsmLiveActivity activity) {
|
||||
this.activity = new WeakReference<>(activity);
|
||||
app = activity.getMyApplication();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doInBackground(Void... params) {
|
||||
try {
|
||||
return AndroidNetworkUtils.sendRequest(app, URL, null, "Requesting map updates info...", false, false);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error: " + "Requesting map updates info error", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String response) {
|
||||
OsmLiveActivity a = activity.get();
|
||||
if (response != null && a != null) {
|
||||
ActionBar actionBar = a.getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
SimpleDateFormat source = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US);
|
||||
source.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
SimpleDateFormat dest = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US);
|
||||
dest.setTimeZone(TimeZone.getDefault());
|
||||
try {
|
||||
Date parsed = source.parse(response);
|
||||
actionBar.setSubtitle(dest.format(parsed));
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class LiveUpdatesFragmentPagerAdapter extends FragmentPagerAdapter {
|
||||
private final Fragment[] fragments = new Fragment[] { new LiveUpdatesFragment(), new ReportsFragment() };
|
||||
private static final int[] titleIds = new int[] { LiveUpdatesFragment.TITLE, ReportsFragment.TITLE };
|
||||
private final Fragment[] fragments = new Fragment[] { new ReportsFragment() };
|
||||
private static final int[] titleIds = new int[] { ReportsFragment.TITLE };
|
||||
private final String[] titles;
|
||||
private final boolean showSettingsOnly;
|
||||
|
||||
|
|
|
@ -6,9 +6,13 @@ import android.content.Context;
|
|||
import android.os.AsyncTask;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import net.osmand.AndroidNetworkUtils;
|
||||
import net.osmand.AndroidNetworkUtils.OnRequestResultListener;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.download.DownloadActivity;
|
||||
import net.osmand.plus.settings.backend.CommonPreference;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
|
@ -17,12 +21,20 @@ import net.osmand.plus.download.DownloadActivityType;
|
|||
import net.osmand.plus.download.DownloadIndexesThread;
|
||||
import net.osmand.plus.download.IndexItem;
|
||||
import net.osmand.plus.resources.IncrementalChangesManager;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLastCheck;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLatestUpdateAvailable;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceUpdateFrequency;
|
||||
|
||||
public class PerformLiveUpdateAsyncTask
|
||||
|
@ -34,13 +46,20 @@ public class PerformLiveUpdateAsyncTask
|
|||
@NonNull
|
||||
private final String localIndexFileName;
|
||||
private final boolean userRequested;
|
||||
private final LiveUpdateListener listener;
|
||||
|
||||
public interface LiveUpdateListener {
|
||||
void processFinish();
|
||||
}
|
||||
|
||||
public PerformLiveUpdateAsyncTask(@NonNull Context context,
|
||||
@NonNull String localIndexFileName,
|
||||
boolean userRequested) {
|
||||
boolean userRequested,
|
||||
@Nullable LiveUpdateListener listener) {
|
||||
this.context = context;
|
||||
this.localIndexFileName = localIndexFileName;
|
||||
this.userRequested = userRequested;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -52,7 +71,7 @@ public class PerformLiveUpdateAsyncTask
|
|||
}
|
||||
final OsmandApplication myApplication = getMyApplication();
|
||||
CommonPreference<Long> lastCheckPreference =
|
||||
LiveUpdatesHelper.preferenceLastCheck(localIndexFileName, myApplication.getSettings());
|
||||
preferenceLastCheck(localIndexFileName, myApplication.getSettings());
|
||||
lastCheckPreference.set(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
|
@ -129,6 +148,10 @@ public class PerformLiveUpdateAsyncTask
|
|||
if (context instanceof DownloadIndexesThread.DownloadEvents) {
|
||||
((DownloadIndexesThread.DownloadEvents) context).downloadInProgress();
|
||||
}
|
||||
updateLatestAvailability(application, localIndexFileName);
|
||||
if (listener != null) {
|
||||
listener.processFinish();
|
||||
}
|
||||
} else {
|
||||
LOG.debug("onPostExecute: Not enough space for updates");
|
||||
}
|
||||
|
@ -138,7 +161,11 @@ public class PerformLiveUpdateAsyncTask
|
|||
} else {
|
||||
if (context instanceof DownloadIndexesThread.DownloadEvents) {
|
||||
((DownloadIndexesThread.DownloadEvents) context).downloadInProgress();
|
||||
if (userRequested && context instanceof OsmLiveActivity) {
|
||||
if (userRequested && context instanceof DownloadActivity) {
|
||||
updateLatestAvailability(application, localIndexFileName);
|
||||
if (listener != null) {
|
||||
listener.processFinish();
|
||||
}
|
||||
application.showShortToastMessage(R.string.no_updates_available);
|
||||
}
|
||||
}
|
||||
|
@ -170,4 +197,30 @@ public class PerformLiveUpdateAsyncTask
|
|||
settings.LIVE_UPDATES_RETRIES.resetToDefault();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLatestAvailability(OsmandApplication app, @NonNull final String localIndexFileName) {
|
||||
final OsmandSettings settings = app.getSettings();
|
||||
AndroidNetworkUtils.sendRequestAsync(
|
||||
app, LiveUpdatesFragmentNew.URL, null, "Requesting map updates info...", false, false, new OnRequestResultListener() {
|
||||
@Override
|
||||
public void onResult(String result) {
|
||||
if (!Algorithms.isEmpty(result)) {
|
||||
SimpleDateFormat source = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US);
|
||||
source.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
try {
|
||||
Date parsed = source.parse(result);
|
||||
if (parsed != null) {
|
||||
long dateTime = parsed.getTime();
|
||||
preferenceLatestUpdateAvailable(settings).set(dateTime);
|
||||
preferenceLatestUpdateAvailable(localIndexFileName, settings).set(dateTime);
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
long dateTime = preferenceLatestUpdateAvailable(settings).get();
|
||||
preferenceLatestUpdateAvailable(localIndexFileName, settings).set(dateTime);
|
||||
LOG.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ public class MapDataMenuController extends MenuController {
|
|||
} else if (!downloaded || indexItem.isOutdated()) {
|
||||
new DownloadValidationManager(app).startDownload(activity, indexItem);
|
||||
} else if (isLiveUpdatesOn()) {
|
||||
LiveUpdatesHelper.runLiveUpdate(activity, indexItem.getTargetFileName(), true);
|
||||
LiveUpdatesHelper.runLiveUpdate(activity, indexItem.getTargetFileName(), true, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,9 +11,9 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
|
@ -688,7 +688,7 @@ public class PlanRouteFragment extends BaseOsmAndFragment implements OsmAndLocat
|
|||
}
|
||||
});
|
||||
if (!portrait) {
|
||||
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) appModesBtn.getLayoutParams();
|
||||
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) appModesBtn.getLayoutParams();
|
||||
params.leftMargin = mapActivity.getResources().getDimensionPixelSize(R.dimen.dashboard_land_width);
|
||||
appModesBtn.setLayoutParams(params);
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static net.osmand.AndroidUtils.getSecondaryTextColorId;
|
||||
import static net.osmand.plus.UiUtilities.CompoundButtonType.PROFILE_DEPENDENT;
|
||||
|
||||
public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragment {
|
||||
|
@ -612,11 +613,6 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen
|
|||
return nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light;
|
||||
}
|
||||
|
||||
@ColorRes
|
||||
public static int getSecondaryTextColorId(boolean nightMode) {
|
||||
return nightMode ? R.color.text_color_secondary_dark : R.color.text_color_secondary_light;
|
||||
}
|
||||
|
||||
@ColorRes
|
||||
public static int getActiveIconColorId(boolean nightMode) {
|
||||
return nightMode ? R.color.icon_color_active_dark : R.color.icon_color_active_light;
|
||||
|
|
|
@ -6,6 +6,8 @@ import android.graphics.drawable.LayerDrawable;
|
|||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -32,6 +34,10 @@ import net.osmand.plus.settings.preferences.SwitchPreferenceEx;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import static net.osmand.plus.UiUtilities.CompoundButtonType.TOOLBAR;
|
||||
import static net.osmand.plus.liveupdates.LiveUpdatesSettingsDialogFragmentNew.getActivePrimaryColorId;
|
||||
import static net.osmand.plus.monitoring.TripRecordingActiveBottomSheet.getSecondaryIconColorId;
|
||||
|
||||
public class BooleanPreferenceBottomSheet extends BasePreferenceBottomSheet {
|
||||
|
||||
public static final String TAG = BooleanPreferenceBottomSheet.class.getSimpleName();
|
||||
|
@ -125,17 +131,25 @@ public class BooleanPreferenceBottomSheet extends BasePreferenceBottomSheet {
|
|||
public static View getCustomButtonView(OsmandApplication app, ApplicationMode mode, boolean checked, boolean nightMode) {
|
||||
View customView = UiUtilities.getInflater(app, nightMode).inflate(R.layout.bottom_sheet_item_preference_switch, null);
|
||||
updateCustomButtonView(app, mode, customView, checked, nightMode);
|
||||
|
||||
return customView;
|
||||
}
|
||||
|
||||
public static void updateCustomButtonView(OsmandApplication app, ApplicationMode mode, View customView, boolean checked, boolean nightMode) {
|
||||
Context themedCtx = UiUtilities.getThemedContext(app, nightMode);
|
||||
View buttonView = customView.findViewById(R.id.button_container);
|
||||
LinearLayout buttonView = customView.findViewById(R.id.button_container);
|
||||
|
||||
int bgColor;
|
||||
int selectedColor;
|
||||
if (mode != null) {
|
||||
int color = checked ? mode.getProfileColor(nightMode) : AndroidUtils.getColorFromAttr(themedCtx, R.attr.divider_color_basic);
|
||||
int bgColor = UiUtilities.getColorWithAlpha(color, checked ? 0.1f : 0.5f);
|
||||
int selectedColor = UiUtilities.getColorWithAlpha(color, checked ? 0.3f : 0.5f);
|
||||
bgColor = UiUtilities.getColorWithAlpha(color, checked ? 0.1f : 0.5f);
|
||||
selectedColor = UiUtilities.getColorWithAlpha(color, checked ? 0.3f : 0.5f);
|
||||
} else {
|
||||
bgColor = ContextCompat.getColor(app, checked
|
||||
? getActivePrimaryColorId(nightMode) : getSecondaryIconColorId(nightMode));
|
||||
selectedColor = UiUtilities.getColorWithAlpha(
|
||||
ContextCompat.getColor(app, getActivePrimaryColorId(nightMode)), checked ? 0.3f : 0.5f);
|
||||
}
|
||||
|
||||
int bgResId = R.drawable.rectangle_rounded_right;
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
|
||||
|
|
|
@ -101,12 +101,16 @@ public class MultiStateToggleButton {
|
|||
}
|
||||
|
||||
private void updateView() {
|
||||
updateView(true);
|
||||
}
|
||||
|
||||
public void updateView(boolean isEnabled) {
|
||||
int activeColor = ContextCompat.getColor(app, nightMode
|
||||
? R.color.active_color_primary_dark
|
||||
: R.color.active_color_primary_light);
|
||||
? isEnabled ? R.color.active_color_primary_dark : R.color.icon_color_default_dark
|
||||
: isEnabled ? R.color.active_color_primary_light : R.color.icon_color_default_light);
|
||||
int textColor = ContextCompat.getColor(app, nightMode
|
||||
? R.color.text_color_primary_dark
|
||||
: R.color.text_color_primary_light);
|
||||
? isEnabled ? R.color.text_color_primary_dark : R.color.text_color_secondary_dark
|
||||
: isEnabled ? R.color.text_color_primary_light : R.color.text_color_secondary_light);
|
||||
int radius = AndroidUtils.dpToPx(app, 4);
|
||||
float[] leftBtnRadii = new float[]{radius, radius, 0, 0, 0, 0, radius, radius};
|
||||
float[] rightBtnRadii = new float[]{0, 0, radius, radius, radius, radius, 0, 0};
|
||||
|
@ -121,6 +125,7 @@ public class MultiStateToggleButton {
|
|||
for (int i = 0; i < items.size(); i++) {
|
||||
RadioItem item = items.get(i);
|
||||
ViewGroup container = buttons.get(i);
|
||||
container.setEnabled(isEnabled);
|
||||
TextView tvTitle = (TextView) container.findViewById(R.id.title);
|
||||
if (selectedItem == item) {
|
||||
if (i == 0) {
|
||||
|
|
Loading…
Reference in a new issue