Add timeline tab and gpx statistic dialog and sync aidl
This commit is contained in:
parent
bd1709a306
commit
80eda68e01
51 changed files with 3031 additions and 204 deletions
24
OsmAnd-telegram/res/drawable/btn_round_border.xml
Normal file
24
OsmAnd-telegram/res/drawable/btn_round_border.xml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item android:state_pressed="true">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid android:color="@color/ctrl_active_light" />
|
||||||
|
<corners android:radius="@dimen/dialog_button_radius" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item android:state_enabled="false">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid android:color="@color/ctrl_light" />
|
||||||
|
<corners android:radius="@dimen/dialog_button_radius" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid android:color="@null" />
|
||||||
|
<corners android:radius="@dimen/dialog_button_radius" />
|
||||||
|
<stroke android:width="1dp" android:color="@color/app_bar_divider" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
</selector>
|
184
OsmAnd-telegram/res/layout/fragment_timeline_tab.xml
Normal file
184
OsmAnd-telegram/res/layout/fragment_timeline_tab.xml
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
<?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="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<android.support.design.widget.AppBarLayout
|
||||||
|
android:id="@+id/app_bar_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/card_bg_color">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/title_row"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/action_bar_height"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="@dimen/action_bar_height"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:letterSpacing="@dimen/title_letter_spacing"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:paddingLeft="@dimen/content_padding_standard"
|
||||||
|
android:paddingRight="@dimen/content_padding_standard"
|
||||||
|
android:text="@string/timeline"
|
||||||
|
android:textColor="@color/app_bar_title_light"
|
||||||
|
android:textSize="@dimen/title_text_size"
|
||||||
|
app:typeface="@string/font_roboto_mono_bold" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/options"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding_standard"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_standard"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:paddingLeft="@dimen/content_padding_half"
|
||||||
|
android:paddingRight="@dimen/content_padding_half"
|
||||||
|
tools:src="@drawable/ic_action_other_menu"
|
||||||
|
tools:tint="@color/icon_light"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="@dimen/action_bar_descr_bottom_margin"
|
||||||
|
android:paddingLeft="@dimen/content_padding_standard"
|
||||||
|
android:paddingRight="@dimen/content_padding_standard"
|
||||||
|
android:text="@string/timeline_description"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:textSize="@dimen/descr_text_size" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/monitoring_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/action_bar_height"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingLeft="@dimen/content_padding_standard"
|
||||||
|
android:paddingRight="@dimen/content_padding_standard">
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/monitoring_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="center_vertical|start"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:text="@string/monitoring_is_enabled"
|
||||||
|
android:textColor="@color/ctrl_active_light"
|
||||||
|
android:textSize="@dimen/descr_text_size"
|
||||||
|
app:typeface="@string/font_roboto_medium" />
|
||||||
|
|
||||||
|
<Switch
|
||||||
|
android:id="@+id/monitoring_switcher"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="end|center_vertical"
|
||||||
|
android:background="@null"
|
||||||
|
android:clickable="false"
|
||||||
|
android:focusable="false" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="@color/app_bar_divider" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/date_row"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/list_header_height"
|
||||||
|
android:background="@color/screen_bg_light"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingLeft="@dimen/content_padding_standard"
|
||||||
|
android:paddingRight="@dimen/content_padding_standard">
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/date_start_btn"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="@dimen/dialog_button_height"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding_half"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_half"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@drawable/btn_round_border"
|
||||||
|
android:drawablePadding="@dimen/content_padding_half"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="start|center_vertical"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:paddingLeft="@dimen/image_button_padding"
|
||||||
|
android:paddingRight="@dimen/image_button_padding"
|
||||||
|
android:text="@string/start_date"
|
||||||
|
android:textColor="?attr/ctrl_active_color"
|
||||||
|
android:textSize="@dimen/text_button_text_size"
|
||||||
|
app:typeface="@string/font_roboto_medium" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="16dp"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:background="@color/app_bar_divider" />
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/date_end_btn"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="@dimen/dialog_button_height"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding_half"
|
||||||
|
android:layout_marginStart="@dimen/content_padding_half"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@drawable/btn_round_border"
|
||||||
|
android:drawablePadding="@dimen/content_padding_half"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="start|center_vertical"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:paddingLeft="@dimen/image_button_padding"
|
||||||
|
android:paddingRight="@dimen/image_button_padding"
|
||||||
|
android:text="@string/end_date"
|
||||||
|
android:textColor="?attr/ctrl_active_color"
|
||||||
|
android:textSize="@dimen/text_button_text_size"
|
||||||
|
app:typeface="@string/font_roboto_medium" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</android.support.design.widget.AppBarLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/last_telegram_update_time"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="top|center_horizontal"
|
||||||
|
android:gravity="center"
|
||||||
|
android:paddingTop="@dimen/content_padding_half"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:textSize="@dimen/list_item_description_text_size"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:typeface="@string/font_roboto_regular" />
|
||||||
|
|
||||||
|
<android.support.v7.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:paddingBottom="@dimen/list_item_content_margin"
|
||||||
|
android:scrollbars="vertical" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
509
OsmAnd-telegram/res/layout/fragment_user_gpx_info.xml
Normal file
509
OsmAnd-telegram/res/layout/fragment_user_gpx_info.xml
Normal file
|
@ -0,0 +1,509 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ScrollView 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:background="?attr/card_bg_color">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/image_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="120dp"
|
||||||
|
app:layout_scrollFlags="scroll">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/back_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="start"
|
||||||
|
android:layout_marginTop="@dimen/content_padding_standard"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:contentDescription="@string/shared_string_back"
|
||||||
|
android:padding="@dimen/content_padding_standard"
|
||||||
|
tools:src="@drawable/ic_arrow_back"
|
||||||
|
tools:tint="@color/icon_light" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/user_icon"
|
||||||
|
android:layout_width="@dimen/my_location_user_icon_size"
|
||||||
|
android:layout_height="@dimen/my_location_user_icon_size"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginTop="@dimen/content_padding_standard"
|
||||||
|
tools:src="@drawable/img_user_picture" />
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom|center_horizontal"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="center"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:text="@string/start_location_sharing"
|
||||||
|
android:textColor="?android:textColorPrimary"
|
||||||
|
android:textSize="@dimen/title_text_size"
|
||||||
|
app:typeface="@string/font_roboto_mono_bold" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/interval_row"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingLeft="@dimen/content_padding_standard"
|
||||||
|
android:paddingRight="@dimen/content_padding_standard">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/start_descr"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding_standard"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_standard"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:text="@string/start_date"
|
||||||
|
android:textColor="?attr/android:textColorSecondary"
|
||||||
|
android:textSize="@dimen/list_item_description_text_size"
|
||||||
|
app:firstBaselineToTopHeight="@dimen/list_item_baseline_to_top_height"
|
||||||
|
app:typeface="@string/font_roboto_regular" />
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/end_descr"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding_standard"
|
||||||
|
android:layout_marginStart="@dimen/content_padding_standard"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:text="@string/end_date"
|
||||||
|
android:textColor="?attr/android:textColorSecondary"
|
||||||
|
android:textSize="@dimen/list_item_description_text_size"
|
||||||
|
app:firstBaselineToTopHeight="@dimen/list_item_baseline_to_top_height"
|
||||||
|
app:typeface="@string/font_roboto_regular" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/list_header_height"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/date_start_btn"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="@dimen/dialog_button_height"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding_half"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_half"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@drawable/btn_round"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="center"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:paddingLeft="@dimen/image_button_padding"
|
||||||
|
android:paddingRight="@dimen/image_button_padding"
|
||||||
|
android:textSize="@dimen/text_button_text_size"
|
||||||
|
app:typeface="@string/font_roboto_medium"
|
||||||
|
tools:textColor="?attr/ctrl_active_color"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/time_start_btn"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/dialog_button_height"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:background="@drawable/btn_round"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="center"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:paddingLeft="@dimen/image_button_padding"
|
||||||
|
android:paddingRight="@dimen/image_button_padding"
|
||||||
|
android:textSize="@dimen/text_button_text_size"
|
||||||
|
app:typeface="@string/font_roboto_medium"
|
||||||
|
tools:textColor="?attr/ctrl_active_color"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="16dp"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding_half"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_half"
|
||||||
|
android:background="@color/card_divider_light" />
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/date_end_btn"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="@dimen/dialog_button_height"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding_half"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_half"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@drawable/btn_round"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="center"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:paddingLeft="@dimen/image_button_padding"
|
||||||
|
android:paddingRight="@dimen/image_button_padding"
|
||||||
|
android:textSize="@dimen/text_button_text_size"
|
||||||
|
app:typeface="@string/font_roboto_medium"
|
||||||
|
tools:textColor="?attr/ctrl_active_color"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/time_end_btn"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/dialog_button_height"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:background="@drawable/btn_round"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="center"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:paddingLeft="@dimen/image_button_padding"
|
||||||
|
android:paddingRight="@dimen/image_button_padding"
|
||||||
|
android:textSize="@dimen/text_button_text_size"
|
||||||
|
app:typeface="@string/font_roboto_medium"
|
||||||
|
tools:textColor="?attr/ctrl_active_color"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/map_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="152dp"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding_standard"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_standard">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/gpx_map"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:contentDescription="@string/shared_string_map" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/gpx_statistic"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/distance_time_span"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingBottom="11dp"
|
||||||
|
android:paddingTop="13dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingLeft="16dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/distance_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:src="@drawable/ic_action_polygom_dark" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="18dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/distance_desc"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="3dp"
|
||||||
|
android:background="@null"
|
||||||
|
android:text="@string/shared_string_distance"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:textSize="@dimen/list_item_description_text_size" />
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/distance_text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@null"
|
||||||
|
android:text="40 km"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:textSize="@dimen/hint_text_size"
|
||||||
|
app:typeface="@string/font_roboto_medium" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingLeft="16dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/duration_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:src="@drawable/ic_action_share_location" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="18dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/duration_desc"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="3dp"
|
||||||
|
android:background="@null"
|
||||||
|
android:text="@string/time_on_the_move"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:textSize="@dimen/list_item_description_text_size" />
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/duration_text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@null"
|
||||||
|
android:text="3:32:44"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:textSize="@dimen/hint_text_size"
|
||||||
|
app:typeface="@string/font_roboto_medium" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/list_divider"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingRight="8dp">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="@color/card_divider_light" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingLeft="8dp"
|
||||||
|
android:paddingRight="16dp">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="@color/card_divider_light" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/start_end_time"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingBottom="11dp"
|
||||||
|
android:paddingTop="13dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingLeft="16dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/average_speed_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:src="@drawable/ic_action_speed_average" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="18dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/average_speed_desc"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:background="@null"
|
||||||
|
android:text="@string/average_speed"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:textSize="@dimen/list_item_description_text_size" />
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/average_speed_text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@null"
|
||||||
|
android:text="15:04:58"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:textSize="@dimen/hint_text_size"
|
||||||
|
app:typeface="@string/font_roboto_medium" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingLeft="16dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/average_altitude_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:src="@drawable/ic_action_share_location" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="18dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/average_altitude_desc"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:background="@null"
|
||||||
|
android:text="@string/average_altitude"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:textSize="@dimen/list_item_description_text_size" />
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/average_altitude_text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@null"
|
||||||
|
android:text="20:58:00"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:textSize="@dimen/hint_text_size"
|
||||||
|
app:typeface="@string/font_roboto_medium" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/open_in_osmand_btn"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/list_item_height_min"
|
||||||
|
android:layout_marginBottom="@dimen/content_padding_standard"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding_half"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_half"
|
||||||
|
android:background="@drawable/btn_round"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:paddingLeft="@dimen/content_padding_half"
|
||||||
|
android:paddingRight="@dimen/content_padding_half">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/open_in_osmand_icon"
|
||||||
|
android:layout_width="@dimen/list_item_icon_size"
|
||||||
|
android:layout_height="@dimen/list_item_icon_size"
|
||||||
|
android:src="@drawable/ic_logo_osmand_free" />
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/open_in_osmand_title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding_big"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_big"
|
||||||
|
android:text="@string/open_in_osmand"
|
||||||
|
android:textColor="?android:textColorPrimary"
|
||||||
|
android:textSize="@dimen/list_item_title_text_size"
|
||||||
|
app:typeface="@string/font_roboto_medium" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/share_gpx_btn"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/list_item_height_min"
|
||||||
|
android:layout_marginBottom="@dimen/content_padding_standard"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding_half"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_half"
|
||||||
|
android:background="@drawable/btn_round"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:paddingLeft="@dimen/content_padding_half"
|
||||||
|
android:paddingRight="@dimen/content_padding_half">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/share_gpx_icon"
|
||||||
|
android:layout_width="@dimen/list_item_icon_size"
|
||||||
|
android:layout_height="@dimen/list_item_icon_size"
|
||||||
|
android:src="@drawable/ic_action_share"
|
||||||
|
android:tint="@color/ctrl_active_light" />
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/share_gpx_title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding_big"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_big"
|
||||||
|
android:text="@string/shared_string_share"
|
||||||
|
android:textColor="?android:textColorPrimary"
|
||||||
|
android:textSize="@dimen/list_item_title_text_size"
|
||||||
|
app:typeface="@string/font_roboto_medium" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
|
@ -9,4 +9,9 @@
|
||||||
android:id="@+id/action_live_now"
|
android:id="@+id/action_live_now"
|
||||||
android:icon="@drawable/ic_action_live_now"
|
android:icon="@drawable/ic_action_live_now"
|
||||||
android:title="@string/live_now"/>
|
android:title="@string/live_now"/>
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_timeline"
|
||||||
|
android:icon="@drawable/ic_action_timeline"
|
||||||
|
android:title="@string/timeline"/>
|
||||||
</menu>
|
</menu>
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<resources>
|
<resources>
|
||||||
|
<string name="timeline_description">Включите мониторинг, для сбора данных о перемещении в фоновом режиме.</string>
|
||||||
<string name="last_update_from_telegram">Последнее обновление в Telegram</string>
|
<string name="last_update_from_telegram">Последнее обновление в Telegram</string>
|
||||||
<string name="device_name">Имя устройства</string>
|
<string name="device_name">Имя устройства</string>
|
||||||
<string name="shared_string_hide">Спрятать</string>
|
<string name="shared_string_hide">Спрятать</string>
|
||||||
|
|
|
@ -1,4 +1,13 @@
|
||||||
<resources>
|
<resources>
|
||||||
|
<string name="monitoring_is_enabled">Monitoring is enabled</string>
|
||||||
|
<string name="monitoring_is_disabled">Monitoring is disabled</string>
|
||||||
|
<string name="time_on_the_move">time on the move</string>
|
||||||
|
<string name="average_altitude">Average altitude</string>
|
||||||
|
<string name="average_speed">Average speed</string>
|
||||||
|
<string name="open_in_osmand">Open in OsmAnd</string>
|
||||||
|
<string name="end_date">End date</string>
|
||||||
|
<string name="start_date">Start date</string>
|
||||||
|
<string name="timeline_description">Enable monitoring to collect movement data in the background.</string>
|
||||||
<string name="send_location_as">Send location as</string>
|
<string name="send_location_as">Send location as</string>
|
||||||
<string name="send_location_as_descr">Choose how messages with your location will look like.</string>
|
<string name="send_location_as_descr">Choose how messages with your location will look like.</string>
|
||||||
<string name="shared_string_map">Map</string>
|
<string name="shared_string_map">Map</string>
|
||||||
|
@ -176,6 +185,7 @@
|
||||||
<string name="welcome_descr"><![CDATA[<b>OsmAnd Location Sharing</b> lets you share your location and see that of others in the OsmAnd.<br/><br/>The app uses Telegram API and you need a Telegram account.]]></string>
|
<string name="welcome_descr"><![CDATA[<b>OsmAnd Location Sharing</b> lets you share your location and see that of others in the OsmAnd.<br/><br/>The app uses Telegram API and you need a Telegram account.]]></string>
|
||||||
<string name="my_location">My location</string>
|
<string name="my_location">My location</string>
|
||||||
<string name="live_now">Live now</string>
|
<string name="live_now">Live now</string>
|
||||||
|
<string name="timeline">Timeline</string>
|
||||||
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
package net.osmand.aidl;
|
package net.osmand.aidl;
|
||||||
|
|
||||||
import net.osmand.aidl.search.SearchResult;
|
import net.osmand.aidl.search.SearchResult;
|
||||||
|
import net.osmand.aidl.gpx.AGpxBitmap;
|
||||||
|
|
||||||
interface IOsmAndAidlCallback {
|
interface IOsmAndAidlCallback {
|
||||||
void onSearchComplete(in List<SearchResult> resultSet);
|
void onSearchComplete(in List<SearchResult> resultSet);
|
||||||
|
|
||||||
void onUpdate();
|
void onUpdate();
|
||||||
|
|
||||||
|
void onAppInitialized();
|
||||||
|
|
||||||
|
void onGpxBitmapCreated(in AGpxBitmap bitmap);
|
||||||
}
|
}
|
|
@ -55,6 +55,9 @@ import net.osmand.aidl.maplayer.point.ShowMapPointParams;
|
||||||
|
|
||||||
import net.osmand.aidl.navdrawer.SetNavDrawerItemsParams;
|
import net.osmand.aidl.navdrawer.SetNavDrawerItemsParams;
|
||||||
|
|
||||||
|
import net.osmand.aidl.navdrawer.NavDrawerFooterParams;
|
||||||
|
import net.osmand.aidl.navdrawer.NavDrawerHeaderParams;
|
||||||
|
|
||||||
import net.osmand.aidl.navigation.PauseNavigationParams;
|
import net.osmand.aidl.navigation.PauseNavigationParams;
|
||||||
import net.osmand.aidl.navigation.ResumeNavigationParams;
|
import net.osmand.aidl.navigation.ResumeNavigationParams;
|
||||||
import net.osmand.aidl.navigation.StopNavigationParams;
|
import net.osmand.aidl.navigation.StopNavigationParams;
|
||||||
|
@ -67,6 +70,16 @@ import net.osmand.aidl.search.SearchResult;
|
||||||
import net.osmand.aidl.search.SearchParams;
|
import net.osmand.aidl.search.SearchParams;
|
||||||
import net.osmand.aidl.navigation.NavigateSearchParams;
|
import net.osmand.aidl.navigation.NavigateSearchParams;
|
||||||
|
|
||||||
|
import net.osmand.aidl.customization.SetWidgetsParams;
|
||||||
|
import net.osmand.aidl.customization.OsmandSettingsParams;
|
||||||
|
|
||||||
|
import net.osmand.aidl.gpx.AGpxFile;
|
||||||
|
import net.osmand.aidl.gpx.AGpxFileDetails;
|
||||||
|
import net.osmand.aidl.gpx.CreateGpxBitmapParams;
|
||||||
|
import net.osmand.aidl.tiles.ASqliteDbFile;
|
||||||
|
|
||||||
|
import net.osmand.aidl.plugins.PluginParams;
|
||||||
|
|
||||||
// NOTE: Add new methods at the end of file!!!
|
// NOTE: Add new methods at the end of file!!!
|
||||||
|
|
||||||
interface IOsmAndAidlInterface {
|
interface IOsmAndAidlInterface {
|
||||||
|
@ -133,4 +146,34 @@ interface IOsmAndAidlInterface {
|
||||||
|
|
||||||
long registerForUpdates(in long updateTimeMS, IOsmAndAidlCallback callback);
|
long registerForUpdates(in long updateTimeMS, IOsmAndAidlCallback callback);
|
||||||
boolean unregisterFromUpdates(in long callbackId);
|
boolean unregisterFromUpdates(in long callbackId);
|
||||||
|
|
||||||
|
boolean setNavDrawerLogo(in String imageUri);
|
||||||
|
|
||||||
|
boolean setEnabledIds(in List<String> ids);
|
||||||
|
boolean setDisabledIds(in List<String> ids);
|
||||||
|
boolean setEnabledPatterns(in List<String> patterns);
|
||||||
|
boolean setDisabledPatterns(in List<String> patterns);
|
||||||
|
|
||||||
|
boolean regWidgetVisibility(in SetWidgetsParams params);
|
||||||
|
boolean regWidgetAvailability(in SetWidgetsParams params);
|
||||||
|
|
||||||
|
boolean customizeOsmandSettings(in OsmandSettingsParams params);
|
||||||
|
|
||||||
|
boolean getImportedGpx(out List<AGpxFile> files);
|
||||||
|
|
||||||
|
boolean getSqliteDbFiles(out List<ASqliteDbFile> files);
|
||||||
|
boolean getActiveSqliteDbFiles(out List<ASqliteDbFile> files);
|
||||||
|
boolean showSqliteDbFile(String fileName);
|
||||||
|
boolean hideSqliteDbFile(String fileName);
|
||||||
|
|
||||||
|
boolean setNavDrawerLogoWithParams(in NavDrawerHeaderParams params);
|
||||||
|
boolean setNavDrawerFooterWithParams(in NavDrawerFooterParams params);
|
||||||
|
|
||||||
|
boolean restoreOsmand();
|
||||||
|
|
||||||
|
boolean changePluginState(in PluginParams params);
|
||||||
|
|
||||||
|
boolean registerForOsmandInitListener(in IOsmAndAidlCallback callback);
|
||||||
|
|
||||||
|
boolean getBitmapForGpx(in CreateGpxBitmapParams file, IOsmAndAidlCallback callback);
|
||||||
}
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
package net.osmand.aidl.customization;
|
||||||
|
|
||||||
|
parcelable OsmandSettingsParams;
|
|
@ -0,0 +1,60 @@
|
||||||
|
package net.osmand.aidl.customization;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
public class OsmandSettingsParams implements Parcelable {
|
||||||
|
|
||||||
|
private String sharedPreferencesName;
|
||||||
|
private Bundle bundle;
|
||||||
|
|
||||||
|
public OsmandSettingsParams(@NonNull String sharedPreferencesName, @Nullable Bundle bundle) {
|
||||||
|
this.sharedPreferencesName = sharedPreferencesName;
|
||||||
|
this.bundle = bundle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OsmandSettingsParams(Parcel in) {
|
||||||
|
readFromParcel(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<OsmandSettingsParams> CREATOR = new Creator<OsmandSettingsParams>() {
|
||||||
|
@Override
|
||||||
|
public OsmandSettingsParams createFromParcel(Parcel in) {
|
||||||
|
return new OsmandSettingsParams(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OsmandSettingsParams[] newArray(int size) {
|
||||||
|
return new OsmandSettingsParams[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public String getSharedPreferencesName() {
|
||||||
|
return sharedPreferencesName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bundle getBundle() {
|
||||||
|
return bundle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel out, int flags) {
|
||||||
|
out.writeString(sharedPreferencesName);
|
||||||
|
out.writeBundle(bundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("ParcelClassLoader")
|
||||||
|
private void readFromParcel(Parcel in) {
|
||||||
|
sharedPreferencesName = in.readString();
|
||||||
|
bundle = in.readBundle();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
package net.osmand.aidl.customization;
|
||||||
|
|
||||||
|
parcelable SetWidgetsParams;
|
|
@ -0,0 +1,93 @@
|
||||||
|
package net.osmand.aidl.customization;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SetWidgetsParams implements Parcelable {
|
||||||
|
|
||||||
|
private String widgetKey;
|
||||||
|
private List<String> appModesKeys;
|
||||||
|
|
||||||
|
public SetWidgetsParams(String widgetKey, @Nullable List<String> appModesKeys) {
|
||||||
|
this.widgetKey = widgetKey;
|
||||||
|
this.appModesKeys = appModesKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SetWidgetsParams(Parcel in) {
|
||||||
|
readFromParcel(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<SetWidgetsParams> CREATOR = new Creator<SetWidgetsParams>() {
|
||||||
|
@Override
|
||||||
|
public SetWidgetsParams createFromParcel(Parcel in) {
|
||||||
|
return new SetWidgetsParams(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SetWidgetsParams[] newArray(int size) {
|
||||||
|
return new SetWidgetsParams[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public String getWidgetKey() {
|
||||||
|
return widgetKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getAppModesKeys() {
|
||||||
|
return appModesKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel out, int flags) {
|
||||||
|
out.writeString(widgetKey);
|
||||||
|
writeStringList(out, appModesKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readFromParcel(Parcel in) {
|
||||||
|
widgetKey = in.readString();
|
||||||
|
appModesKeys = readStringList(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeStringList(Parcel out, List<String> val) {
|
||||||
|
if (val == null) {
|
||||||
|
out.writeInt(-1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int N = val.size();
|
||||||
|
int i = 0;
|
||||||
|
out.writeInt(N);
|
||||||
|
while (i < N) {
|
||||||
|
out.writeString(val.get(i));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> readStringList(Parcel in) {
|
||||||
|
List<String> list = new ArrayList<>();
|
||||||
|
int M = list.size();
|
||||||
|
int N = in.readInt();
|
||||||
|
if (N == -1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int i = 0;
|
||||||
|
for (; i < M && i < N; i++) {
|
||||||
|
list.set(i, in.readString());
|
||||||
|
}
|
||||||
|
for (; i < N; i++) {
|
||||||
|
list.add(in.readString());
|
||||||
|
}
|
||||||
|
for (; i < M; i++) {
|
||||||
|
list.remove(N);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
4
OsmAnd-telegram/src/net/osmand/aidl/gpx/AGpxBitmap.aidl
Normal file
4
OsmAnd-telegram/src/net/osmand/aidl/gpx/AGpxBitmap.aidl
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
package net.osmand.aidl.gpx;
|
||||||
|
|
||||||
|
parcelable AGpxBitmap;
|
||||||
|
|
50
OsmAnd-telegram/src/net/osmand/aidl/gpx/AGpxBitmap.java
Normal file
50
OsmAnd-telegram/src/net/osmand/aidl/gpx/AGpxBitmap.java
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
package net.osmand.aidl.gpx;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
public class AGpxBitmap implements Parcelable {
|
||||||
|
|
||||||
|
private Bitmap bitmap;
|
||||||
|
|
||||||
|
public AGpxBitmap(@NonNull Bitmap bitmap) {
|
||||||
|
this.bitmap = bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AGpxBitmap(Parcel in) {
|
||||||
|
readFromParcel(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bitmap getBitmap() {
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBitmap(Bitmap bitmap) {
|
||||||
|
this.bitmap = bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<AGpxBitmap> CREATOR = new
|
||||||
|
Creator<AGpxBitmap>() {
|
||||||
|
public AGpxBitmap createFromParcel(Parcel in) {
|
||||||
|
return new AGpxBitmap(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AGpxBitmap[] newArray(int size) {
|
||||||
|
return new AGpxBitmap[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public void writeToParcel(Parcel out, int flags) {
|
||||||
|
out.writeParcelable(bitmap, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readFromParcel(Parcel in) {
|
||||||
|
bitmap = in.readParcelable(Bitmap.class.getClassLoader());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
3
OsmAnd-telegram/src/net/osmand/aidl/gpx/AGpxFile.aidl
Normal file
3
OsmAnd-telegram/src/net/osmand/aidl/gpx/AGpxFile.aidl
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
package net.osmand.aidl.gpx;
|
||||||
|
|
||||||
|
parcelable AGpxFile;
|
89
OsmAnd-telegram/src/net/osmand/aidl/gpx/AGpxFile.java
Normal file
89
OsmAnd-telegram/src/net/osmand/aidl/gpx/AGpxFile.java
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
package net.osmand.aidl.gpx;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
public class AGpxFile implements Parcelable {
|
||||||
|
|
||||||
|
private String fileName;
|
||||||
|
private long modifiedTime;
|
||||||
|
private long fileSize;
|
||||||
|
private boolean active;
|
||||||
|
private AGpxFileDetails details;
|
||||||
|
|
||||||
|
public AGpxFile(@NonNull String fileName, long modifiedTime, long fileSize, boolean active, @Nullable AGpxFileDetails details) {
|
||||||
|
this.fileName = fileName;
|
||||||
|
this.modifiedTime = modifiedTime;
|
||||||
|
this.fileSize = fileSize;
|
||||||
|
this.active = active;
|
||||||
|
this.details = details;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AGpxFile(Parcel in) {
|
||||||
|
readFromParcel(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<AGpxFile> CREATOR = new
|
||||||
|
Creator<AGpxFile>() {
|
||||||
|
public AGpxFile createFromParcel(Parcel in) {
|
||||||
|
return new AGpxFile(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AGpxFile[] newArray(int size) {
|
||||||
|
return new AGpxFile[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getModifiedTime() {
|
||||||
|
return modifiedTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getFileSize() {
|
||||||
|
return fileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isActive() {
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AGpxFileDetails getDetails() {
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeToParcel(Parcel out, int flags) {
|
||||||
|
out.writeString(fileName);
|
||||||
|
out.writeLong(modifiedTime);
|
||||||
|
out.writeLong(fileSize);
|
||||||
|
out.writeByte((byte) (active ? 1 : 0));
|
||||||
|
|
||||||
|
out.writeByte((byte) (details != null ? 1 : 0));
|
||||||
|
if (details != null) {
|
||||||
|
out.writeParcelable(details, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readFromParcel(Parcel in) {
|
||||||
|
fileName = in.readString();
|
||||||
|
modifiedTime = in.readLong();
|
||||||
|
fileSize = in.readLong();
|
||||||
|
active = in.readByte() != 0;
|
||||||
|
|
||||||
|
boolean hasDetails= in.readByte() != 0;
|
||||||
|
if (hasDetails) {
|
||||||
|
details = in.readParcelable(AGpxFileDetails.class.getClassLoader());
|
||||||
|
} else {
|
||||||
|
details = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
package net.osmand.aidl.gpx;
|
||||||
|
|
||||||
|
parcelable AGpxFileDetails;
|
196
OsmAnd-telegram/src/net/osmand/aidl/gpx/AGpxFileDetails.java
Normal file
196
OsmAnd-telegram/src/net/osmand/aidl/gpx/AGpxFileDetails.java
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
package net.osmand.aidl.gpx;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class AGpxFileDetails implements Parcelable {
|
||||||
|
|
||||||
|
private float totalDistance = 0;
|
||||||
|
private int totalTracks = 0;
|
||||||
|
private long startTime = Long.MAX_VALUE;
|
||||||
|
private long endTime = Long.MIN_VALUE;
|
||||||
|
private long timeSpan = 0;
|
||||||
|
private long timeMoving = 0;
|
||||||
|
private float totalDistanceMoving = 0;
|
||||||
|
|
||||||
|
private double diffElevationUp = 0;
|
||||||
|
private double diffElevationDown = 0;
|
||||||
|
private double avgElevation = 0;
|
||||||
|
private double minElevation = 99999;
|
||||||
|
private double maxElevation = -100;
|
||||||
|
|
||||||
|
private float minSpeed = Float.MAX_VALUE;
|
||||||
|
private float maxSpeed = 0;
|
||||||
|
private float avgSpeed;
|
||||||
|
|
||||||
|
private int points;
|
||||||
|
private int wptPoints = 0;
|
||||||
|
|
||||||
|
private List<String> wptCategoryNames = new ArrayList<>();
|
||||||
|
|
||||||
|
public AGpxFileDetails(float totalDistance, int totalTracks,
|
||||||
|
long startTime, long endTime,
|
||||||
|
long timeSpan, long timeMoving, float totalDistanceMoving,
|
||||||
|
double diffElevationUp, double diffElevationDown,
|
||||||
|
double avgElevation, double minElevation, double maxElevation,
|
||||||
|
float minSpeed, float maxSpeed, float avgSpeed,
|
||||||
|
int points, int wptPoints, Set<String> wptCategoryNames) {
|
||||||
|
this.totalDistance = totalDistance;
|
||||||
|
this.totalTracks = totalTracks;
|
||||||
|
this.startTime = startTime;
|
||||||
|
this.endTime = endTime;
|
||||||
|
this.timeSpan = timeSpan;
|
||||||
|
this.timeMoving = timeMoving;
|
||||||
|
this.totalDistanceMoving = totalDistanceMoving;
|
||||||
|
this.diffElevationUp = diffElevationUp;
|
||||||
|
this.diffElevationDown = diffElevationDown;
|
||||||
|
this.avgElevation = avgElevation;
|
||||||
|
this.minElevation = minElevation;
|
||||||
|
this.maxElevation = maxElevation;
|
||||||
|
this.minSpeed = minSpeed;
|
||||||
|
this.maxSpeed = maxSpeed;
|
||||||
|
this.avgSpeed = avgSpeed;
|
||||||
|
this.points = points;
|
||||||
|
this.wptPoints = wptPoints;
|
||||||
|
if (wptCategoryNames != null) {
|
||||||
|
this.wptCategoryNames = new ArrayList<>(wptCategoryNames);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public AGpxFileDetails(Parcel in) {
|
||||||
|
readFromParcel(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<AGpxFileDetails> CREATOR = new
|
||||||
|
Creator<AGpxFileDetails>() {
|
||||||
|
public AGpxFileDetails createFromParcel(Parcel in) {
|
||||||
|
return new AGpxFileDetails(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AGpxFileDetails[] newArray(int size) {
|
||||||
|
return new AGpxFileDetails[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public float getTotalDistance() {
|
||||||
|
return totalDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTotalTracks() {
|
||||||
|
return totalTracks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getStartTime() {
|
||||||
|
return startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getEndTime() {
|
||||||
|
return endTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTimeSpan() {
|
||||||
|
return timeSpan;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTimeMoving() {
|
||||||
|
return timeMoving;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getTotalDistanceMoving() {
|
||||||
|
return totalDistanceMoving;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getDiffElevationUp() {
|
||||||
|
return diffElevationUp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getDiffElevationDown() {
|
||||||
|
return diffElevationDown;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getAvgElevation() {
|
||||||
|
return avgElevation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMinElevation() {
|
||||||
|
return minElevation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMaxElevation() {
|
||||||
|
return maxElevation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getMinSpeed() {
|
||||||
|
return minSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getMaxSpeed() {
|
||||||
|
return maxSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getAvgSpeed() {
|
||||||
|
return avgSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPoints() {
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWptPoints() {
|
||||||
|
return wptPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getWptCategoryNames() {
|
||||||
|
return wptCategoryNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeToParcel(Parcel out, int flags) {
|
||||||
|
out.writeFloat(totalDistance);
|
||||||
|
out.writeInt(totalTracks);
|
||||||
|
out.writeLong(startTime);
|
||||||
|
out.writeLong(endTime);
|
||||||
|
out.writeLong(timeSpan);
|
||||||
|
out.writeLong(timeMoving);
|
||||||
|
out.writeFloat(totalDistanceMoving);
|
||||||
|
out.writeDouble(diffElevationUp);
|
||||||
|
out.writeDouble(diffElevationDown);
|
||||||
|
out.writeDouble(avgElevation);
|
||||||
|
out.writeDouble(minElevation);
|
||||||
|
out.writeDouble(maxElevation);
|
||||||
|
out.writeFloat(minSpeed);
|
||||||
|
out.writeFloat(maxSpeed);
|
||||||
|
out.writeFloat(avgSpeed);
|
||||||
|
out.writeInt(points);
|
||||||
|
out.writeInt(wptPoints);
|
||||||
|
out.writeStringList(wptCategoryNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readFromParcel(Parcel in) {
|
||||||
|
totalDistance = in.readFloat();
|
||||||
|
totalTracks = in.readInt();
|
||||||
|
startTime = in.readLong();
|
||||||
|
endTime = in.readLong();
|
||||||
|
timeSpan = in.readLong();
|
||||||
|
timeMoving = in.readLong();
|
||||||
|
totalDistanceMoving = in.readFloat();
|
||||||
|
diffElevationUp = in.readDouble();
|
||||||
|
diffElevationDown = in.readDouble();
|
||||||
|
avgElevation = in.readDouble();
|
||||||
|
minElevation = in.readDouble();
|
||||||
|
maxElevation = in.readDouble();
|
||||||
|
minSpeed = in.readFloat();
|
||||||
|
maxSpeed = in.readFloat();
|
||||||
|
avgSpeed = in.readFloat();
|
||||||
|
points = in.readInt();
|
||||||
|
wptPoints = in.readInt();
|
||||||
|
in.readStringList(wptCategoryNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
package net.osmand.aidl.gpx;
|
||||||
|
|
||||||
|
parcelable CreateGpxBitmapParams;
|
|
@ -0,0 +1,101 @@
|
||||||
|
package net.osmand.aidl.gpx;
|
||||||
|
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class CreateGpxBitmapParams implements Parcelable {
|
||||||
|
|
||||||
|
private File gpxFile;
|
||||||
|
private Uri gpxUri;
|
||||||
|
private float density;
|
||||||
|
private int widthPixels;
|
||||||
|
private int heightPixels;
|
||||||
|
private int color; //ARGB color int
|
||||||
|
|
||||||
|
public CreateGpxBitmapParams(File gpxFile, float density, int widthPixels, int heightPixels, int color) {
|
||||||
|
this.gpxFile = gpxFile;
|
||||||
|
this.density = density;
|
||||||
|
this.widthPixels = widthPixels;
|
||||||
|
this.heightPixels = heightPixels;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CreateGpxBitmapParams(Uri gpxUri, float density, int widthPixels, int heightPixels, int color) {
|
||||||
|
this.gpxUri = gpxUri;
|
||||||
|
this.density = density;
|
||||||
|
this.widthPixels = widthPixels;
|
||||||
|
this.heightPixels = heightPixels;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CreateGpxBitmapParams(Parcel in) {
|
||||||
|
readFromParcel(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<CreateGpxBitmapParams> CREATOR = new
|
||||||
|
Creator<CreateGpxBitmapParams>() {
|
||||||
|
public CreateGpxBitmapParams createFromParcel(Parcel in) {
|
||||||
|
return new CreateGpxBitmapParams(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CreateGpxBitmapParams[] newArray(int size) {
|
||||||
|
return new CreateGpxBitmapParams[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public File getGpxFile() {
|
||||||
|
return gpxFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uri getGpxUri() {
|
||||||
|
return gpxUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWidthPixels() {
|
||||||
|
return widthPixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeightPixels() {
|
||||||
|
return heightPixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getDensity() {
|
||||||
|
return density;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeToParcel(Parcel out, int flags) {
|
||||||
|
if (gpxFile != null) {
|
||||||
|
out.writeString(gpxFile.getAbsolutePath());
|
||||||
|
} else {
|
||||||
|
out.writeString(null);
|
||||||
|
}
|
||||||
|
out.writeParcelable(gpxUri, flags);
|
||||||
|
out.writeFloat(density);
|
||||||
|
out.writeInt(widthPixels);
|
||||||
|
out.writeInt(heightPixels);
|
||||||
|
out.writeInt(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readFromParcel(Parcel in) {
|
||||||
|
String gpxAbsolutePath = in.readString();
|
||||||
|
if (gpxAbsolutePath != null) {
|
||||||
|
gpxFile = new File(gpxAbsolutePath);
|
||||||
|
}
|
||||||
|
gpxUri = in.readParcelable(Uri.class.getClassLoader());
|
||||||
|
density = in.readFloat();
|
||||||
|
widthPixels = in.readInt();
|
||||||
|
heightPixels = in.readInt();
|
||||||
|
color = in.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
package net.osmand.aidl.navdrawer;
|
||||||
|
|
||||||
|
parcelable NavDrawerFooterParams;
|
|
@ -0,0 +1,68 @@
|
||||||
|
package net.osmand.aidl.navdrawer;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
public class NavDrawerFooterParams implements Parcelable {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private String packageName;
|
||||||
|
@Nullable
|
||||||
|
private String intent;
|
||||||
|
@Nullable
|
||||||
|
private String appName;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public String getPackageName() {
|
||||||
|
return packageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getIntent() {
|
||||||
|
return intent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getAppName() {
|
||||||
|
return appName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NavDrawerFooterParams(@NonNull String packageName, @Nullable String intent,
|
||||||
|
@Nullable String appName) {
|
||||||
|
this.packageName = packageName;
|
||||||
|
this.intent = intent;
|
||||||
|
this.appName = appName;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected NavDrawerFooterParams(Parcel in) {
|
||||||
|
packageName = in.readString();
|
||||||
|
intent = in.readString();
|
||||||
|
appName = in.readString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeString(packageName);
|
||||||
|
dest.writeString(intent);
|
||||||
|
dest.writeString(appName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<NavDrawerFooterParams> CREATOR = new Creator<NavDrawerFooterParams>() {
|
||||||
|
@Override
|
||||||
|
public NavDrawerFooterParams createFromParcel(Parcel in) {
|
||||||
|
return new NavDrawerFooterParams(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NavDrawerFooterParams[] newArray(int size) {
|
||||||
|
return new NavDrawerFooterParams[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
package net.osmand.aidl.navdrawer;
|
||||||
|
|
||||||
|
parcelable NavDrawerHeaderParams;
|
|
@ -0,0 +1,68 @@
|
||||||
|
package net.osmand.aidl.navdrawer;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
public class NavDrawerHeaderParams implements Parcelable {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private String imageUri;
|
||||||
|
@NonNull
|
||||||
|
private String packageName;
|
||||||
|
@Nullable
|
||||||
|
private String intent;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public String getImageUri() {
|
||||||
|
return imageUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public String getPackageName() {
|
||||||
|
return packageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getIntent() {
|
||||||
|
return intent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NavDrawerHeaderParams(@NonNull String imageUri, @NonNull String packageName,
|
||||||
|
@Nullable String intent) {
|
||||||
|
this.imageUri = imageUri;
|
||||||
|
this.packageName = packageName;
|
||||||
|
this.intent = intent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NavDrawerHeaderParams(Parcel in) {
|
||||||
|
imageUri = in.readString();
|
||||||
|
packageName = in.readString();
|
||||||
|
intent = in.readString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeString(imageUri);
|
||||||
|
dest.writeString(packageName);
|
||||||
|
dest.writeString(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<NavDrawerHeaderParams> CREATOR = new Creator<NavDrawerHeaderParams>() {
|
||||||
|
@Override
|
||||||
|
public NavDrawerHeaderParams createFromParcel(Parcel in) {
|
||||||
|
return new NavDrawerHeaderParams(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NavDrawerHeaderParams[] newArray(int size) {
|
||||||
|
return new NavDrawerHeaderParams[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
// PluginParams.aidl
|
||||||
|
package net.osmand.aidl.plugins;
|
||||||
|
|
||||||
|
parcelable PluginParams;
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
package net.osmand.aidl.plugins;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
public class PluginParams implements Parcelable {
|
||||||
|
|
||||||
|
private String pluginId;
|
||||||
|
private int newState; //0- off, 1 - on
|
||||||
|
|
||||||
|
public PluginParams(String pluginId, int newState) {
|
||||||
|
this.pluginId = pluginId;
|
||||||
|
this.newState = newState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPluginId() {
|
||||||
|
return pluginId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNewState() {
|
||||||
|
return newState;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected PluginParams(Parcel in) {
|
||||||
|
pluginId = in.readString();
|
||||||
|
newState = in.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeString(pluginId);
|
||||||
|
dest.writeInt(newState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<PluginParams> CREATOR = new Creator<PluginParams>() {
|
||||||
|
@Override
|
||||||
|
public PluginParams createFromParcel(Parcel in) {
|
||||||
|
return new PluginParams(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PluginParams[] newArray(int size) {
|
||||||
|
return new PluginParams[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
package net.osmand.aidl.tiles;
|
||||||
|
|
||||||
|
parcelable ASqliteDbFile;
|
69
OsmAnd-telegram/src/net/osmand/aidl/tiles/ASqliteDbFile.java
Normal file
69
OsmAnd-telegram/src/net/osmand/aidl/tiles/ASqliteDbFile.java
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
package net.osmand.aidl.tiles;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
public class ASqliteDbFile implements Parcelable {
|
||||||
|
|
||||||
|
private String fileName;
|
||||||
|
private long modifiedTime;
|
||||||
|
private long fileSize;
|
||||||
|
private boolean active;
|
||||||
|
|
||||||
|
public ASqliteDbFile(@NonNull String fileName, long modifiedTime, long fileSize, boolean active) {
|
||||||
|
this.fileName = fileName;
|
||||||
|
this.modifiedTime = modifiedTime;
|
||||||
|
this.fileSize = fileSize;
|
||||||
|
this.active = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASqliteDbFile(Parcel in) {
|
||||||
|
readFromParcel(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<ASqliteDbFile> CREATOR = new
|
||||||
|
Creator<ASqliteDbFile>() {
|
||||||
|
public ASqliteDbFile createFromParcel(Parcel in) {
|
||||||
|
return new ASqliteDbFile(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASqliteDbFile[] newArray(int size) {
|
||||||
|
return new ASqliteDbFile[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getModifiedTime() {
|
||||||
|
return modifiedTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getFileSize() {
|
||||||
|
return fileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isActive() {
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeToParcel(Parcel out, int flags) {
|
||||||
|
out.writeString(fileName);
|
||||||
|
out.writeLong(modifiedTime);
|
||||||
|
out.writeLong(fileSize);
|
||||||
|
out.writeByte((byte) (active ? 1 : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readFromParcel(Parcel in) {
|
||||||
|
fileName = in.readString();
|
||||||
|
modifiedTime = in.readLong();
|
||||||
|
fileSize = in.readLong();
|
||||||
|
active = in.readByte() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -79,6 +79,8 @@ private const val SHARE_CHATS_INFO_KEY = "share_chats_info"
|
||||||
|
|
||||||
private const val BATTERY_OPTIMISATION_ASKED = "battery_optimisation_asked"
|
private const val BATTERY_OPTIMISATION_ASKED = "battery_optimisation_asked"
|
||||||
|
|
||||||
|
private const val MONITORING_ENABLED = "monitoring_enabled"
|
||||||
|
|
||||||
private const val SHARING_INITIALIZATION_TIME = 60 * 2L // 2 minutes
|
private const val SHARING_INITIALIZATION_TIME = 60 * 2L // 2 minutes
|
||||||
|
|
||||||
private const val GPS_UPDATE_EXPIRED_TIME = 60 * 3L // 3 minutes
|
private const val GPS_UPDATE_EXPIRED_TIME = 60 * 3L // 3 minutes
|
||||||
|
@ -111,6 +113,8 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
|
|
||||||
var batteryOptimisationAsked = false
|
var batteryOptimisationAsked = false
|
||||||
|
|
||||||
|
var monitoringEnabled = false
|
||||||
|
|
||||||
init {
|
init {
|
||||||
updatePrefs()
|
updatePrefs()
|
||||||
read()
|
read()
|
||||||
|
@ -435,6 +439,8 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
|
|
||||||
edit.putBoolean(BATTERY_OPTIMISATION_ASKED, batteryOptimisationAsked)
|
edit.putBoolean(BATTERY_OPTIMISATION_ASKED, batteryOptimisationAsked)
|
||||||
|
|
||||||
|
edit.putBoolean(MONITORING_ENABLED, monitoringEnabled)
|
||||||
|
|
||||||
val jArray = convertShareChatsInfoToJson()
|
val jArray = convertShareChatsInfoToJson()
|
||||||
if (jArray != null) {
|
if (jArray != null) {
|
||||||
edit.putString(SHARE_CHATS_INFO_KEY, jArray.toString())
|
edit.putString(SHARE_CHATS_INFO_KEY, jArray.toString())
|
||||||
|
@ -491,6 +497,8 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
)
|
)
|
||||||
|
|
||||||
batteryOptimisationAsked = prefs.getBoolean(BATTERY_OPTIMISATION_ASKED,false)
|
batteryOptimisationAsked = prefs.getBoolean(BATTERY_OPTIMISATION_ASKED,false)
|
||||||
|
|
||||||
|
monitoringEnabled = prefs.getBoolean(MONITORING_ENABLED,false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun convertShareDevicesToJson():JSONObject?{
|
private fun convertShareDevicesToJson():JSONObject?{
|
||||||
|
|
|
@ -75,6 +75,12 @@ class OsmandAidlHelper(private val app: TelegramApplication) {
|
||||||
fun onSearchComplete(resultSet: List<SearchResult>)
|
fun onSearchComplete(resultSet: List<SearchResult>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var gpxBitmapCreatedListener: GpxBitmapCreatedListener? = null
|
||||||
|
|
||||||
|
interface GpxBitmapCreatedListener {
|
||||||
|
fun onGpxBitmapCreated(bitmap: AGpxBitmap)
|
||||||
|
}
|
||||||
|
|
||||||
private val mIOsmAndAidlCallback = object : IOsmAndAidlCallback.Stub() {
|
private val mIOsmAndAidlCallback = object : IOsmAndAidlCallback.Stub() {
|
||||||
|
|
||||||
@Throws(RemoteException::class)
|
@Throws(RemoteException::class)
|
||||||
|
@ -90,12 +96,26 @@ class OsmandAidlHelper(private val app: TelegramApplication) {
|
||||||
mUpdatesListener!!.update()
|
mUpdatesListener!!.update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onAppInitialized() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onGpxBitmapCreated(bitmap: AGpxBitmap) {
|
||||||
|
if (gpxBitmapCreatedListener != null) {
|
||||||
|
gpxBitmapCreatedListener!!.onGpxBitmapCreated(bitmap)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setSearchCompleteListener(mSearchCompleteListener: SearchCompleteListener) {
|
fun setSearchCompleteListener(mSearchCompleteListener: SearchCompleteListener) {
|
||||||
this.mSearchCompleteListener = mSearchCompleteListener
|
this.mSearchCompleteListener = mSearchCompleteListener
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setGpxBitmapCreatedListener(gpxBitmapCreatedListener: GpxBitmapCreatedListener) {
|
||||||
|
this.gpxBitmapCreatedListener = gpxBitmapCreatedListener
|
||||||
|
}
|
||||||
|
|
||||||
private var mUpdatesListener: UpdatesListener? = null
|
private var mUpdatesListener: UpdatesListener? = null
|
||||||
|
|
||||||
interface UpdatesListener {
|
interface UpdatesListener {
|
||||||
|
@ -1059,4 +1079,16 @@ class OsmandAidlHelper(private val app: TelegramApplication) {
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getBitmapForGpx(gpxUri: Uri, density: Float, widthPixels: Int, heightPixels: Int, color: Int): Boolean {
|
||||||
|
if (mIOsmAndAidlInterface != null) {
|
||||||
|
try {
|
||||||
|
app.grantUriPermission(app.settings.appToConnectPackage, gpxUri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||||
|
return mIOsmAndAidlInterface!!.getBitmapForGpx(CreateGpxBitmapParams(gpxUri, density, widthPixels, heightPixels, color), mIOsmAndAidlCallback)
|
||||||
|
} catch (e: RemoteException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import android.os.AsyncTask;
|
||||||
|
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
import net.osmand.telegram.TelegramApplication;
|
import net.osmand.telegram.TelegramApplication;
|
||||||
import net.osmand.telegram.ui.LiveNowTabFragment;
|
|
||||||
import net.osmand.telegram.utils.GPXUtilities;
|
import net.osmand.telegram.utils.GPXUtilities;
|
||||||
import net.osmand.telegram.utils.GPXUtilities.GPXFile;
|
import net.osmand.telegram.utils.GPXUtilities.GPXFile;
|
||||||
import net.osmand.telegram.utils.GPXUtilities.Track;
|
import net.osmand.telegram.utils.GPXUtilities.Track;
|
||||||
|
@ -19,7 +18,6 @@ import org.drinkless.td.libcore.telegram.TdApi;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -50,7 +48,7 @@ public class SavingTracksDbHelper extends SQLiteOpenHelper {
|
||||||
+ TRACK_COL_ALTITUDE + " double, " + TRACK_COL_SPEED + " double, " //$NON-NLS-1$ //$NON-NLS-2$
|
+ TRACK_COL_ALTITUDE + " double, " + TRACK_COL_SPEED + " double, " //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
+ TRACK_COL_HDOP + " double, " + TRACK_COL_DATE + " long, " + TRACK_COL_TEXT_INFO + " int )";
|
+ TRACK_COL_HDOP + " double, " + TRACK_COL_DATE + " long, " + TRACK_COL_TEXT_INFO + " int )";
|
||||||
|
|
||||||
public final static Log log = PlatformUtil.getLog(SavingTracksDbHelper.class);
|
private final static Log log = PlatformUtil.getLog(SavingTracksDbHelper.class);
|
||||||
|
|
||||||
private final TelegramApplication app;
|
private final TelegramApplication app;
|
||||||
|
|
||||||
|
@ -110,23 +108,32 @@ public class SavingTracksDbHelper extends SQLiteOpenHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveAsyncUserDataToGpx(LiveNowTabFragment fragment, File dir, int userId, long interval) {
|
public void saveUserDataToGpx(SaveGpxListener listener, File dir, int userId, long chatId, long start, long end) {
|
||||||
GPXFile gpxFile = app.getSavingTracksDbHelper().collectRecordedDataForUser(userId, interval);
|
GPXFile gpxFile = collectRecordedDataForUserAndChat(userId, chatId, start, end);
|
||||||
if (gpxFile != null && !gpxFile.isEmpty()) {
|
if (gpxFile != null && !gpxFile.isEmpty()) {
|
||||||
SaveGPXTrackToFileTask task = new SaveGPXTrackToFileTask(fragment, gpxFile, dir, userId);
|
SaveGPXTrackToFileTask task = new SaveGPXTrackToFileTask(app, listener, gpxFile, dir, userId);
|
||||||
|
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveGpx(SaveGpxListener listener, File dir, GPXFile gpxFile) {
|
||||||
|
if (gpxFile != null && !gpxFile.isEmpty()) {
|
||||||
|
SaveGPXTrackToFileTask task = new SaveGPXTrackToFileTask(app, listener, gpxFile, dir, 0);
|
||||||
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateLocationMessage(TdApi.Message message) {
|
private void updateLocationMessage(TdApi.Message message) {
|
||||||
|
log.debug(message);
|
||||||
TdApi.MessageContent content = message.content;
|
TdApi.MessageContent content = message.content;
|
||||||
|
int senderId = app.getTelegramHelper().getSenderMessageId(message);
|
||||||
if (content instanceof TdApi.MessageLocation) {
|
if (content instanceof TdApi.MessageLocation) {
|
||||||
long lastTextMessageUpdate = getLastTextTrackPointTimeForUser(message.senderUserId);
|
long lastTextMessageUpdate = getLastTextTrackPointTimeForUser(message.senderUserId);
|
||||||
long currentTime = System.currentTimeMillis();
|
long currentTime = System.currentTimeMillis();
|
||||||
if (lastTextMessageUpdate == 0 || currentTime - lastTextMessageUpdate < 10 * 1000) {
|
if (lastTextMessageUpdate == 0 || currentTime - lastTextMessageUpdate < 10 * 1000) {
|
||||||
log.debug("Add map message" + message.senderUserId);
|
log.debug("Add map message " + message.senderUserId);
|
||||||
TdApi.MessageLocation messageLocation = (TdApi.MessageLocation) content;
|
TdApi.MessageLocation messageLocation = (TdApi.MessageLocation) content;
|
||||||
insertData(message.senderUserId, message.chatId, messageLocation.location.latitude,
|
insertData(senderId, message.chatId, messageLocation.location.latitude,
|
||||||
messageLocation.location.longitude, 0.0, 0.0, 0.0,
|
messageLocation.location.longitude, 0.0, 0.0, 0.0,
|
||||||
Math.max(message.date, message.editDate), 0);
|
Math.max(message.date, message.editDate), 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -135,7 +142,7 @@ public class SavingTracksDbHelper extends SQLiteOpenHelper {
|
||||||
} else if (content instanceof TelegramHelper.MessageLocation) {
|
} else if (content instanceof TelegramHelper.MessageLocation) {
|
||||||
log.debug("Add text message " + message.senderUserId);
|
log.debug("Add text message " + message.senderUserId);
|
||||||
TelegramHelper.MessageLocation messageLocation = (TelegramHelper.MessageLocation) content;
|
TelegramHelper.MessageLocation messageLocation = (TelegramHelper.MessageLocation) content;
|
||||||
insertData(message.senderUserId, message.chatId, messageLocation.getLat(), messageLocation.getLon(),
|
insertData(senderId, message.chatId, messageLocation.getLat(), messageLocation.getLon(),
|
||||||
messageLocation.getAltitude(), messageLocation.getSpeed(), messageLocation.getHdop(),
|
messageLocation.getAltitude(), messageLocation.getSpeed(), messageLocation.getHdop(),
|
||||||
messageLocation.getLastUpdated() * 1000L, 1);
|
messageLocation.getLastUpdated() * 1000L, 1);
|
||||||
}
|
}
|
||||||
|
@ -181,12 +188,12 @@ public class SavingTracksDbHelper extends SQLiteOpenHelper {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private GPXFile collectRecordedDataForUser(int userId, long interval) {
|
public GPXFile collectRecordedDataForUserAndChat(int userId, long chatId, long start, long end) {
|
||||||
GPXFile gpxFile = null;
|
GPXFile gpxFile = null;
|
||||||
SQLiteDatabase db = getReadableDatabase();
|
SQLiteDatabase db = getReadableDatabase();
|
||||||
if (db != null && db.isOpen()) {
|
if (db != null && db.isOpen()) {
|
||||||
try {
|
try {
|
||||||
gpxFile = collectDBTracksForUser(db, userId, interval);
|
gpxFile = collectDBTracksForUser(db, userId, chatId, start, end);
|
||||||
} finally {
|
} finally {
|
||||||
db.close();
|
db.close();
|
||||||
}
|
}
|
||||||
|
@ -194,21 +201,52 @@ public class SavingTracksDbHelper extends SQLiteOpenHelper {
|
||||||
return gpxFile;
|
return gpxFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
private GPXFile collectDBTracksForUser(SQLiteDatabase db, int userId, long interval) {
|
public GPXFile collectRecordedDataForUser(int userId, long chatId, long start, long end) {
|
||||||
Cursor query = db.rawQuery("SELECT " + TRACK_COL_USER_ID + "," + TRACK_COL_CHAT_ID + "," + TRACK_COL_LAT + "," + TRACK_COL_LON + "," + TRACK_COL_ALTITUDE + "," //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
|
GPXFile gpxFile = null;
|
||||||
+ TRACK_COL_SPEED + "," + TRACK_COL_HDOP + "," + TRACK_COL_DATE + " FROM " + TRACK_NAME +
|
SQLiteDatabase db = getReadableDatabase();
|
||||||
" WHERE " + TRACK_COL_USER_ID + " = ? ORDER BY " + TRACK_COL_DATE + " ASC ", new String[]{String.valueOf(userId)}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
if (db != null && db.isOpen()) {
|
||||||
|
try {
|
||||||
|
if (chatId == 0) {
|
||||||
|
gpxFile = collectDBTracksForUser(db, userId, start, end);
|
||||||
|
} else {
|
||||||
|
gpxFile = collectDBTracksForUser(db, userId, chatId, start, end);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return gpxFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<GPXFile> collectRecordedDataForUsers(long start, long end, ArrayList<Integer> ignoredUsersIds) {
|
||||||
|
ArrayList<GPXFile> data = new ArrayList<>();
|
||||||
|
SQLiteDatabase db = getReadableDatabase();
|
||||||
|
if (db != null && db.isOpen()) {
|
||||||
|
try {
|
||||||
|
collectDBTracksForUsers(db, data, start, end, ignoredUsersIds);
|
||||||
|
} finally {
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GPXFile collectDBTracksForUser(SQLiteDatabase db, int userId, long chatId, long start, long end) {
|
||||||
|
Cursor query = db.rawQuery("SELECT " + TRACK_COL_USER_ID + "," + TRACK_COL_CHAT_ID + ","
|
||||||
|
+ TRACK_COL_LAT + "," + TRACK_COL_LON + "," + TRACK_COL_ALTITUDE + "," + TRACK_COL_SPEED + ","
|
||||||
|
+ TRACK_COL_HDOP + "," + TRACK_COL_DATE + " FROM " + TRACK_NAME + " WHERE " + TRACK_COL_USER_ID + " = ?"
|
||||||
|
+ " AND " + TRACK_COL_CHAT_ID + " = ?" + " AND " + TRACK_COL_DATE + " BETWEEN " + start + " AND " + end
|
||||||
|
+ " ORDER BY " + TRACK_COL_DATE + " ASC ", new String[]{String.valueOf(userId), String.valueOf(chatId)});
|
||||||
|
|
||||||
GPXFile gpxFile = new GPXFile();
|
GPXFile gpxFile = new GPXFile();
|
||||||
|
gpxFile.chatId = chatId;
|
||||||
|
gpxFile.userId = userId;
|
||||||
long previousTime = 0;
|
long previousTime = 0;
|
||||||
TrkSegment segment = null;
|
TrkSegment segment = null;
|
||||||
Track track = null;
|
Track track = null;
|
||||||
if (query.moveToFirst()) {
|
if (query.moveToFirst()) {
|
||||||
do {
|
do {
|
||||||
long time = query.getLong(7);
|
long time = query.getLong(7);
|
||||||
long curTime = System.currentTimeMillis();
|
|
||||||
if (curTime - time > interval) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
WptPt pt = new WptPt();
|
WptPt pt = new WptPt();
|
||||||
pt.userId = query.getInt(0);
|
pt.userId = query.getInt(0);
|
||||||
pt.chatId = query.getLong(1);
|
pt.chatId = query.getLong(1);
|
||||||
|
@ -244,19 +282,135 @@ public class SavingTracksDbHelper extends SQLiteOpenHelper {
|
||||||
return gpxFile;
|
return gpxFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private GPXFile collectDBTracksForUser(SQLiteDatabase db, int userId, long start, long end) {
|
||||||
|
Cursor query = db.rawQuery("SELECT " + TRACK_COL_USER_ID + "," + TRACK_COL_CHAT_ID + ","
|
||||||
|
+ TRACK_COL_LAT + "," + TRACK_COL_LON + "," + TRACK_COL_ALTITUDE + "," + TRACK_COL_SPEED + ","
|
||||||
|
+ TRACK_COL_HDOP + "," + TRACK_COL_DATE + " FROM " + TRACK_NAME + " WHERE " + TRACK_COL_USER_ID + " = ?"
|
||||||
|
+ " AND " + TRACK_COL_DATE + " BETWEEN " + start + " AND " + end
|
||||||
|
+ " ORDER BY " + TRACK_COL_DATE + " ASC ", new String[]{String.valueOf(userId)});
|
||||||
|
|
||||||
|
GPXFile gpxFile = new GPXFile();
|
||||||
|
gpxFile.userId = userId;
|
||||||
|
long previousTime = 0;
|
||||||
|
TrkSegment segment = null;
|
||||||
|
Track track = null;
|
||||||
|
if (query.moveToFirst()) {
|
||||||
|
do {
|
||||||
|
long time = query.getLong(7);
|
||||||
|
WptPt pt = new WptPt();
|
||||||
|
pt.userId = query.getInt(0);
|
||||||
|
pt.chatId = query.getLong(1);
|
||||||
|
pt.lat = query.getDouble(2);
|
||||||
|
pt.lon = query.getDouble(3);
|
||||||
|
pt.ele = query.getDouble(4);
|
||||||
|
pt.speed = query.getDouble(5);
|
||||||
|
pt.hdop = query.getDouble(6);
|
||||||
|
pt.time = time;
|
||||||
|
long currentInterval = Math.abs(time - previousTime);
|
||||||
|
|
||||||
|
if (track != null) {
|
||||||
|
if (currentInterval < 30 * 60 * 1000) {
|
||||||
|
// 30 minute - same segment
|
||||||
|
segment.points.add(pt);
|
||||||
|
} else {
|
||||||
|
segment = new TrkSegment();
|
||||||
|
segment.points.add(pt);
|
||||||
|
track.segments.add(segment);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
track = new Track();
|
||||||
|
segment = new TrkSegment();
|
||||||
|
track.segments.add(segment);
|
||||||
|
segment.points.add(pt);
|
||||||
|
|
||||||
|
gpxFile.tracks.add(track);
|
||||||
|
}
|
||||||
|
previousTime = time;
|
||||||
|
} while (query.moveToNext());
|
||||||
|
}
|
||||||
|
query.close();
|
||||||
|
return gpxFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void collectDBTracksForUsers(SQLiteDatabase db, ArrayList<GPXFile> dataTracks, long start, long end, ArrayList<Integer> ignoredUsersIds) {
|
||||||
|
Cursor query = db.rawQuery("SELECT " + TRACK_COL_USER_ID + "," + TRACK_COL_CHAT_ID + ","
|
||||||
|
+ TRACK_COL_LAT + "," + TRACK_COL_LON + "," + TRACK_COL_ALTITUDE + "," + TRACK_COL_SPEED + ","
|
||||||
|
+ TRACK_COL_HDOP + "," + TRACK_COL_DATE + " FROM " + TRACK_NAME + " WHERE " + TRACK_COL_DATE
|
||||||
|
+ " BETWEEN " + start + " AND " + end + " ORDER BY " + TRACK_COL_USER_ID + " ASC, "
|
||||||
|
+ TRACK_COL_CHAT_ID + " ASC, " + TRACK_COL_DATE + " ASC ", null);
|
||||||
|
|
||||||
|
long previousTime = 0;
|
||||||
|
long previousChatId = 0;
|
||||||
|
int previousUserId = 0;
|
||||||
|
TrkSegment segment = null;
|
||||||
|
Track track = null;
|
||||||
|
GPXFile gpx = new GPXFile();
|
||||||
|
if (query.moveToFirst()) {
|
||||||
|
do {
|
||||||
|
int userId = query.getInt(0);
|
||||||
|
if (ignoredUsersIds.contains(userId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int chatId = query.getInt(1);
|
||||||
|
long time = query.getLong(7);
|
||||||
|
if (previousUserId != userId || previousChatId != chatId) {
|
||||||
|
gpx = new GPXFile();
|
||||||
|
gpx.chatId = chatId;
|
||||||
|
gpx.userId = userId;
|
||||||
|
previousTime = 0;
|
||||||
|
track = null;
|
||||||
|
segment = null;
|
||||||
|
dataTracks.add(gpx);
|
||||||
|
}
|
||||||
|
|
||||||
|
WptPt pt = new WptPt();
|
||||||
|
pt.userId = userId;
|
||||||
|
pt.chatId = chatId;
|
||||||
|
pt.lat = query.getDouble(2);
|
||||||
|
pt.lon = query.getDouble(3);
|
||||||
|
pt.ele = query.getDouble(4);
|
||||||
|
pt.speed = query.getDouble(5);
|
||||||
|
pt.hdop = query.getDouble(6);
|
||||||
|
pt.time = time;
|
||||||
|
long currentInterval = Math.abs(time - previousTime);
|
||||||
|
if (track != null) {
|
||||||
|
if (currentInterval < 30 * 60 * 1000) {
|
||||||
|
// 30 minute - same segment
|
||||||
|
segment.points.add(pt);
|
||||||
|
} else {
|
||||||
|
segment = new TrkSegment();
|
||||||
|
segment.points.add(pt);
|
||||||
|
track.segments.add(segment);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
track = new Track();
|
||||||
|
segment = new TrkSegment();
|
||||||
|
track.segments.add(segment);
|
||||||
|
segment.points.add(pt);
|
||||||
|
|
||||||
|
gpx.tracks.add(track);
|
||||||
|
}
|
||||||
|
previousTime = time;
|
||||||
|
previousUserId = userId;
|
||||||
|
previousChatId = chatId;
|
||||||
|
} while (query.moveToNext());
|
||||||
|
}
|
||||||
|
query.close();
|
||||||
|
}
|
||||||
|
|
||||||
private static class SaveGPXTrackToFileTask extends AsyncTask<Void, Void, List<String>> {
|
private static class SaveGPXTrackToFileTask extends AsyncTask<Void, Void, List<String>> {
|
||||||
|
|
||||||
private TelegramApplication app;
|
private TelegramApplication app;
|
||||||
private WeakReference<LiveNowTabFragment> fragmentRef;
|
private SaveGpxListener listener;
|
||||||
|
|
||||||
private final GPXFile gpxFile;
|
private final GPXFile gpxFile;
|
||||||
private File dir;
|
private File dir;
|
||||||
private int userId;
|
private int userId;
|
||||||
|
|
||||||
SaveGPXTrackToFileTask(LiveNowTabFragment fragment, GPXFile gpxFile, File dir, int userId) {
|
SaveGPXTrackToFileTask(TelegramApplication app, SaveGpxListener listener, GPXFile gpxFile, File dir, int userId) {
|
||||||
this.gpxFile = gpxFile;
|
this.gpxFile = gpxFile;
|
||||||
this.fragmentRef = new WeakReference<>(fragment);
|
this.listener = listener;
|
||||||
this.app = (TelegramApplication) fragment.getActivity().getApplication();
|
this.app = app;
|
||||||
this.dir = dir;
|
this.dir = dir;
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
}
|
}
|
||||||
|
@ -300,12 +454,21 @@ public class SavingTracksDbHelper extends SQLiteOpenHelper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(List<String> warnings) {
|
protected void onPostExecute(List<String> warnings) {
|
||||||
if (warnings != null && warnings.isEmpty()) {
|
if (listener != null) {
|
||||||
LiveNowTabFragment fragment = fragmentRef.get();
|
if (warnings != null && warnings.isEmpty()) {
|
||||||
if (fragment != null && fragment.isResumed()) {
|
listener.onSavingGpxFinish(gpxFile.path);
|
||||||
fragment.shareGpx(gpxFile.path);
|
} else {
|
||||||
|
listener.onSavingGpxError(warnings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public interface SaveGpxListener {
|
||||||
|
|
||||||
|
void onSavingGpxFinish(String path);
|
||||||
|
|
||||||
|
void onSavingGpxError(List<String> warnings);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -391,6 +391,15 @@ class TelegramHelper private constructor() {
|
||||||
|
|
||||||
fun isBot(userId: Int) = users[userId]?.type is TdApi.UserTypeBot
|
fun isBot(userId: Int) = users[userId]?.type is TdApi.UserTypeBot
|
||||||
|
|
||||||
|
fun getSenderMessageId(message: TdApi.Message): Int {
|
||||||
|
val forwardInfo = message.forwardInfo
|
||||||
|
return if (forwardInfo != null && forwardInfo is TdApi.MessageForwardedFromUser) {
|
||||||
|
forwardInfo.senderUserId
|
||||||
|
} else {
|
||||||
|
message.senderUserId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun startLiveMessagesUpdates(interval: Long) {
|
fun startLiveMessagesUpdates(interval: Long) {
|
||||||
stopLiveMessagesUpdates()
|
stopLiveMessagesUpdates()
|
||||||
|
|
||||||
|
@ -738,10 +747,13 @@ class TelegramHelper private constructor() {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
removeOldMessages(message, fromBot, viaBot)
|
removeOldMessages(message, fromBot, viaBot)
|
||||||
val oldMessage = usersLocationMessages.values.firstOrNull { it.senderUserId == message.senderUserId && !fromBot && !viaBot }
|
val oldMessage = usersLocationMessages.values.firstOrNull { getSenderMessageId(it) == getSenderMessageId(message) && !fromBot && !viaBot }
|
||||||
if (oldMessage == null || (Math.max(message.editDate, message.date) > Math.max(oldMessage.editDate, oldMessage.date))) {
|
val hasNewerMessage = oldMessage != null && (Math.max(message.editDate, message.date) < Math.max(oldMessage.editDate, oldMessage.date))
|
||||||
|
if (!hasNewerMessage) {
|
||||||
usersLocationMessages[message.id] = message
|
usersLocationMessages[message.id] = message
|
||||||
incomingMessagesListeners.forEach {
|
}
|
||||||
|
incomingMessagesListeners.forEach {
|
||||||
|
if (!hasNewerMessage || it is SavingTracksDbHelper) {
|
||||||
it.onReceiveChatLocationMessages(message.chatId, message)
|
it.onReceiveChatLocationMessages(message.chatId, message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -754,7 +766,7 @@ class TelegramHelper private constructor() {
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
val message = iterator.next().value
|
val message = iterator.next().value
|
||||||
if (newMessage.chatId == message.chatId) {
|
if (newMessage.chatId == message.chatId) {
|
||||||
val sameSender = newMessage.senderUserId == message.senderUserId
|
val sameSender = getSenderMessageId(newMessage) == getSenderMessageId(message)
|
||||||
val viaSameBot = newMessage.viaBotUserId == message.viaBotUserId
|
val viaSameBot = newMessage.viaBotUserId == message.viaBotUserId
|
||||||
if (fromBot || viaBot) {
|
if (fromBot || viaBot) {
|
||||||
if ((fromBot && sameSender) || (viaBot && viaSameBot)) {
|
if ((fromBot && sameSender) || (viaBot && viaSameBot)) {
|
||||||
|
@ -1075,23 +1087,6 @@ class TelegramHelper private constructor() {
|
||||||
return TdApi.InputMessageText(TdApi.FormattedText(textMessage, entities.toTypedArray()), true, true)
|
return TdApi.InputMessageText(TdApi.FormattedText(textMessage, entities.toTypedArray()), true, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @chatId Id of the chat
|
|
||||||
* @message Text of the message
|
|
||||||
*/
|
|
||||||
fun sendTextMessage(chatId: Long, message: String): Boolean {
|
|
||||||
// initialize reply markup just for testing
|
|
||||||
//val row = arrayOf(TdApi.InlineKeyboardButton("https://telegram.org?1", TdApi.InlineKeyboardButtonTypeUrl()), TdApi.InlineKeyboardButton("https://telegram.org?2", TdApi.InlineKeyboardButtonTypeUrl()), TdApi.InlineKeyboardButton("https://telegram.org?3", TdApi.InlineKeyboardButtonTypeUrl()))
|
|
||||||
//val replyMarkup = TdApi.ReplyMarkupInlineKeyboard(arrayOf(row, row, row))
|
|
||||||
|
|
||||||
if (haveAuthorization) {
|
|
||||||
val content = TdApi.InputMessageText(TdApi.FormattedText(message, null), false, true)
|
|
||||||
client?.send(TdApi.SendMessage(chatId, 0, false, true, null, content), defaultHandler)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
fun logout(): Boolean {
|
fun logout(): Boolean {
|
||||||
return if (libraryLoaded) {
|
return if (libraryLoaded) {
|
||||||
haveAuthorization = false
|
haveAuthorization = false
|
||||||
|
|
|
@ -8,6 +8,7 @@ import net.osmand.telegram.R
|
||||||
import net.osmand.telegram.TelegramApplication
|
import net.osmand.telegram.TelegramApplication
|
||||||
import net.osmand.telegram.helpers.TelegramHelper.MessageOsmAndBotLocation
|
import net.osmand.telegram.helpers.TelegramHelper.MessageOsmAndBotLocation
|
||||||
import net.osmand.telegram.helpers.TelegramHelper.MessageUserTextLocation
|
import net.osmand.telegram.helpers.TelegramHelper.MessageUserTextLocation
|
||||||
|
import net.osmand.telegram.utils.GPXUtilities
|
||||||
import org.drinkless.td.libcore.telegram.TdApi
|
import org.drinkless.td.libcore.telegram.TdApi
|
||||||
|
|
||||||
object TelegramUiHelper {
|
object TelegramUiHelper {
|
||||||
|
@ -129,6 +130,10 @@ object TelegramUiHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun gpxToChatItem(helper: TelegramHelper, gpx: GPXUtilities.GPXFile, simpleUserItem: Boolean): GpxChatItem? {
|
||||||
|
return if (simpleUserItem) gpxToUserGpxChatItem(helper, gpx) else gpxToGpxChatItem(helper, gpx)
|
||||||
|
}
|
||||||
|
|
||||||
private fun botMessageToLocationItem(
|
private fun botMessageToLocationItem(
|
||||||
chat: TdApi.Chat,
|
chat: TdApi.Chat,
|
||||||
content: MessageOsmAndBotLocation
|
content: MessageOsmAndBotLocation
|
||||||
|
@ -224,6 +229,49 @@ object TelegramUiHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun gpxToGpxChatItem(
|
||||||
|
helper: TelegramHelper,
|
||||||
|
gpx: GPXUtilities.GPXFile
|
||||||
|
): GpxChatItem? {
|
||||||
|
val user = helper.getUser(gpx.userId) ?: return null
|
||||||
|
val chat = helper.getChat(gpx.chatId) ?: return null
|
||||||
|
return GpxChatItem().apply {
|
||||||
|
chatId = chat.id
|
||||||
|
chatTitle = chat.title
|
||||||
|
gpxFile = gpx
|
||||||
|
name = TelegramUiHelper.getUserName(user)
|
||||||
|
if (helper.isGroup(chat)) {
|
||||||
|
photoPath = helper.getUserPhotoPath(user)
|
||||||
|
groupPhotoPath = chat.photo?.small?.local?.path
|
||||||
|
} else {
|
||||||
|
photoPath = user.profilePhoto?.small?.local?.path
|
||||||
|
}
|
||||||
|
grayscalePhotoPath = helper.getUserGreyPhotoPath(user)
|
||||||
|
placeholderId = R.drawable.img_user_picture
|
||||||
|
userId = user.id
|
||||||
|
privateChat = helper.isPrivateChat(chat) || helper.isSecretChat(chat)
|
||||||
|
chatWithBot = helper.isBot(userId)
|
||||||
|
lastUpdated = (gpx.modifiedTime / 1000).toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun gpxToUserGpxChatItem(
|
||||||
|
helper: TelegramHelper,
|
||||||
|
gpx: GPXUtilities.GPXFile
|
||||||
|
): GpxChatItem? {
|
||||||
|
val user = helper.getUser(gpx.userId) ?: return null
|
||||||
|
return GpxChatItem().apply {
|
||||||
|
gpxFile = gpx
|
||||||
|
name = TelegramUiHelper.getUserName(user)
|
||||||
|
photoPath = user.profilePhoto?.small?.local?.path
|
||||||
|
grayscalePhotoPath = helper.getUserGreyPhotoPath(user)
|
||||||
|
placeholderId = R.drawable.img_user_picture
|
||||||
|
userId = user.id
|
||||||
|
chatWithBot = helper.isBot(userId)
|
||||||
|
lastUpdated = (gpx.modifiedTime / 1000).toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
abstract class ListItem {
|
abstract class ListItem {
|
||||||
|
|
||||||
var chatId: Long = 0
|
var chatId: Long = 0
|
||||||
|
@ -272,6 +320,24 @@ object TelegramUiHelper {
|
||||||
override fun getVisibleName() = chatTitle
|
override fun getVisibleName() = chatTitle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GpxChatItem : ListItem() {
|
||||||
|
|
||||||
|
var gpxFile: GPXUtilities.GPXFile? = null
|
||||||
|
internal set
|
||||||
|
var groupPhotoPath: String? = null
|
||||||
|
internal set
|
||||||
|
var privateChat: Boolean = false
|
||||||
|
internal set
|
||||||
|
var chatWithBot: Boolean = false
|
||||||
|
internal set
|
||||||
|
|
||||||
|
override fun canBeOpenedOnMap() = latLon != null
|
||||||
|
|
||||||
|
override fun getMapPointId() = "${chatId}_$userId"
|
||||||
|
|
||||||
|
override fun getVisibleName() = chatTitle
|
||||||
|
}
|
||||||
|
|
||||||
class LocationItem : ListItem() {
|
class LocationItem : ListItem() {
|
||||||
|
|
||||||
override fun canBeOpenedOnMap() = latLon != null
|
override fun canBeOpenedOnMap() = latLon != null
|
||||||
|
|
|
@ -11,10 +11,7 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.animation.LinearInterpolator
|
import android.view.animation.LinearInterpolator
|
||||||
import android.widget.ArrayAdapter
|
import android.widget.*
|
||||||
import android.widget.ImageView
|
|
||||||
import android.widget.LinearLayout
|
|
||||||
import android.widget.TextView
|
|
||||||
import net.osmand.Location
|
import net.osmand.Location
|
||||||
import net.osmand.data.LatLon
|
import net.osmand.data.LatLon
|
||||||
import net.osmand.telegram.R
|
import net.osmand.telegram.R
|
||||||
|
@ -22,6 +19,7 @@ import net.osmand.telegram.TelegramApplication
|
||||||
import net.osmand.telegram.TelegramLocationProvider.TelegramCompassListener
|
import net.osmand.telegram.TelegramLocationProvider.TelegramCompassListener
|
||||||
import net.osmand.telegram.TelegramLocationProvider.TelegramLocationListener
|
import net.osmand.telegram.TelegramLocationProvider.TelegramLocationListener
|
||||||
import net.osmand.telegram.TelegramSettings
|
import net.osmand.telegram.TelegramSettings
|
||||||
|
import net.osmand.telegram.helpers.SavingTracksDbHelper
|
||||||
import net.osmand.telegram.helpers.TelegramHelper.*
|
import net.osmand.telegram.helpers.TelegramHelper.*
|
||||||
import net.osmand.telegram.helpers.TelegramUiHelper
|
import net.osmand.telegram.helpers.TelegramUiHelper
|
||||||
import net.osmand.telegram.helpers.TelegramUiHelper.ChatItem
|
import net.osmand.telegram.helpers.TelegramUiHelper.ChatItem
|
||||||
|
@ -33,7 +31,7 @@ import net.osmand.telegram.utils.OsmandFormatter
|
||||||
import net.osmand.telegram.utils.UiUtils.UpdateLocationViewCache
|
import net.osmand.telegram.utils.UiUtils.UpdateLocationViewCache
|
||||||
import net.osmand.util.MapUtils
|
import net.osmand.util.MapUtils
|
||||||
import org.drinkless.td.libcore.telegram.TdApi
|
import org.drinkless.td.libcore.telegram.TdApi
|
||||||
import java.io.File
|
import java.util.*
|
||||||
|
|
||||||
private const val CHAT_VIEW_TYPE = 0
|
private const val CHAT_VIEW_TYPE = 0
|
||||||
private const val LOCATION_ITEM_VIEW_TYPE = 1
|
private const val LOCATION_ITEM_VIEW_TYPE = 1
|
||||||
|
@ -233,15 +231,6 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
|
||||||
stopLocationUpdate()
|
stopLocationUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun shareGpx(path: String) {
|
|
||||||
val fileUri = AndroidUtils.getUriForFile(app, File(path))
|
|
||||||
val sendIntent = Intent(Intent.ACTION_SEND)
|
|
||||||
sendIntent.putExtra(Intent.EXTRA_STREAM, fileUri)
|
|
||||||
sendIntent.type = "application/gpx+xml"
|
|
||||||
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
|
||||||
startActivity(sendIntent)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun chooseOsmAnd() {
|
private fun chooseOsmAnd() {
|
||||||
val ctx = context ?: return
|
val ctx = context ?: return
|
||||||
val installedApps = TelegramSettings.AppConnect.getInstalledApps(ctx)
|
val installedApps = TelegramSettings.AppConnect.getInstalledApps(ctx)
|
||||||
|
@ -456,15 +445,6 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
|
||||||
app.showLocationHelper.showLocationOnMap(item, staleLocation)
|
app.showLocationHelper.showLocationOnMap(item, staleLocation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
openOnMapView?.setOnLongClickListener {
|
|
||||||
app.savingTracksDbHelper.saveAsyncUserDataToGpx(
|
|
||||||
this@LiveNowTabFragment,
|
|
||||||
app.getExternalFilesDir(null),
|
|
||||||
item.userId,
|
|
||||||
60 * 60 * 24 * 1000
|
|
||||||
)
|
|
||||||
true
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
openOnMapView?.setOnClickListener(null)
|
openOnMapView?.setOnClickListener(null)
|
||||||
}
|
}
|
||||||
|
@ -485,17 +465,6 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
|
||||||
if (lastItem) {
|
if (lastItem) {
|
||||||
holder.lastTelegramUpdateTime?.visibility = View.VISIBLE
|
holder.lastTelegramUpdateTime?.visibility = View.VISIBLE
|
||||||
holder.lastTelegramUpdateTime?.text = OsmandFormatter.getListItemLiveTimeDescr(app, telegramHelper.lastTelegramUpdateTime, lastTelegramUpdateStr)
|
holder.lastTelegramUpdateTime?.text = OsmandFormatter.getListItemLiveTimeDescr(app, telegramHelper.lastTelegramUpdateTime, lastTelegramUpdateStr)
|
||||||
holder.lastTelegramUpdateTime?.setOnClickListener {
|
|
||||||
val currentUserId = telegramHelper.getCurrentUser()?.id
|
|
||||||
if (currentUserId != null) {
|
|
||||||
app.savingTracksDbHelper.saveAsyncUserDataToGpx(
|
|
||||||
this@LiveNowTabFragment,
|
|
||||||
app.getExternalFilesDir(null),
|
|
||||||
currentUserId,
|
|
||||||
60 * 60 * 24 * 1000
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
holder.lastTelegramUpdateTime?.visibility = View.GONE
|
holder.lastTelegramUpdateTime?.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import net.osmand.telegram.ui.MyLocationTabFragment.ActionButtonsListener
|
||||||
import net.osmand.telegram.ui.views.LockableViewPager
|
import net.osmand.telegram.ui.views.LockableViewPager
|
||||||
import net.osmand.telegram.utils.*
|
import net.osmand.telegram.utils.*
|
||||||
import org.drinkless.td.libcore.telegram.TdApi
|
import org.drinkless.td.libcore.telegram.TdApi
|
||||||
|
import java.io.File
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
const val OPEN_MY_LOCATION_TAB_KEY = "open_my_location_tab"
|
const val OPEN_MY_LOCATION_TAB_KEY = "open_my_location_tab"
|
||||||
|
@ -35,6 +36,7 @@ private const val PERMISSION_REQUEST_LOCATION = 1
|
||||||
|
|
||||||
private const val MY_LOCATION_TAB_POS = 0
|
private const val MY_LOCATION_TAB_POS = 0
|
||||||
private const val LIVE_NOW_TAB_POS = 1
|
private const val LIVE_NOW_TAB_POS = 1
|
||||||
|
private const val TIMELINE_TAB_POS = 2
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListener, TelegramIncomingMessagesListener {
|
class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListener, TelegramIncomingMessagesListener {
|
||||||
|
|
||||||
|
@ -54,6 +56,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
||||||
|
|
||||||
private var myLocationTabFragment: MyLocationTabFragment? = null
|
private var myLocationTabFragment: MyLocationTabFragment? = null
|
||||||
private var liveNowTabFragment: LiveNowTabFragment? = null
|
private var liveNowTabFragment: LiveNowTabFragment? = null
|
||||||
|
private var timelineTabFragment: TimelineTabFragment? = null
|
||||||
|
|
||||||
private lateinit var buttonsBar: LinearLayout
|
private lateinit var buttonsBar: LinearLayout
|
||||||
private lateinit var bottomNav: BottomNavigationView
|
private lateinit var bottomNav: BottomNavigationView
|
||||||
|
@ -72,7 +75,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
||||||
|
|
||||||
val viewPager = findViewById<LockableViewPager>(R.id.view_pager).apply {
|
val viewPager = findViewById<LockableViewPager>(R.id.view_pager).apply {
|
||||||
swipeLocked = true
|
swipeLocked = true
|
||||||
offscreenPageLimit = 2
|
offscreenPageLimit = 3
|
||||||
adapter = ViewPagerAdapter(supportFragmentManager)
|
adapter = ViewPagerAdapter(supportFragmentManager)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,11 +85,13 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
||||||
when (it.itemId) {
|
when (it.itemId) {
|
||||||
R.id.action_my_location -> pos = MY_LOCATION_TAB_POS
|
R.id.action_my_location -> pos = MY_LOCATION_TAB_POS
|
||||||
R.id.action_live_now -> pos = LIVE_NOW_TAB_POS
|
R.id.action_live_now -> pos = LIVE_NOW_TAB_POS
|
||||||
|
R.id.action_timeline -> pos = TIMELINE_TAB_POS
|
||||||
}
|
}
|
||||||
if (pos != -1 && pos != viewPager.currentItem) {
|
if (pos != -1 && pos != viewPager.currentItem) {
|
||||||
when (pos) {
|
when (pos) {
|
||||||
MY_LOCATION_TAB_POS -> liveNowTabFragment?.tabClosed()
|
MY_LOCATION_TAB_POS -> liveNowTabFragment?.tabClosed()
|
||||||
LIVE_NOW_TAB_POS -> liveNowTabFragment?.tabOpened()
|
LIVE_NOW_TAB_POS -> liveNowTabFragment?.tabOpened()
|
||||||
|
TIMELINE_TAB_POS -> liveNowTabFragment?.tabClosed()
|
||||||
}
|
}
|
||||||
viewPager.currentItem = pos
|
viewPager.currentItem = pos
|
||||||
return@setOnNavigationItemSelectedListener true
|
return@setOnNavigationItemSelectedListener true
|
||||||
|
@ -139,10 +144,10 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
||||||
if (fragment is TelegramListener) {
|
if (fragment is TelegramListener) {
|
||||||
listeners.add(WeakReference(fragment))
|
listeners.add(WeakReference(fragment))
|
||||||
}
|
}
|
||||||
if (fragment is MyLocationTabFragment) {
|
when (fragment) {
|
||||||
myLocationTabFragment = fragment
|
is MyLocationTabFragment -> myLocationTabFragment = fragment
|
||||||
} else if (fragment is LiveNowTabFragment) {
|
is LiveNowTabFragment -> liveNowTabFragment = fragment
|
||||||
liveNowTabFragment = fragment
|
is TimelineTabFragment -> timelineTabFragment = fragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,6 +322,15 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
||||||
android.os.Process.killProcess(android.os.Process.myPid())
|
android.os.Process.killProcess(android.os.Process.myPid())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun shareGpx(path: String) {
|
||||||
|
val fileUri = AndroidUtils.getUriForFile(app, File(path))
|
||||||
|
val sendIntent = Intent(Intent.ACTION_SEND)
|
||||||
|
sendIntent.putExtra(Intent.EXTRA_STREAM, fileUri)
|
||||||
|
sendIntent.type = "application/gpx+xml"
|
||||||
|
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||||
|
startActivity(sendIntent)
|
||||||
|
}
|
||||||
|
|
||||||
fun loginTelegram() {
|
fun loginTelegram() {
|
||||||
if (telegramHelper.getTelegramAuthorizationState() != TelegramAuthorizationState.CLOSED) {
|
if (telegramHelper.getTelegramAuthorizationState() != TelegramAuthorizationState.CLOSED) {
|
||||||
telegramHelper.logout()
|
telegramHelper.logout()
|
||||||
|
@ -463,7 +477,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
||||||
|
|
||||||
class ViewPagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) {
|
class ViewPagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) {
|
||||||
|
|
||||||
private val fragments = listOf<Fragment>(MyLocationTabFragment(), LiveNowTabFragment())
|
private val fragments = listOf<Fragment>(MyLocationTabFragment(), LiveNowTabFragment(), TimelineTabFragment())
|
||||||
|
|
||||||
override fun getItem(position: Int) = fragments[position]
|
override fun getItem(position: Int) = fragments[position]
|
||||||
|
|
||||||
|
|
|
@ -599,12 +599,6 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
holder.title?.text = title
|
holder.title?.text = title
|
||||||
holder.icon?.setOnClickListener {
|
|
||||||
app.forceUpdateMyLocation()
|
|
||||||
val curUser = telegramHelper.getCurrentUser()
|
|
||||||
val text = "${curUser?.id} ${curUser?.firstName} ${curUser?.lastName}"
|
|
||||||
Toast.makeText(app, text, Toast.LENGTH_LONG).show()
|
|
||||||
}
|
|
||||||
if (holder is ChatViewHolder) {
|
if (holder is ChatViewHolder) {
|
||||||
holder.description?.visibility = View.GONE
|
holder.description?.visibility = View.GONE
|
||||||
if (live) {
|
if (live) {
|
||||||
|
|
|
@ -0,0 +1,261 @@
|
||||||
|
package net.osmand.telegram.ui
|
||||||
|
|
||||||
|
import android.app.DatePickerDialog
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.support.annotation.DrawableRes
|
||||||
|
import android.support.v4.app.Fragment
|
||||||
|
import android.support.v7.widget.LinearLayoutManager
|
||||||
|
import android.support.v7.widget.RecyclerView
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.Switch
|
||||||
|
import android.widget.TextView
|
||||||
|
import net.osmand.PlatformUtil
|
||||||
|
import net.osmand.telegram.R
|
||||||
|
import net.osmand.telegram.TelegramApplication
|
||||||
|
import net.osmand.telegram.helpers.TelegramUiHelper
|
||||||
|
import net.osmand.telegram.helpers.TelegramUiHelper.ListItem
|
||||||
|
import net.osmand.telegram.ui.TimelineTabFragment.LiveNowListAdapter.BaseViewHolder
|
||||||
|
import net.osmand.telegram.utils.AndroidUtils
|
||||||
|
import net.osmand.telegram.utils.OsmandFormatter
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
|
class TimelineTabFragment : Fragment() {
|
||||||
|
|
||||||
|
private val log = PlatformUtil.getLog(TimelineTabFragment::class.java)
|
||||||
|
|
||||||
|
private val app: TelegramApplication
|
||||||
|
get() = activity?.application as TelegramApplication
|
||||||
|
|
||||||
|
private val telegramHelper get() = app.telegramHelper
|
||||||
|
private val settings get() = app.settings
|
||||||
|
|
||||||
|
private lateinit var adapter: LiveNowListAdapter
|
||||||
|
|
||||||
|
private lateinit var dateStartBtn: TextView
|
||||||
|
private lateinit var dateEndBtn: TextView
|
||||||
|
private lateinit var mainView: View
|
||||||
|
|
||||||
|
private var start = 0L
|
||||||
|
private var end = 0L
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View? {
|
||||||
|
mainView = inflater.inflate(R.layout.fragment_timeline_tab, container, false)
|
||||||
|
val appBarLayout = mainView.findViewById<View>(R.id.app_bar_layout)
|
||||||
|
|
||||||
|
start = System.currentTimeMillis()
|
||||||
|
end = System.currentTimeMillis()
|
||||||
|
|
||||||
|
AndroidUtils.addStatusBarPadding19v(context!!, appBarLayout)
|
||||||
|
adapter = LiveNowListAdapter()
|
||||||
|
mainView.findViewById<RecyclerView>(R.id.recycler_view).apply {
|
||||||
|
layoutManager = LinearLayoutManager(context)
|
||||||
|
adapter = this@TimelineTabFragment.adapter
|
||||||
|
}
|
||||||
|
|
||||||
|
val switcher = mainView.findViewById<Switch>(R.id.monitoring_switcher)
|
||||||
|
val monitoringTv = mainView.findViewById<TextView>(R.id.monitoring_title)
|
||||||
|
monitoringTv.setText(if (settings.monitoringEnabled) R.string.monitoring_is_enabled else R.string.monitoring_is_disabled)
|
||||||
|
|
||||||
|
mainView.findViewById<View>(R.id.monitoring_container).setOnClickListener {
|
||||||
|
val monitoringEnabled = !settings.monitoringEnabled
|
||||||
|
settings.monitoringEnabled = monitoringEnabled
|
||||||
|
switcher.isChecked = monitoringEnabled
|
||||||
|
monitoringTv.setText(if (monitoringEnabled) R.string.monitoring_is_enabled else R.string.monitoring_is_disabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
dateStartBtn = mainView.findViewById<TextView>(R.id.date_start_btn).apply {
|
||||||
|
setOnClickListener {
|
||||||
|
selectStartDate()
|
||||||
|
}
|
||||||
|
setCompoundDrawablesWithIntrinsicBounds(getPressedStateIcon(R.drawable.ic_action_date_start), null, null, null)
|
||||||
|
}
|
||||||
|
dateEndBtn = mainView.findViewById<TextView>(R.id.date_end_btn).apply {
|
||||||
|
setOnClickListener {
|
||||||
|
selectEndDate()
|
||||||
|
}
|
||||||
|
setCompoundDrawablesWithIntrinsicBounds(getPressedStateIcon(R.drawable.ic_action_date_add), null, null, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
setupBtnTextColor(dateStartBtn)
|
||||||
|
setupBtnTextColor(dateEndBtn)
|
||||||
|
|
||||||
|
return mainView
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupBtnTextColor(textView: TextView) {
|
||||||
|
textView.setTextColor(AndroidUtils.createPressedColorStateList(app, true, R.color.ctrl_active_light, R.color.ctrl_light))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun selectStartDate() {
|
||||||
|
val dateFromDialog =
|
||||||
|
DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
|
||||||
|
val from = Calendar.getInstance()
|
||||||
|
from.set(Calendar.YEAR, year)
|
||||||
|
from.set(Calendar.MONTH, monthOfYear)
|
||||||
|
from.set(Calendar.DAY_OF_MONTH, dayOfMonth)
|
||||||
|
start = from.timeInMillis
|
||||||
|
updateList()
|
||||||
|
updateDateButtons()
|
||||||
|
}
|
||||||
|
val startCalendar = Calendar.getInstance()
|
||||||
|
startCalendar.timeInMillis = start
|
||||||
|
DatePickerDialog(context, dateFromDialog,
|
||||||
|
startCalendar.get(Calendar.YEAR),
|
||||||
|
startCalendar.get(Calendar.MONTH),
|
||||||
|
startCalendar.get(Calendar.DAY_OF_MONTH)
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun selectEndDate() {
|
||||||
|
val dateFromDialog =
|
||||||
|
DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
|
||||||
|
val from = Calendar.getInstance()
|
||||||
|
from.set(Calendar.YEAR, year)
|
||||||
|
from.set(Calendar.MONTH, monthOfYear)
|
||||||
|
from.set(Calendar.DAY_OF_MONTH, dayOfMonth)
|
||||||
|
end = from.timeInMillis
|
||||||
|
updateList()
|
||||||
|
updateDateButtons()
|
||||||
|
}
|
||||||
|
val endCalendar = Calendar.getInstance()
|
||||||
|
endCalendar.timeInMillis = end
|
||||||
|
DatePickerDialog(context, dateFromDialog,
|
||||||
|
endCalendar.get(Calendar.YEAR),
|
||||||
|
endCalendar.get(Calendar.MONTH),
|
||||||
|
endCalendar.get(Calendar.DAY_OF_MONTH)
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateDateButtons() {
|
||||||
|
dateStartBtn.text = OsmandFormatter.getFormattedDate(start / 1000)
|
||||||
|
dateEndBtn.text = OsmandFormatter.getFormattedDate(end / 1000)
|
||||||
|
dateEndBtn.setCompoundDrawablesWithIntrinsicBounds(getPressedStateIcon(R.drawable.ic_action_date_end), null, null, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getPressedStateIcon(@DrawableRes iconId: Int): Drawable? {
|
||||||
|
val normal = app.uiUtils.getActiveIcon(iconId)
|
||||||
|
if (Build.VERSION.SDK_INT >= 21) {
|
||||||
|
val active = app.uiUtils.getIcon(iconId, R.color.ctrl_light)
|
||||||
|
if (normal != null && active != null) {
|
||||||
|
return AndroidUtils.createPressedStateListDrawable(normal, active)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return normal
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateList() {
|
||||||
|
val res = mutableListOf<ListItem>()
|
||||||
|
val s = System.currentTimeMillis()
|
||||||
|
log.debug("updateList $start")
|
||||||
|
val ignoredUsersIds = ArrayList<Int>()
|
||||||
|
val currentUserId = telegramHelper.getCurrentUser()?.id
|
||||||
|
if (currentUserId != null) {
|
||||||
|
val currentUserGpx = app.savingTracksDbHelper.collectRecordedDataForUser(currentUserId, 0, start, end)
|
||||||
|
TelegramUiHelper.gpxToChatItem(telegramHelper, currentUserGpx, true)?.also {
|
||||||
|
res.add(it)
|
||||||
|
}
|
||||||
|
ignoredUsersIds.add(currentUserId)
|
||||||
|
}
|
||||||
|
val gpxFiles = app.savingTracksDbHelper.collectRecordedDataForUsers(start, end, ignoredUsersIds)
|
||||||
|
val e = System.currentTimeMillis()
|
||||||
|
|
||||||
|
gpxFiles.forEach {
|
||||||
|
TelegramUiHelper.gpxToChatItem(telegramHelper, it,false)?.also { chatItem ->
|
||||||
|
res.add(chatItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
adapter.items = sortAdapterItems(res)
|
||||||
|
log.debug("updateList $s dif: ${e - s}")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sortAdapterItems(list: MutableList<ListItem>): MutableList<ListItem> {
|
||||||
|
val currentUserId = telegramHelper.getCurrentUser()?.id ?: 0
|
||||||
|
list.sortWith(java.util.Comparator { lhs, rhs ->
|
||||||
|
when (currentUserId) {
|
||||||
|
lhs.userId -> return@Comparator 1
|
||||||
|
rhs.userId -> return@Comparator 1
|
||||||
|
else -> return@Comparator lhs.name.compareTo(rhs.name)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class LiveNowListAdapter : RecyclerView.Adapter<BaseViewHolder>() {
|
||||||
|
|
||||||
|
var items: List<ListItem> = emptyList()
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
|
||||||
|
val inflater = LayoutInflater.from(parent.context)
|
||||||
|
return BaseViewHolder(inflater.inflate(R.layout.live_now_chat_card, parent, false))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
|
||||||
|
val lastItem = position == itemCount - 1
|
||||||
|
val item = items[position]
|
||||||
|
val currentUserId = telegramHelper.getCurrentUser()?.id ?: 0
|
||||||
|
|
||||||
|
TelegramUiHelper.setupPhoto(app, holder.icon, item.photoPath, R.drawable.img_user_picture_active, false)
|
||||||
|
holder.title?.text = item.name
|
||||||
|
holder.bottomShadow?.visibility = if (lastItem) View.VISIBLE else View.GONE
|
||||||
|
holder.lastTelegramUpdateTime?.visibility = View.GONE
|
||||||
|
|
||||||
|
if (item is TelegramUiHelper.GpxChatItem) {
|
||||||
|
val gpx = item.gpxFile
|
||||||
|
val groupDescrRowVisible = (!item.privateChat || item.chatWithBot) && item.userId != currentUserId
|
||||||
|
if (groupDescrRowVisible) {
|
||||||
|
holder.groupDescrContainer?.visibility = View.VISIBLE
|
||||||
|
holder.groupTitle?.text = item.getVisibleName()
|
||||||
|
TelegramUiHelper.setupPhoto(app, holder.groupImage, item.groupPhotoPath, item.placeholderId, false)
|
||||||
|
} else {
|
||||||
|
holder.groupDescrContainer?.visibility = View.GONE
|
||||||
|
}
|
||||||
|
holder.userRow?.setOnClickListener {
|
||||||
|
if (gpx != null) {
|
||||||
|
childFragmentManager.also {
|
||||||
|
UserGpxInfoFragment.showInstance(it, gpx, start, end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
holder.imageButton?.visibility = View.GONE
|
||||||
|
holder.showOnMapRow?.visibility = View.GONE
|
||||||
|
holder.bottomDivider?.visibility = if (lastItem) View.GONE else View.VISIBLE
|
||||||
|
holder.topDivider?.visibility = if (position != 0) View.GONE else View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount() = items.size
|
||||||
|
|
||||||
|
inner class BaseViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||||
|
val icon: ImageView? = view.findViewById(R.id.icon)
|
||||||
|
val title: TextView? = view.findViewById(R.id.title)
|
||||||
|
val description: TextView? = view.findViewById(R.id.description)
|
||||||
|
val bottomShadow: View? = view.findViewById(R.id.bottom_shadow)
|
||||||
|
val lastTelegramUpdateTime: TextView? = view.findViewById(R.id.last_telegram_update_time)
|
||||||
|
|
||||||
|
val userRow: View? = view.findViewById(R.id.user_row)
|
||||||
|
val groupDescrContainer: View? = view.findViewById(R.id.group_container)
|
||||||
|
val groupImage: ImageView? = view.findViewById(R.id.group_icon)
|
||||||
|
val groupTitle: TextView? = view.findViewById(R.id.group_title)
|
||||||
|
val imageButton: ImageView? = view.findViewById(R.id.image_button)
|
||||||
|
val showOnMapRow: View? = view.findViewById(R.id.show_on_map_row)
|
||||||
|
val topDivider: View? = view.findViewById(R.id.top_divider)
|
||||||
|
val bottomDivider: View? = view.findViewById(R.id.bottom_divider)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,322 @@
|
||||||
|
package net.osmand.telegram.ui
|
||||||
|
|
||||||
|
import android.app.DatePickerDialog
|
||||||
|
import android.app.TimePickerDialog
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.graphics.drawable.BitmapDrawable
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.support.v4.app.FragmentManager
|
||||||
|
import android.util.DisplayMetrics
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.view.WindowManager
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.TextView
|
||||||
|
import android.widget.Toast
|
||||||
|
import net.osmand.PlatformUtil
|
||||||
|
import net.osmand.aidl.gpx.AGpxBitmap
|
||||||
|
import net.osmand.telegram.R
|
||||||
|
import net.osmand.telegram.helpers.OsmandAidlHelper
|
||||||
|
import net.osmand.telegram.helpers.SavingTracksDbHelper
|
||||||
|
import net.osmand.telegram.helpers.TelegramUiHelper
|
||||||
|
import net.osmand.telegram.utils.AndroidUtils
|
||||||
|
import net.osmand.telegram.utils.GPXUtilities
|
||||||
|
import net.osmand.telegram.utils.OsmandFormatter
|
||||||
|
import net.osmand.util.Algorithms
|
||||||
|
import java.io.File
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class UserGpxInfoFragment : BaseDialogFragment() {
|
||||||
|
|
||||||
|
private val log = PlatformUtil.getLog(UserGpxInfoFragment::class.java)
|
||||||
|
|
||||||
|
private val uiUtils get() = app.uiUtils
|
||||||
|
|
||||||
|
private lateinit var gpxFile: GPXUtilities.GPXFile
|
||||||
|
|
||||||
|
private lateinit var dateStartBtn: TextView
|
||||||
|
private lateinit var timeStartBtn: TextView
|
||||||
|
private lateinit var dateEndBtn: TextView
|
||||||
|
private lateinit var timeEndBtn: TextView
|
||||||
|
|
||||||
|
private lateinit var avgElevationTv: TextView
|
||||||
|
private lateinit var avgSpeedTv: TextView
|
||||||
|
private lateinit var totalDistanceTv: TextView
|
||||||
|
private lateinit var timeSpanTv: TextView
|
||||||
|
|
||||||
|
private var startCalendar = Calendar.getInstance()
|
||||||
|
private var endCalendar = Calendar.getInstance()
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
parent: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
val mainView = inflater.inflate(R.layout.fragment_user_gpx_info, parent)
|
||||||
|
AndroidUtils.addStatusBarPadding19v(context!!, mainView)
|
||||||
|
|
||||||
|
readFromBundle(savedInstanceState ?: arguments)
|
||||||
|
|
||||||
|
val userId = gpxFile.userId
|
||||||
|
val chatId = gpxFile.chatId
|
||||||
|
|
||||||
|
val user = app.telegramHelper.getUser(userId)
|
||||||
|
if (user != null) {
|
||||||
|
mainView.findViewById<TextView>(R.id.title).text = TelegramUiHelper.getUserName(user)
|
||||||
|
TelegramUiHelper.setupPhoto(app, mainView.findViewById<ImageView>(R.id.user_icon),
|
||||||
|
telegramHelper.getUserPhotoPath(user), R.drawable.img_user_placeholder, false)
|
||||||
|
}
|
||||||
|
app.osmandAidlHelper.setGpxBitmapCreatedListener(
|
||||||
|
object : OsmandAidlHelper.GpxBitmapCreatedListener {
|
||||||
|
override fun onGpxBitmapCreated(bitmap: AGpxBitmap) {
|
||||||
|
activity?.runOnUiThread {
|
||||||
|
mainView.findViewById<ImageView>(R.id.gpx_map).setImageDrawable(BitmapDrawable(app.resources, bitmap.bitmap))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
updateGPXMap()
|
||||||
|
|
||||||
|
val backBtn = mainView.findViewById<ImageView>(R.id.back_button)
|
||||||
|
backBtn.setImageDrawable(uiUtils.getThemedIcon(R.drawable.ic_arrow_back))
|
||||||
|
backBtn.setOnClickListener {
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
dateStartBtn = mainView.findViewById<TextView>(R.id.date_start_btn)
|
||||||
|
timeStartBtn = mainView.findViewById<TextView>(R.id.time_start_btn)
|
||||||
|
dateEndBtn = mainView.findViewById<TextView>(R.id.date_end_btn)
|
||||||
|
timeEndBtn = mainView.findViewById<TextView>(R.id.time_end_btn)
|
||||||
|
|
||||||
|
dateStartBtn.setOnClickListener { selectStartDate() }
|
||||||
|
timeStartBtn.setOnClickListener { selectStartTime() }
|
||||||
|
dateEndBtn.setOnClickListener { selectEndDate() }
|
||||||
|
timeEndBtn.setOnClickListener { selectEndTime() }
|
||||||
|
|
||||||
|
setupBtnTextColor(dateStartBtn)
|
||||||
|
setupBtnTextColor(timeStartBtn)
|
||||||
|
setupBtnTextColor(dateEndBtn)
|
||||||
|
setupBtnTextColor(timeEndBtn)
|
||||||
|
|
||||||
|
updateDateAndTimeButtons()
|
||||||
|
|
||||||
|
avgElevationTv = mainView.findViewById<TextView>(R.id.average_altitude_text)
|
||||||
|
avgSpeedTv = mainView.findViewById<TextView>(R.id.average_speed_text)
|
||||||
|
totalDistanceTv = mainView.findViewById<TextView>(R.id.distance_text)
|
||||||
|
timeSpanTv = mainView.findViewById<TextView>(R.id.duration_text)
|
||||||
|
|
||||||
|
mainView.findViewById<ImageView>(R.id.average_altitude_icon).apply {
|
||||||
|
setImageDrawable(uiUtils.getThemedIcon(R.drawable.ic_action_altitude_range))
|
||||||
|
}
|
||||||
|
mainView.findViewById<ImageView>(R.id.average_speed_icon).apply {
|
||||||
|
setImageDrawable(uiUtils.getThemedIcon(R.drawable.ic_action_speed_average))
|
||||||
|
}
|
||||||
|
mainView.findViewById<ImageView>(R.id.distance_icon).apply {
|
||||||
|
setImageDrawable(uiUtils.getThemedIcon(R.drawable.ic_action_altitude_range))
|
||||||
|
}
|
||||||
|
mainView.findViewById<ImageView>(R.id.duration_icon).apply {
|
||||||
|
setImageDrawable(uiUtils.getThemedIcon(R.drawable.ic_action_altitude_range))
|
||||||
|
}
|
||||||
|
|
||||||
|
updateGPXStatisticRow()
|
||||||
|
|
||||||
|
mainView.findViewById<ImageView>(R.id.open_in_osmand_icon).setImageResource(R.drawable.ic_logo_osmand_free)
|
||||||
|
|
||||||
|
mainView.findViewById<LinearLayout>(R.id.open_in_osmand_btn).apply {
|
||||||
|
setOnClickListener {
|
||||||
|
val gpx = gpxFile
|
||||||
|
if (gpx.path.isNotEmpty()) {
|
||||||
|
openGpx(gpx.path)
|
||||||
|
} else {
|
||||||
|
saveCurrentGpxToFile(object :
|
||||||
|
SavingTracksDbHelper.SaveGpxListener {
|
||||||
|
override fun onSavingGpxFinish(path: String) {
|
||||||
|
openGpx(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSavingGpxError(warnings: MutableList<String>?) {
|
||||||
|
Toast.makeText(app, warnings?.firstOrNull(), Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mainView.findViewById<ImageView>(R.id.share_gpx_icon).setImageDrawable(uiUtils.getActiveIcon(R.drawable.ic_action_share))
|
||||||
|
|
||||||
|
mainView.findViewById<LinearLayout>(R.id.share_gpx_btn).apply {
|
||||||
|
setOnClickListener {
|
||||||
|
val gpx = gpxFile
|
||||||
|
if (gpx.path.isNotEmpty()) {
|
||||||
|
(activity as MainActivity).shareGpx(gpx.path)
|
||||||
|
} else {
|
||||||
|
saveCurrentGpxToFile(object :
|
||||||
|
SavingTracksDbHelper.SaveGpxListener {
|
||||||
|
override fun onSavingGpxFinish(path: String) {
|
||||||
|
(activity as MainActivity).shareGpx(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSavingGpxError(warnings: MutableList<String>?) {
|
||||||
|
Toast.makeText(app, warnings?.firstOrNull(), Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mainView
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
|
super.onSaveInstanceState(outState)
|
||||||
|
outState.putLong(START_KEY, startCalendar.timeInMillis)
|
||||||
|
outState.putLong(END_KEY, endCalendar.timeInMillis)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun openGpx(path: String) {
|
||||||
|
val fileUri = AndroidUtils.getUriForFile(app, File(path))
|
||||||
|
val openGpxIntent = Intent(Intent.ACTION_VIEW)
|
||||||
|
openGpxIntent.setDataAndType(fileUri, "application/gpx+xml")
|
||||||
|
// openGpxIntent.type = "application/gpx+xml"
|
||||||
|
openGpxIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||||
|
val resolved = activity?.packageManager?.resolveActivity(openGpxIntent, PackageManager.MATCH_DEFAULT_ONLY)
|
||||||
|
if (resolved != null) {
|
||||||
|
startActivity(openGpxIntent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun saveCurrentGpxToFile(listener: SavingTracksDbHelper.SaveGpxListener) {
|
||||||
|
app.savingTracksDbHelper.saveGpx(listener, app.getExternalFilesDir(null), gpxFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun readFromBundle(bundle: Bundle?) {
|
||||||
|
bundle?.also {
|
||||||
|
startCalendar.timeInMillis = it.getLong(START_KEY)
|
||||||
|
endCalendar.timeInMillis = it.getLong(END_KEY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupBtnTextColor(textView: TextView) {
|
||||||
|
textView.setTextColor(AndroidUtils.createPressedColorStateList(app, true, R.color.ctrl_active_light, R.color.ctrl_light))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateGpxInfo() {
|
||||||
|
gpxFile = app.savingTracksDbHelper.collectRecordedDataForUser(gpxFile.userId, gpxFile.chatId, startCalendar.timeInMillis, endCalendar.timeInMillis)
|
||||||
|
updateGPXStatisticRow()
|
||||||
|
updateDateAndTimeButtons()
|
||||||
|
updateGPXMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateDateAndTimeButtons() {
|
||||||
|
dateStartBtn.text = SimpleDateFormat("dd MMM", Locale.getDefault()).format(startCalendar.timeInMillis)
|
||||||
|
dateEndBtn.text = SimpleDateFormat("dd MMM", Locale.getDefault()).format(endCalendar.timeInMillis)
|
||||||
|
|
||||||
|
timeStartBtn.text = SimpleDateFormat("HH:mm", Locale.getDefault()).format(startCalendar.timeInMillis)
|
||||||
|
timeEndBtn.text = SimpleDateFormat("HH:mm", Locale.getDefault()).format(endCalendar.timeInMillis)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateGPXStatisticRow() {
|
||||||
|
val analysis: GPXUtilities.GPXTrackAnalysis = gpxFile.getAnalysis(0)
|
||||||
|
avgElevationTv.text = OsmandFormatter.getFormattedAlt(analysis.avgElevation, app)
|
||||||
|
avgSpeedTv.text = if (analysis.isSpeedSpecified) OsmandFormatter.getFormattedSpeed(analysis.avgSpeed, app) else ""
|
||||||
|
totalDistanceTv.text = OsmandFormatter.getFormattedDistance(analysis.totalDistance, app)
|
||||||
|
timeSpanTv.text = Algorithms.formatDuration((analysis.timeSpan / 1000).toInt(), true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateGPXMap() {
|
||||||
|
saveCurrentGpxToFile(object :
|
||||||
|
SavingTracksDbHelper.SaveGpxListener {
|
||||||
|
override fun onSavingGpxFinish(path: String) {
|
||||||
|
val mgr = activity?.getSystemService(Context.WINDOW_SERVICE)
|
||||||
|
if (mgr != null) {
|
||||||
|
val dm = DisplayMetrics()
|
||||||
|
(mgr as WindowManager).defaultDisplay.getMetrics(dm)
|
||||||
|
val widthPixels = dm.widthPixels - (2 * app.resources.getDimensionPixelSize(R.dimen.content_padding_standard))
|
||||||
|
val heightPixels = AndroidUtils.dpToPx(app, 152f)
|
||||||
|
val gpxUri = AndroidUtils.getUriForFile(app, File(path))
|
||||||
|
app.osmandAidlHelper.getBitmapForGpx(gpxUri, dm.density , widthPixels, heightPixels, GPX_TRACK_COLOR)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSavingGpxError(warnings: MutableList<String>?) {
|
||||||
|
log.debug("onSavingGpxError ${warnings?.firstOrNull()}")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun selectStartDate() {
|
||||||
|
val dateFromDialog =
|
||||||
|
DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
|
||||||
|
startCalendar.set(Calendar.YEAR, year)
|
||||||
|
startCalendar.set(Calendar.MONTH, monthOfYear)
|
||||||
|
startCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth)
|
||||||
|
updateGpxInfo()
|
||||||
|
}
|
||||||
|
DatePickerDialog(context, dateFromDialog,
|
||||||
|
startCalendar.get(Calendar.YEAR),
|
||||||
|
startCalendar.get(Calendar.MONTH),
|
||||||
|
startCalendar.get(Calendar.DAY_OF_MONTH)).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun selectStartTime() {
|
||||||
|
TimePickerDialog(context,
|
||||||
|
TimePickerDialog.OnTimeSetListener { _, hours, minutes ->
|
||||||
|
startCalendar.set(Calendar.HOUR_OF_DAY, hours)
|
||||||
|
startCalendar.set(Calendar.MINUTE, minutes)
|
||||||
|
updateGpxInfo()
|
||||||
|
}, 0, 0, true).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun selectEndDate() {
|
||||||
|
val dateFromDialog =
|
||||||
|
DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
|
||||||
|
endCalendar.set(Calendar.YEAR, year)
|
||||||
|
endCalendar.set(Calendar.MONTH, monthOfYear)
|
||||||
|
endCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth)
|
||||||
|
updateGpxInfo()
|
||||||
|
}
|
||||||
|
DatePickerDialog(context, dateFromDialog,
|
||||||
|
endCalendar.get(Calendar.YEAR),
|
||||||
|
endCalendar.get(Calendar.MONTH),
|
||||||
|
endCalendar.get(Calendar.DAY_OF_MONTH)).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun selectEndTime() {
|
||||||
|
TimePickerDialog(context,
|
||||||
|
TimePickerDialog.OnTimeSetListener { _, hours, minutes ->
|
||||||
|
endCalendar.set(Calendar.HOUR_OF_DAY, hours)
|
||||||
|
endCalendar.set(Calendar.MINUTE, minutes)
|
||||||
|
updateGpxInfo()
|
||||||
|
}, 0, 0, true).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
private const val TAG = "UserGpxInfoFragment"
|
||||||
|
private const val START_KEY = "start_key"
|
||||||
|
private const val END_KEY = "end_key"
|
||||||
|
|
||||||
|
private const val GPX_TRACK_COLOR = -65536
|
||||||
|
|
||||||
|
fun showInstance(fm: FragmentManager, gpxFile: GPXUtilities.GPXFile, start: Long, end: Long): Boolean {
|
||||||
|
return try {
|
||||||
|
val fragment = UserGpxInfoFragment().apply {
|
||||||
|
arguments = Bundle().apply {
|
||||||
|
putLong(START_KEY, start)
|
||||||
|
putLong(END_KEY, end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fragment.gpxFile = gpxFile
|
||||||
|
fragment.show(fm, TAG)
|
||||||
|
true
|
||||||
|
} catch (e: RuntimeException) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ import android.text.TextUtils;
|
||||||
|
|
||||||
import net.osmand.Location;
|
import net.osmand.Location;
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
|
import net.osmand.data.QuadRect;
|
||||||
import net.osmand.data.RotatedTileBox;
|
import net.osmand.data.RotatedTileBox;
|
||||||
import net.osmand.telegram.TelegramApplication;
|
import net.osmand.telegram.TelegramApplication;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
@ -49,7 +50,7 @@ import java.util.Set;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
// copy from net.osmand.plus.GPXUtilities and changes done to WptPt (userId,chatId)
|
// copy from net.osmand.plus.GPXUtilities and changes done to WptPt and GPXFile (userId,chatId)
|
||||||
|
|
||||||
public class GPXUtilities {
|
public class GPXUtilities {
|
||||||
public final static Log log = PlatformUtil.getLog(GPXUtilities.class);
|
public final static Log log = PlatformUtil.getLog(GPXUtilities.class);
|
||||||
|
@ -815,6 +816,8 @@ public class GPXUtilities {
|
||||||
public String path = "";
|
public String path = "";
|
||||||
public boolean showCurrentTrack;
|
public boolean showCurrentTrack;
|
||||||
public long modifiedTime = 0;
|
public long modifiedTime = 0;
|
||||||
|
public int userId;
|
||||||
|
public long chatId;
|
||||||
|
|
||||||
private Track generalTrack;
|
private Track generalTrack;
|
||||||
private TrkSegment generalSegment;
|
private TrkSegment generalSegment;
|
||||||
|
@ -1248,6 +1251,57 @@ public class GPXUtilities {
|
||||||
}
|
}
|
||||||
return categories;
|
return categories;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public QuadRect getRect() {
|
||||||
|
double left = 0, right = 0;
|
||||||
|
double top = 0, bottom = 0;
|
||||||
|
for (Track track : tracks) {
|
||||||
|
for (TrkSegment segment : track.segments) {
|
||||||
|
for (WptPt p : segment.points) {
|
||||||
|
if (left == 0 && right == 0) {
|
||||||
|
left = p.getLongitude();
|
||||||
|
right = p.getLongitude();
|
||||||
|
top = p.getLatitude();
|
||||||
|
bottom = p.getLatitude();
|
||||||
|
} else {
|
||||||
|
left = Math.min(left, p.getLongitude());
|
||||||
|
right = Math.max(right, p.getLongitude());
|
||||||
|
top = Math.max(top, p.getLatitude());
|
||||||
|
bottom = Math.min(bottom, p.getLatitude());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (WptPt p : points) {
|
||||||
|
if (left == 0 && right == 0) {
|
||||||
|
left = p.getLongitude();
|
||||||
|
right = p.getLongitude();
|
||||||
|
top = p.getLatitude();
|
||||||
|
bottom = p.getLatitude();
|
||||||
|
} else {
|
||||||
|
left = Math.min(left, p.getLongitude());
|
||||||
|
right = Math.max(right, p.getLongitude());
|
||||||
|
top = Math.max(top, p.getLatitude());
|
||||||
|
bottom = Math.min(bottom, p.getLatitude());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (GPXUtilities.Route route : routes) {
|
||||||
|
for (WptPt p : route.points) {
|
||||||
|
if (left == 0 && right == 0) {
|
||||||
|
left = p.getLongitude();
|
||||||
|
right = p.getLongitude();
|
||||||
|
top = p.getLatitude();
|
||||||
|
bottom = p.getLatitude();
|
||||||
|
} else {
|
||||||
|
left = Math.min(left, p.getLongitude());
|
||||||
|
right = Math.max(right, p.getLongitude());
|
||||||
|
top = Math.max(top, p.getLatitude());
|
||||||
|
bottom = Math.min(bottom, p.getLatitude());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new QuadRect(left, top, right, bottom);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String asString(GPXFile file, TelegramApplication ctx) {
|
public static String asString(GPXFile file, TelegramApplication ctx) {
|
||||||
|
|
|
@ -23,6 +23,7 @@ object OsmandFormatter {
|
||||||
private const val SHORT_TIME_FORMAT = "%02d:%02d"
|
private const val SHORT_TIME_FORMAT = "%02d:%02d"
|
||||||
private const val SIMPLE_TIME_OF_DAY_FORMAT = "HH:mm"
|
private const val SIMPLE_TIME_OF_DAY_FORMAT = "HH:mm"
|
||||||
private const val SIMPLE_DATE_FORMAT = "dd MMM HH:mm:ss"
|
private const val SIMPLE_DATE_FORMAT = "dd MMM HH:mm:ss"
|
||||||
|
private const val SHORT_DATE_FORMAT = "dd MMM yyyy"
|
||||||
|
|
||||||
private const val MIN_DURATION_FOR_DATE_FORMAT = 48 * 60 * 60
|
private const val MIN_DURATION_FOR_DATE_FORMAT = 48 * 60 * 60
|
||||||
|
|
||||||
|
@ -77,8 +78,13 @@ object OsmandFormatter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getFormattedDate(seconds: Long): String =
|
fun getFormattedDate(seconds: Long, shortFormat: Boolean = false): String {
|
||||||
SimpleDateFormat(SIMPLE_DATE_FORMAT, Locale.getDefault()).format(seconds * 1000L)
|
return if (shortFormat) {
|
||||||
|
SimpleDateFormat(SIMPLE_DATE_FORMAT, Locale.getDefault()).format(seconds * 1000L)
|
||||||
|
} else {
|
||||||
|
SimpleDateFormat(SHORT_DATE_FORMAT, Locale.getDefault()).format(seconds * 1000L)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getListItemLiveTimeDescr(ctx: TelegramApplication, lastUpdated: Int, prefix: String = ""): String {
|
fun getListItemLiveTimeDescr(ctx: TelegramApplication, lastUpdated: Int, prefix: String = ""): String {
|
||||||
return if (lastUpdated > 0) {
|
return if (lastUpdated > 0) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package net.osmand.aidl;
|
package net.osmand.aidl;
|
||||||
|
|
||||||
import net.osmand.aidl.search.SearchResult;
|
import net.osmand.aidl.search.SearchResult;
|
||||||
|
import net.osmand.aidl.gpx.AGpxBitmap;
|
||||||
|
|
||||||
interface IOsmAndAidlCallback {
|
interface IOsmAndAidlCallback {
|
||||||
void onSearchComplete(in List<SearchResult> resultSet);
|
void onSearchComplete(in List<SearchResult> resultSet);
|
||||||
|
@ -8,4 +9,6 @@ interface IOsmAndAidlCallback {
|
||||||
void onUpdate();
|
void onUpdate();
|
||||||
|
|
||||||
void onAppInitialized();
|
void onAppInitialized();
|
||||||
|
|
||||||
|
void onGpxBitmapCreated(in AGpxBitmap bitmap);
|
||||||
}
|
}
|
|
@ -74,6 +74,8 @@ import net.osmand.aidl.customization.OsmandSettingsParams;
|
||||||
|
|
||||||
import net.osmand.aidl.gpx.AGpxFile;
|
import net.osmand.aidl.gpx.AGpxFile;
|
||||||
import net.osmand.aidl.gpx.AGpxFileDetails;
|
import net.osmand.aidl.gpx.AGpxFileDetails;
|
||||||
|
import net.osmand.aidl.gpx.CreateGpxBitmapParams;
|
||||||
|
|
||||||
import net.osmand.aidl.tiles.ASqliteDbFile;
|
import net.osmand.aidl.tiles.ASqliteDbFile;
|
||||||
|
|
||||||
import net.osmand.aidl.plugins.PluginParams;
|
import net.osmand.aidl.plugins.PluginParams;
|
||||||
|
@ -175,4 +177,6 @@ interface IOsmAndAidlInterface {
|
||||||
boolean changePluginState(in PluginParams params);
|
boolean changePluginState(in PluginParams params);
|
||||||
|
|
||||||
boolean registerForOsmandInitListener(in IOsmAndAidlCallback callback);
|
boolean registerForOsmandInitListener(in IOsmAndAidlCallback callback);
|
||||||
|
|
||||||
|
boolean getBitmapForGpx(in CreateGpxBitmapParams file, IOsmAndAidlCallback callback);
|
||||||
}
|
}
|
|
@ -10,6 +10,7 @@ import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
@ -24,10 +25,12 @@ import android.text.TextUtils;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
|
|
||||||
|
import net.osmand.CallbackWithObject;
|
||||||
import net.osmand.IndexConstants;
|
import net.osmand.IndexConstants;
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
import net.osmand.aidl.favorite.AFavorite;
|
import net.osmand.aidl.favorite.AFavorite;
|
||||||
import net.osmand.aidl.favorite.group.AFavoriteGroup;
|
import net.osmand.aidl.favorite.group.AFavoriteGroup;
|
||||||
|
import net.osmand.aidl.gpx.AGpxBitmap;
|
||||||
import net.osmand.aidl.gpx.AGpxFile;
|
import net.osmand.aidl.gpx.AGpxFile;
|
||||||
import net.osmand.aidl.gpx.AGpxFileDetails;
|
import net.osmand.aidl.gpx.AGpxFileDetails;
|
||||||
import net.osmand.aidl.gpx.ASelectedGpxFile;
|
import net.osmand.aidl.gpx.ASelectedGpxFile;
|
||||||
|
@ -69,6 +72,7 @@ import net.osmand.plus.dialogs.ConfigureMapMenu;
|
||||||
import net.osmand.plus.helpers.ColorDialogs;
|
import net.osmand.plus.helpers.ColorDialogs;
|
||||||
import net.osmand.plus.helpers.ExternalApiHelper;
|
import net.osmand.plus.helpers.ExternalApiHelper;
|
||||||
import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
|
import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
|
||||||
|
import net.osmand.plus.myplaces.TrackBitmapDrawer;
|
||||||
import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin;
|
import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin;
|
||||||
import net.osmand.plus.routing.RoutingHelper;
|
import net.osmand.plus.routing.RoutingHelper;
|
||||||
import net.osmand.plus.views.AidlMapLayer;
|
import net.osmand.plus.views.AidlMapLayer;
|
||||||
|
@ -1907,7 +1911,96 @@ public class OsmandAidlApi {
|
||||||
return app.getAppCustomization().changePluginStatus(params);
|
return app.getAppCustomization().changePluginStatus(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean getBitmapForGpx(final Uri gpxUri, final float density, final int widthPixels, final int heightPixels, final int color, final GpxBitmapCreatedCallback callback) {
|
||||||
|
if (gpxUri == null || callback == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final TrackBitmapDrawer.TrackBitmapDrawerListener drawerListener = new TrackBitmapDrawer.TrackBitmapDrawerListener() {
|
||||||
|
@Override
|
||||||
|
public void onTrackBitmapDrawing() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTrackBitmapDrawn() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTrackBitmapSelectionSupported() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawTrackBitmap(Bitmap bitmap) {
|
||||||
|
callback.onGpxBitmapCreatedComplete(new AGpxBitmap(bitmap));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (app.isApplicationInitializing()) {
|
||||||
|
app.getAppInitializer().addListener(new AppInitializer.AppInitializeListener() {
|
||||||
|
@Override
|
||||||
|
public void onProgress(AppInitializer init, AppInitializer.InitEvents event) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish(AppInitializer init) {
|
||||||
|
createGpxBitmapFromUri(gpxUri, density, widthPixels, heightPixels, color, drawerListener);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
createGpxBitmapFromUri(gpxUri, density, widthPixels, heightPixels, color, drawerListener);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createGpxBitmapFromUri(final Uri gpxUri, final float density, final int widthPixels, final int heightPixels, final int color, final TrackBitmapDrawer.TrackBitmapDrawerListener drawerListener) {
|
||||||
|
GpxAsyncLoaderTask gpxAsyncLoaderTask = new GpxAsyncLoaderTask(app, gpxUri, new CallbackWithObject<GPXFile>() {
|
||||||
|
@Override
|
||||||
|
public boolean processResult(GPXFile result) {
|
||||||
|
TrackBitmapDrawer trackBitmapDrawer = new TrackBitmapDrawer(app, result, null, result.getRect(), density, widthPixels, heightPixels);
|
||||||
|
trackBitmapDrawer.addListener(drawerListener);
|
||||||
|
trackBitmapDrawer.setDrawEnabled(true);
|
||||||
|
trackBitmapDrawer.setTrackColor(color);
|
||||||
|
trackBitmapDrawer.initAndDraw();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
gpxAsyncLoaderTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class GpxAsyncLoaderTask extends AsyncTask<Void, Void, GPXFile> {
|
||||||
|
|
||||||
|
private final OsmandApplication app;
|
||||||
|
private final CallbackWithObject<GPXFile> callback;
|
||||||
|
private final Uri gpxUri;
|
||||||
|
|
||||||
|
GpxAsyncLoaderTask(@NonNull OsmandApplication app, @NonNull Uri gpxUri, final CallbackWithObject<GPXFile> callback) {
|
||||||
|
this.app = app;
|
||||||
|
this.gpxUri = gpxUri;
|
||||||
|
this.callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(GPXFile gpxFile) {
|
||||||
|
if (gpxFile.warning == null && callback != null) {
|
||||||
|
callback.processResult(gpxFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected GPXFile doInBackground(Void... voids) {
|
||||||
|
ParcelFileDescriptor gpxParcelDescriptor = null;
|
||||||
|
try {
|
||||||
|
gpxParcelDescriptor = app.getContentResolver().openFileDescriptor(gpxUri, "r");
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
if (gpxParcelDescriptor != null) {
|
||||||
|
final FileDescriptor fileDescriptor = gpxParcelDescriptor.getFileDescriptor();
|
||||||
|
return GPXUtilities.loadGPXFile(app, new FileInputStream(fileDescriptor));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static AGpxFileDetails createGpxFileDetails(@NonNull GPXTrackAnalysis a) {
|
private static AGpxFileDetails createGpxFileDetails(@NonNull GPXTrackAnalysis a) {
|
||||||
return new AGpxFileDetails(a.totalDistance, a.totalTracks, a.startTime, a.endTime,
|
return new AGpxFileDetails(a.totalDistance, a.totalTracks, a.startTime, a.endTime,
|
||||||
|
@ -1980,6 +2073,10 @@ public class OsmandAidlApi {
|
||||||
void onSearchComplete(List<SearchResult> resultSet);
|
void onSearchComplete(List<SearchResult> resultSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface GpxBitmapCreatedCallback {
|
||||||
|
void onGpxBitmapCreatedComplete(AGpxBitmap aGpxBitmap);
|
||||||
|
}
|
||||||
|
|
||||||
public interface OsmandAppInitCallback {
|
public interface OsmandAppInitCallback {
|
||||||
void onAppInitialized();
|
void onAppInitialized();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import android.os.RemoteException;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
|
import net.osmand.aidl.OsmandAidlApi.GpxBitmapCreatedCallback;
|
||||||
import net.osmand.aidl.OsmandAidlApi.OsmandAppInitCallback;
|
import net.osmand.aidl.OsmandAidlApi.OsmandAppInitCallback;
|
||||||
import net.osmand.aidl.OsmandAidlApi.SearchCompleteCallback;
|
import net.osmand.aidl.OsmandAidlApi.SearchCompleteCallback;
|
||||||
import net.osmand.aidl.calculateroute.CalculateRouteParams;
|
import net.osmand.aidl.calculateroute.CalculateRouteParams;
|
||||||
|
@ -22,8 +23,10 @@ import net.osmand.aidl.favorite.UpdateFavoriteParams;
|
||||||
import net.osmand.aidl.favorite.group.AddFavoriteGroupParams;
|
import net.osmand.aidl.favorite.group.AddFavoriteGroupParams;
|
||||||
import net.osmand.aidl.favorite.group.RemoveFavoriteGroupParams;
|
import net.osmand.aidl.favorite.group.RemoveFavoriteGroupParams;
|
||||||
import net.osmand.aidl.favorite.group.UpdateFavoriteGroupParams;
|
import net.osmand.aidl.favorite.group.UpdateFavoriteGroupParams;
|
||||||
|
import net.osmand.aidl.gpx.AGpxBitmap;
|
||||||
import net.osmand.aidl.gpx.AGpxFile;
|
import net.osmand.aidl.gpx.AGpxFile;
|
||||||
import net.osmand.aidl.gpx.ASelectedGpxFile;
|
import net.osmand.aidl.gpx.ASelectedGpxFile;
|
||||||
|
import net.osmand.aidl.gpx.CreateGpxBitmapParams;
|
||||||
import net.osmand.aidl.gpx.HideGpxParams;
|
import net.osmand.aidl.gpx.HideGpxParams;
|
||||||
import net.osmand.aidl.gpx.ImportGpxParams;
|
import net.osmand.aidl.gpx.ImportGpxParams;
|
||||||
import net.osmand.aidl.gpx.RemoveGpxParams;
|
import net.osmand.aidl.gpx.RemoveGpxParams;
|
||||||
|
@ -822,5 +825,25 @@ public class OsmandAidlService extends Service {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getBitmapForGpx(CreateGpxBitmapParams params, final IOsmAndAidlCallback callback) throws RemoteException {
|
||||||
|
try {
|
||||||
|
OsmandAidlApi api = getApi("getBitmapForGpx");
|
||||||
|
return params != null && api != null && api.getBitmapForGpx(params.getGpxUri(), params.getDensity(), params.getWidthPixels(), params.getHeightPixels(), params.getColor(), new GpxBitmapCreatedCallback() {
|
||||||
|
@Override
|
||||||
|
public void onGpxBitmapCreatedComplete(AGpxBitmap aGpxBitmap) {
|
||||||
|
try {
|
||||||
|
callback.onGpxBitmapCreated(aGpxBitmap);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
handleException(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
3
OsmAnd/src/net/osmand/aidl/gpx/AGpxBitmap.aidl
Normal file
3
OsmAnd/src/net/osmand/aidl/gpx/AGpxBitmap.aidl
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
package net.osmand.aidl.gpx;
|
||||||
|
|
||||||
|
parcelable AGpxBitmap;
|
46
OsmAnd/src/net/osmand/aidl/gpx/AGpxBitmap.java
Normal file
46
OsmAnd/src/net/osmand/aidl/gpx/AGpxBitmap.java
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
package net.osmand.aidl.gpx;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
public class AGpxBitmap implements Parcelable {
|
||||||
|
|
||||||
|
private Bitmap bitmap;
|
||||||
|
|
||||||
|
public AGpxBitmap(@NonNull Bitmap bitmap) {
|
||||||
|
this.bitmap = bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AGpxBitmap(Parcel in) {
|
||||||
|
readFromParcel(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bitmap getBitmap() {
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<AGpxBitmap> CREATOR = new
|
||||||
|
Creator<AGpxBitmap>() {
|
||||||
|
public AGpxBitmap createFromParcel(Parcel in) {
|
||||||
|
return new AGpxBitmap(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AGpxBitmap[] newArray(int size) {
|
||||||
|
return new AGpxBitmap[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public void writeToParcel(Parcel out, int flags) {
|
||||||
|
out.writeParcelable(bitmap, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readFromParcel(Parcel in) {
|
||||||
|
bitmap = in.readParcelable(Bitmap.class.getClassLoader());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
package net.osmand.aidl.gpx;
|
||||||
|
|
||||||
|
parcelable CreateGpxBitmapParams;
|
101
OsmAnd/src/net/osmand/aidl/gpx/CreateGpxBitmapParams.java
Normal file
101
OsmAnd/src/net/osmand/aidl/gpx/CreateGpxBitmapParams.java
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
package net.osmand.aidl.gpx;
|
||||||
|
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class CreateGpxBitmapParams implements Parcelable {
|
||||||
|
|
||||||
|
private File gpxFile;
|
||||||
|
private Uri gpxUri;
|
||||||
|
private float density;
|
||||||
|
private int widthPixels;
|
||||||
|
private int heightPixels;
|
||||||
|
private int color; //ARGB color int
|
||||||
|
|
||||||
|
public CreateGpxBitmapParams(File gpxFile, float density, int widthPixels, int heightPixels, int color) {
|
||||||
|
this.gpxFile = gpxFile;
|
||||||
|
this.density = density;
|
||||||
|
this.widthPixels = widthPixels;
|
||||||
|
this.heightPixels = heightPixels;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CreateGpxBitmapParams(Uri gpxUri, float density, int widthPixels, int heightPixels, int color) {
|
||||||
|
this.gpxUri = gpxUri;
|
||||||
|
this.density = density;
|
||||||
|
this.widthPixels = widthPixels;
|
||||||
|
this.heightPixels = heightPixels;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CreateGpxBitmapParams(Parcel in) {
|
||||||
|
readFromParcel(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<CreateGpxBitmapParams> CREATOR = new
|
||||||
|
Creator<CreateGpxBitmapParams>() {
|
||||||
|
public CreateGpxBitmapParams createFromParcel(Parcel in) {
|
||||||
|
return new CreateGpxBitmapParams(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CreateGpxBitmapParams[] newArray(int size) {
|
||||||
|
return new CreateGpxBitmapParams[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public File getGpxFile() {
|
||||||
|
return gpxFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uri getGpxUri() {
|
||||||
|
return gpxUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWidthPixels() {
|
||||||
|
return widthPixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeightPixels() {
|
||||||
|
return heightPixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getDensity() {
|
||||||
|
return density;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeToParcel(Parcel out, int flags) {
|
||||||
|
if (gpxFile != null) {
|
||||||
|
out.writeString(gpxFile.getAbsolutePath());
|
||||||
|
} else {
|
||||||
|
out.writeString(null);
|
||||||
|
}
|
||||||
|
out.writeParcelable(gpxUri, flags);
|
||||||
|
out.writeFloat(density);
|
||||||
|
out.writeInt(widthPixels);
|
||||||
|
out.writeInt(heightPixels);
|
||||||
|
out.writeInt(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readFromParcel(Parcel in) {
|
||||||
|
String gpxAbsolutePath = in.readString();
|
||||||
|
if (gpxAbsolutePath != null) {
|
||||||
|
gpxFile = new File(gpxAbsolutePath);
|
||||||
|
}
|
||||||
|
gpxUri = in.readParcelable(Uri.class.getClassLoader());
|
||||||
|
density = in.readFloat();
|
||||||
|
widthPixels = in.readInt();
|
||||||
|
heightPixels = in.readInt();
|
||||||
|
color = in.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ import net.osmand.Location;
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
import net.osmand.data.LocationPoint;
|
import net.osmand.data.LocationPoint;
|
||||||
import net.osmand.data.PointDescription;
|
import net.osmand.data.PointDescription;
|
||||||
|
import net.osmand.data.QuadRect;
|
||||||
import net.osmand.data.RotatedTileBox;
|
import net.osmand.data.RotatedTileBox;
|
||||||
import net.osmand.plus.views.Renderable;
|
import net.osmand.plus.views.Renderable;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
@ -1247,6 +1248,57 @@ public class GPXUtilities {
|
||||||
}
|
}
|
||||||
return categories;
|
return categories;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public QuadRect getRect() {
|
||||||
|
double left = 0, right = 0;
|
||||||
|
double top = 0, bottom = 0;
|
||||||
|
for (Track track : tracks) {
|
||||||
|
for (TrkSegment segment : track.segments) {
|
||||||
|
for (WptPt p : segment.points) {
|
||||||
|
if (left == 0 && right == 0) {
|
||||||
|
left = p.getLongitude();
|
||||||
|
right = p.getLongitude();
|
||||||
|
top = p.getLatitude();
|
||||||
|
bottom = p.getLatitude();
|
||||||
|
} else {
|
||||||
|
left = Math.min(left, p.getLongitude());
|
||||||
|
right = Math.max(right, p.getLongitude());
|
||||||
|
top = Math.max(top, p.getLatitude());
|
||||||
|
bottom = Math.min(bottom, p.getLatitude());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (WptPt p : points) {
|
||||||
|
if (left == 0 && right == 0) {
|
||||||
|
left = p.getLongitude();
|
||||||
|
right = p.getLongitude();
|
||||||
|
top = p.getLatitude();
|
||||||
|
bottom = p.getLatitude();
|
||||||
|
} else {
|
||||||
|
left = Math.min(left, p.getLongitude());
|
||||||
|
right = Math.max(right, p.getLongitude());
|
||||||
|
top = Math.max(top, p.getLatitude());
|
||||||
|
bottom = Math.min(bottom, p.getLatitude());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (GPXUtilities.Route route : routes) {
|
||||||
|
for (WptPt p : route.points) {
|
||||||
|
if (left == 0 && right == 0) {
|
||||||
|
left = p.getLongitude();
|
||||||
|
right = p.getLongitude();
|
||||||
|
top = p.getLatitude();
|
||||||
|
bottom = p.getLatitude();
|
||||||
|
} else {
|
||||||
|
left = Math.min(left, p.getLongitude());
|
||||||
|
right = Math.max(right, p.getLongitude());
|
||||||
|
top = Math.max(top, p.getLatitude());
|
||||||
|
bottom = Math.min(bottom, p.getLatitude());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new QuadRect(left, top, right, bottom);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String asString(GPXFile file, OsmandApplication ctx) {
|
public static String asString(GPXFile file, OsmandApplication ctx) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package net.osmand.plus.activities;
|
package net.osmand.plus.activities;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.ColorStateList;
|
import android.content.res.ColorStateList;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
@ -9,9 +10,11 @@ import android.support.annotation.Nullable;
|
||||||
import android.support.design.widget.BottomNavigationView;
|
import android.support.design.widget.BottomNavigationView;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v7.app.ActionBar;
|
import android.support.v7.app.ActionBar;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
|
||||||
import net.osmand.AndroidUtils;
|
import net.osmand.AndroidUtils;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
|
@ -20,7 +23,6 @@ import net.osmand.data.QuadRect;
|
||||||
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
||||||
import net.osmand.plus.GPXUtilities;
|
import net.osmand.plus.GPXUtilities;
|
||||||
import net.osmand.plus.GPXUtilities.GPXFile;
|
import net.osmand.plus.GPXUtilities.GPXFile;
|
||||||
import net.osmand.plus.GPXUtilities.Track;
|
|
||||||
import net.osmand.plus.GPXUtilities.TrkSegment;
|
import net.osmand.plus.GPXUtilities.TrkSegment;
|
||||||
import net.osmand.plus.GPXUtilities.WptPt;
|
import net.osmand.plus.GPXUtilities.WptPt;
|
||||||
import net.osmand.plus.GpxSelectionHelper;
|
import net.osmand.plus.GpxSelectionHelper;
|
||||||
|
@ -35,7 +37,6 @@ import net.osmand.plus.mapmarkers.CoordinateInputDialogFragment;
|
||||||
import net.osmand.plus.measurementtool.NewGpxData;
|
import net.osmand.plus.measurementtool.NewGpxData;
|
||||||
import net.osmand.plus.myplaces.FavoritesActivity;
|
import net.osmand.plus.myplaces.FavoritesActivity;
|
||||||
import net.osmand.plus.myplaces.SplitSegmentDialogFragment;
|
import net.osmand.plus.myplaces.SplitSegmentDialogFragment;
|
||||||
import net.osmand.plus.myplaces.TrackActivityFragmentAdapter;
|
|
||||||
import net.osmand.plus.myplaces.TrackBitmapDrawer;
|
import net.osmand.plus.myplaces.TrackBitmapDrawer;
|
||||||
import net.osmand.plus.myplaces.TrackBitmapDrawer.TrackBitmapDrawerListener;
|
import net.osmand.plus.myplaces.TrackBitmapDrawer.TrackBitmapDrawerListener;
|
||||||
import net.osmand.plus.myplaces.TrackPointFragment;
|
import net.osmand.plus.myplaces.TrackPointFragment;
|
||||||
|
@ -156,56 +157,11 @@ public class TrackActivity extends TabActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public QuadRect getRect() {
|
public QuadRect getRect() {
|
||||||
double left = 0, right = 0;
|
|
||||||
double top = 0, bottom = 0;
|
|
||||||
if (getGpx() != null) {
|
if (getGpx() != null) {
|
||||||
for (Track track : getGpx().tracks) {
|
return getGpx().getRect();
|
||||||
for (TrkSegment segment : track.segments) {
|
} else {
|
||||||
for (WptPt p : segment.points) {
|
return new QuadRect(0, 0, 0, 0);
|
||||||
if (left == 0 && right == 0) {
|
|
||||||
left = p.getLongitude();
|
|
||||||
right = p.getLongitude();
|
|
||||||
top = p.getLatitude();
|
|
||||||
bottom = p.getLatitude();
|
|
||||||
} else {
|
|
||||||
left = Math.min(left, p.getLongitude());
|
|
||||||
right = Math.max(right, p.getLongitude());
|
|
||||||
top = Math.max(top, p.getLatitude());
|
|
||||||
bottom = Math.min(bottom, p.getLatitude());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (WptPt p : getGpx().getPoints()) {
|
|
||||||
if (left == 0 && right == 0) {
|
|
||||||
left = p.getLongitude();
|
|
||||||
right = p.getLongitude();
|
|
||||||
top = p.getLatitude();
|
|
||||||
bottom = p.getLatitude();
|
|
||||||
} else {
|
|
||||||
left = Math.min(left, p.getLongitude());
|
|
||||||
right = Math.max(right, p.getLongitude());
|
|
||||||
top = Math.max(top, p.getLatitude());
|
|
||||||
bottom = Math.min(bottom, p.getLatitude());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (GPXUtilities.Route route : getGpx().routes) {
|
|
||||||
for (WptPt p : route.points) {
|
|
||||||
if (left == 0 && right == 0) {
|
|
||||||
left = p.getLongitude();
|
|
||||||
right = p.getLongitude();
|
|
||||||
top = p.getLatitude();
|
|
||||||
bottom = p.getLatitude();
|
|
||||||
} else {
|
|
||||||
left = Math.min(left, p.getLongitude());
|
|
||||||
right = Math.max(right, p.getLongitude());
|
|
||||||
top = Math.max(top, p.getLatitude());
|
|
||||||
bottom = Math.min(bottom, p.getLatitude());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return new QuadRect(left, top, right, bottom);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setGpxDataItem(GpxDataItem gpxDataItem) {
|
protected void setGpxDataItem(GpxDataItem gpxDataItem) {
|
||||||
|
@ -383,8 +339,11 @@ public class TrackActivity extends TabActivity {
|
||||||
setGpx(gpxFile);
|
setGpx(gpxFile);
|
||||||
setGpxDataItem(file != null ? app.getGpxDatabase().getItem(file) : null);
|
setGpxDataItem(file != null ? app.getGpxDatabase().getItem(file) : null);
|
||||||
|
|
||||||
if (gpxFile != null) {
|
WindowManager mgr = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
|
||||||
trackBitmapDrawer = new TrackBitmapDrawer(this, gpxFile, getGpxDataItem(), getRect());
|
if (gpxFile != null && mgr != null) {
|
||||||
|
DisplayMetrics dm = new DisplayMetrics();
|
||||||
|
mgr.getDefaultDisplay().getMetrics(dm);
|
||||||
|
trackBitmapDrawer = new TrackBitmapDrawer(app, gpxFile, getGpxDataItem(), getRect(), dm.density, dm.widthPixels, AndroidUtils.dpToPx(app, 152f));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (WeakReference<Fragment> f : fragList) {
|
for (WeakReference<Fragment> f : fragList) {
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package net.osmand.plus.myplaces;
|
package net.osmand.plus.myplaces;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
|
@ -12,8 +10,6 @@ import android.support.annotation.ColorInt;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.util.DisplayMetrics;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
|
|
||||||
import net.osmand.AndroidUtils;
|
import net.osmand.AndroidUtils;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
|
@ -32,15 +28,16 @@ import net.osmand.plus.resources.ResourceManager;
|
||||||
import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
|
import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
|
||||||
import net.osmand.plus.views.Renderable;
|
import net.osmand.plus.views.Renderable;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class TrackBitmapDrawer {
|
public class TrackBitmapDrawer {
|
||||||
|
|
||||||
private OsmandApplication app;
|
private OsmandApplication app;
|
||||||
private WeakReference<Activity> activityRef;
|
|
||||||
private QuadRect rect;
|
private QuadRect rect;
|
||||||
|
private float density;
|
||||||
|
private int widthPixels;
|
||||||
|
private int heightPixels;
|
||||||
|
|
||||||
private boolean drawEnabled;
|
private boolean drawEnabled;
|
||||||
private RotatedTileBox rotatedTileBox;
|
private RotatedTileBox rotatedTileBox;
|
||||||
|
@ -69,11 +66,13 @@ public class TrackBitmapDrawer {
|
||||||
void drawTrackBitmap(Bitmap bitmap);
|
void drawTrackBitmap(Bitmap bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TrackBitmapDrawer(@NonNull Activity activity, @NonNull GPXFile gpxFile,
|
public TrackBitmapDrawer(@NonNull OsmandApplication app, @NonNull GPXFile gpxFile,
|
||||||
@Nullable GpxDataItem gpxDataItem, @NonNull QuadRect rect) {
|
@Nullable GpxDataItem gpxDataItem, @NonNull QuadRect rect, float density, int widthPixels, int heightPixels) {
|
||||||
this.activityRef = new WeakReference<>(activity);
|
this.density = density;
|
||||||
|
this.widthPixels = widthPixels;
|
||||||
|
this.heightPixels = heightPixels;
|
||||||
this.rect = rect;
|
this.rect = rect;
|
||||||
this.app = (OsmandApplication) activity.getApplication();
|
this.app = app;
|
||||||
this.gpxFile = gpxFile;
|
this.gpxFile = gpxFile;
|
||||||
this.gpxDataItem = gpxDataItem;
|
this.gpxDataItem = gpxDataItem;
|
||||||
|
|
||||||
|
@ -83,8 +82,8 @@ public class TrackBitmapDrawer {
|
||||||
paint.setStrokeWidth(AndroidUtils.dpToPx(app, 4f));
|
paint.setStrokeWidth(AndroidUtils.dpToPx(app, 4f));
|
||||||
defPointColor = ContextCompat.getColor(app, R.color.gpx_color_point);
|
defPointColor = ContextCompat.getColor(app, R.color.gpx_color_point);
|
||||||
paintIcon = new Paint();
|
paintIcon = new Paint();
|
||||||
pointSmall = BitmapFactory.decodeResource(activity.getResources(), R.drawable.map_white_shield_small);
|
pointSmall = BitmapFactory.decodeResource(app.getResources(), R.drawable.map_white_shield_small);
|
||||||
selectedPoint = BitmapFactory.decodeResource(activity.getResources(), R.drawable.map_default_location);
|
selectedPoint = BitmapFactory.decodeResource(app.getResources(), R.drawable.map_default_location);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addListener(TrackBitmapDrawerListener l) {
|
public void addListener(TrackBitmapDrawerListener l) {
|
||||||
|
@ -150,54 +149,48 @@ public class TrackBitmapDrawer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean initAndDraw() {
|
public boolean initAndDraw() {
|
||||||
Activity activity = activityRef.get();
|
if (rect != null && rect.left != 0 && rect.top != 0) {
|
||||||
if (activity != null) {
|
notifyDrawing();
|
||||||
WindowManager mgr = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
|
|
||||||
if (mgr != null && rect != null && rect.left != 0 && rect.top != 0) {
|
|
||||||
notifyDrawing();
|
|
||||||
|
|
||||||
double clat = rect.bottom / 2 + rect.top / 2;
|
double clat = rect.bottom / 2 + rect.top / 2;
|
||||||
double clon = rect.left / 2 + rect.right / 2;
|
double clon = rect.left / 2 + rect.right / 2;
|
||||||
DisplayMetrics dm = new DisplayMetrics();
|
RotatedTileBox.RotatedTileBoxBuilder boxBuilder = new RotatedTileBox.RotatedTileBoxBuilder()
|
||||||
mgr.getDefaultDisplay().getMetrics(dm);
|
.setLocation(clat, clon)
|
||||||
RotatedTileBox.RotatedTileBoxBuilder boxBuilder = new RotatedTileBox.RotatedTileBoxBuilder()
|
.setZoom(15)
|
||||||
.setLocation(clat, clon)
|
.density(density)
|
||||||
.setZoom(15)
|
.setPixelDimensions(widthPixels, heightPixels, 0.5f, 0.5f);
|
||||||
.density(dm.density)
|
|
||||||
.setPixelDimensions(dm.widthPixels, AndroidUtils.dpToPx(app, 152f), 0.5f, 0.5f);
|
|
||||||
|
|
||||||
rotatedTileBox = boxBuilder.build();
|
rotatedTileBox = boxBuilder.build();
|
||||||
while (rotatedTileBox.getZoom() < 17 && rotatedTileBox.containsLatLon(rect.top, rect.left) && rotatedTileBox.containsLatLon(rect.bottom, rect.right)) {
|
while (rotatedTileBox.getZoom() < 17 && rotatedTileBox.containsLatLon(rect.top, rect.left) && rotatedTileBox.containsLatLon(rect.bottom, rect.right)) {
|
||||||
rotatedTileBox.setZoom(rotatedTileBox.getZoom() + 1);
|
rotatedTileBox.setZoom(rotatedTileBox.getZoom() + 1);
|
||||||
}
|
}
|
||||||
while (rotatedTileBox.getZoom() >= 7 && (!rotatedTileBox.containsLatLon(rect.top, rect.left) || !rotatedTileBox.containsLatLon(rect.bottom, rect.right))) {
|
while (rotatedTileBox.getZoom() >= 7 && (!rotatedTileBox.containsLatLon(rect.top, rect.left) || !rotatedTileBox.containsLatLon(rect.bottom, rect.right))) {
|
||||||
rotatedTileBox.setZoom(rotatedTileBox.getZoom() - 1);
|
rotatedTileBox.setZoom(rotatedTileBox.getZoom() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
final DrawSettings drawSettings = new DrawSettings(!app.getSettings().isLightContent(), true);
|
final DrawSettings drawSettings = new DrawSettings(!app.getSettings().isLightContent(), true);
|
||||||
final ResourceManager resourceManager = app.getResourceManager();
|
final ResourceManager resourceManager = app.getResourceManager();
|
||||||
final MapRenderRepositories renderer = resourceManager.getRenderer();
|
final MapRenderRepositories renderer = resourceManager.getRenderer();
|
||||||
if (resourceManager.updateRenderedMapNeeded(rotatedTileBox, drawSettings)) {
|
if (resourceManager.updateRenderedMapNeeded(rotatedTileBox, drawSettings)) {
|
||||||
resourceManager.updateRendererMap(rotatedTileBox, new OnMapLoadedListener() {
|
resourceManager.updateRendererMap(rotatedTileBox, new OnMapLoadedListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onMapLoaded(boolean interrupted) {
|
public void onMapLoaded(boolean interrupted) {
|
||||||
app.runInUIThread(new Runnable() {
|
app.runInUIThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (isDrawEnabled()) {
|
if (isDrawEnabled()) {
|
||||||
mapBitmap = renderer.getBitmap();
|
mapBitmap = renderer.getBitmap();
|
||||||
if (mapBitmap != null) {
|
if (mapBitmap != null) {
|
||||||
notifyDrawn();
|
notifyDrawn();
|
||||||
refreshTrackBitmap();
|
refreshTrackBitmap();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
});
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue