Quick search for samples in progress
|
@ -105,6 +105,7 @@ repositories {
|
|||
dependencies {
|
||||
compile project(path: ':OsmAnd-java', configuration: 'android')
|
||||
compile 'com.android.support:appcompat-v7:23.3.0'
|
||||
compile 'com.android.support:design:23.3.0'
|
||||
compile fileTree(dir: "libs", include: ["*.jar"])
|
||||
compile "net.osmand:OsmAndCore_android:0.1-SNAPSHOT@aar"
|
||||
debugCompile "net.osmand:OsmAndCore_androidNativeRelease:0.1-SNAPSHOT@aar"
|
||||
|
|
BIN
OsmAndCore-sample/res/drawable-hdpi/ic_direction_arrow.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
OsmAndCore-sample/res/drawable-hdpi/map_search_dark.png
Executable file
After Width: | Height: | Size: 1.5 KiB |
BIN
OsmAndCore-sample/res/drawable-mdpi/ic_direction_arrow.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
OsmAndCore-sample/res/drawable-mdpi/map_search_dark.png
Executable file
After Width: | Height: | Size: 1.3 KiB |
BIN
OsmAndCore-sample/res/drawable-xhdpi/ic_direction_arrow.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
OsmAndCore-sample/res/drawable-xhdpi/map_search_dark.png
Executable file
After Width: | Height: | Size: 1.7 KiB |
BIN
OsmAndCore-sample/res/drawable-xxhdpi/ic_direction_arrow.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
OsmAndCore-sample/res/drawable-xxhdpi/map_search_dark.png
Executable file
After Width: | Height: | Size: 2.1 KiB |
|
@ -5,78 +5,6 @@
|
|||
android:orientation="vertical"
|
||||
tools:context="net.osmand.core.samples.android.sample1.MainActivity">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/colorPrimary"
|
||||
android:focusableInTouchMode="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/searchProgressBar"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:indeterminate="true"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/searchIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_action_search_dark"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/searchEditText"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:background="@null"
|
||||
android:gravity="center_vertical"
|
||||
android:hint="@string/search_hint"
|
||||
android:lines="1"
|
||||
android:textColor="@color/titleTextColor"
|
||||
tools:text="Search request"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/clearButton"
|
||||
style="@style/Widget.AppCompat.ActionButton"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:contentDescription="@string/shared_string_close"
|
||||
android:src="@drawable/ic_action_remove_dark"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/searchDetailsText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="56dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:gravity="center_vertical"
|
||||
android:lines="1"
|
||||
android:textColor="@color/titleTextColor"
|
||||
android:visibility="gone"
|
||||
tools:text="City • Street"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
@ -107,6 +35,23 @@
|
|||
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top|left"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginTop="10dp">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/search_button"
|
||||
android:layout_width="52dp"
|
||||
android:layout_height="52dp"
|
||||
android:background="@drawable/btn_circle"
|
||||
android:contentDescription="@string/shared_string_search"
|
||||
android:src="@drawable/map_search_dark"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
20
OsmAndCore-sample/res/layout/list_shadow_footer.xml
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout android:id="@+id/bottomShadowView"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/ctx_menu_info_view_bg"
|
||||
android:orientation="vertical"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<net.osmand.core.samples.android.sample1.customcontrols.OsmandImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scaleType="fitXY"
|
||||
app:osmandSrc="bg_shadow_list_bottom"/>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="16dp"/>
|
||||
|
||||
</LinearLayout>
|
20
OsmAndCore-sample/res/layout/list_shadow_header.xml
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout android:id="@+id/topShadowView"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/ctx_menu_info_view_bg"
|
||||
android:orientation="vertical"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="16dp"/>
|
||||
|
||||
<net.osmand.core.samples.android.sample1.customcontrols.OsmandImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scaleType="fitXY"
|
||||
app:osmandSrc="bg_shadow_list_top"/>
|
||||
|
||||
</LinearLayout>
|
101
OsmAndCore-sample/res/layout/search_dialog_fragment.xml
Normal file
|
@ -0,0 +1,101 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout 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">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:id="@+id/appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="@dimen/dashboard_map_toolbar"
|
||||
android:background="?attr/bg_color"
|
||||
android:minHeight="@dimen/dashboard_map_toolbar"
|
||||
android:theme="?attr/toolbar_theme"
|
||||
app:contentInsetLeft="54dp"
|
||||
app:contentInsetStart="54dp">
|
||||
|
||||
<include layout="@layout/search_text_layout"/>
|
||||
|
||||
</android.support.v7.widget.Toolbar>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/button_toolbar_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/ctx_menu_info_view_bg"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/ctx_menu_info_divider"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/buttonToolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:minHeight="48dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<net.osmand.core.samples.android.sample1.customcontrols.OsmandImageView
|
||||
android:id="@+id/buttonToolbarImage"
|
||||
android:layout_width="54dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
app:osmandSrc="ic_action_marker_dark"/>
|
||||
|
||||
<net.osmand.core.samples.android.sample1.customcontrols.OsmandTextView
|
||||
android:id="@+id/buttonToolbarTitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="@null"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:lines="1"
|
||||
android:singleLine="true"
|
||||
android:textColor="?attr/color_dialog_buttons"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
app:osmandText="shared_string_show_on_map"/>
|
||||
|
||||
<net.osmand.core.samples.android.sample1.customcontrols.OsmandImageButton
|
||||
android:id="@+id/filterButton"
|
||||
style="@style/Widget.AppCompat.ActionButton"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone"
|
||||
app:osmandSrc="ic_action_filter"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/search_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
15
OsmAndCore-sample/res/layout/search_dialog_list_layout.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ListView
|
||||
android:id="@android:id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:divider="@null"
|
||||
android:dividerHeight="0dp"
|
||||
android:drawSelectorOnTop="true"/>
|
||||
|
||||
</LinearLayout>
|
|
@ -3,58 +3,147 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?attr/listPreferredItemHeight"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="12dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingTop="8dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_gravity="top"
|
||||
android:scaleType="centerInside"
|
||||
android:visibility="visible"/>
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/searchListItemLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
android:minHeight="60dp"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingTop="8dp">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/toggle_item"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginRight="20dp"
|
||||
android:focusable="false"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginRight="8dp"
|
||||
android:scaleType="centerInside"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="0dp"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:paddingRight="16dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"
|
||||
tools:text="Amsterdam"/>
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/distance"
|
||||
android:layout_width="wrap_content"
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:paddingRight="16dp"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
tools:text="Amsterdam"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/compass_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/direction"
|
||||
android:layout_width="@dimen/directionIconSize"
|
||||
android:layout_height="@dimen/directionIconSize"
|
||||
android:layout_marginTop="1sp"
|
||||
android:layout_gravity="center_vertical"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/distance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="2dp"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_sub_text_size"
|
||||
tools:text="100500 km"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="right"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
tools:text="100 km"/>
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/type_name_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4.5dp"
|
||||
android:layout_marginRight="4dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/subtitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
tools:text="City"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/time_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginRight="@dimen/gpx_small_icon_margin"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:maxLines="1"
|
||||
android:scrollHorizontally="true"
|
||||
android:singleLine="true"
|
||||
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_sub_text_size"
|
||||
tools:text="10-12 am"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/subtitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
tools:text="City"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="@color/dashboard_divider_light"/>
|
||||
|
||||
</LinearLayout>
|
23
OsmAndCore-sample/res/layout/search_more_list_item.xml
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="48dp"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingTop="8dp">
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/color_dialog_buttons_light"
|
||||
android:textSize="@dimen/default_sub_text_size"
|
||||
tools:text="Amsterdam"/>
|
||||
|
||||
</LinearLayout>
|
37
OsmAndCore-sample/res/layout/search_text_layout.xml
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:focusableInTouchMode="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/searchEditText"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="@null"
|
||||
android:gravity="center_vertical"
|
||||
android:lines="1"
|
||||
android:singleLine="true"
|
||||
android:textColor="?attr/searchbar_text"
|
||||
android:textColorHint="?attr/searchbar_text_hint"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/searchProgressBar"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:indeterminate="true"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/clearButton"
|
||||
style="@style/Widget.AppCompat.ActionButton"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:contentDescription="@string/shared_string_close"
|
||||
android:src="@drawable/ic_action_remove_dark"/>
|
||||
|
||||
</LinearLayout>
|
43
OsmAndCore-sample/res/values/attrs.xml
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<declare-styleable name="AppTheme">
|
||||
<!-- list colors -->
|
||||
<attr name="dashboard_divider" format="reference" />
|
||||
<attr name="ctx_menu_info_divider" format="color"/>
|
||||
<attr name="searchbar_text" format="color"/>
|
||||
<attr name="searchbar_text_hint" format="color"/>
|
||||
<attr name="list_divider" format="color"/>
|
||||
<attr name="expandable_list_item_background" format="color"/>
|
||||
<attr name="expandable_list_background" format="color"/>
|
||||
<attr name="bg_color" format="reference" />
|
||||
<attr name="ctx_menu_info_view_bg" format="reference" />
|
||||
|
||||
<attr name="expandable_category_color" format="reference"/>
|
||||
<attr name="bottomToolBarColor" format="color" />
|
||||
<attr name="spinnerItemTextColor" format="reference" />
|
||||
<attr name="spinnerListBackground" format="color|reference" />
|
||||
<attr name="search_background" format="reference" />
|
||||
|
||||
<attr name="osmo_header_background" format="color"/>
|
||||
<attr name="dashboard_subheader_text_color" format="color"/>
|
||||
<attr name="dashboard_general_button_text_color" format="color"/>
|
||||
|
||||
<attr name="dialog_inactive_text_color" format="reference"/>
|
||||
<attr name="toolbar_theme" format="reference"/>
|
||||
|
||||
<attr name="divider_color" format="reference" />
|
||||
<attr name="contextMenuButtonColor" format="reference" />
|
||||
|
||||
<attr name="color_dialog_buttons" format="color"/>
|
||||
<attr name="secondary_icon_color" format="color"/>
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="OsmandTextView">
|
||||
<attr name="osmandText" format="string"/>
|
||||
</declare-styleable>
|
||||
<declare-styleable name="OsmandButton" parent="OsmandTextView"/>
|
||||
<declare-styleable name="OsmandImageButton" parent="OsmandTextView">
|
||||
<attr name="osmandSrc" format="string"/>
|
||||
</declare-styleable>
|
||||
<declare-styleable name="OsmandImageView" parent="OsmandImageButton"/>
|
||||
</resources>
|
|
@ -7,11 +7,235 @@
|
|||
<color name="dividerColor">#F0F0F0</color>
|
||||
<color name="windowBackgroundColor">#EAEAEA</color>
|
||||
<color name="itemBackgroundColor">#FFF</color>
|
||||
<color name="iconColor">#727272</color>
|
||||
<color name="dialogTitleBackgroundColor">#2f7af5</color>
|
||||
|
||||
<color name="listBackgroundColor">#EAEAEA</color>
|
||||
<color name="titleTextColor">#FFF</color>
|
||||
<color name="listTextColor">#000</color>
|
||||
|
||||
<color name="gpx_track_width_prop">#853fc5</color>
|
||||
<color name="xmas_blue">#3f51b5</color>
|
||||
|
||||
<color name="disabled_btn_text_color">#a0a0a0</color>
|
||||
<color name="discount_bar_bg">#357ef2</color>
|
||||
|
||||
<color name="searchbar_text_dark">#fff</color>
|
||||
<color name="searchbar_text_light">#212121</color>
|
||||
<color name="searchbar_text_hint_dark">#7a8c99</color>
|
||||
<color name="searchbar_text_hint_light">#727272</color>
|
||||
|
||||
<color name="searchbar_tab_inactive_dark">#5b6872</color>
|
||||
<color name="searchbar_tab_inactive_light">#727272</color>
|
||||
|
||||
<color name="markers_top_bar_background">#0f5257</color>
|
||||
<color name="markers_top_bar_2nd_background">#0c4347</color>
|
||||
<color name="marker_top_2nd_line_color">#859899</color>
|
||||
|
||||
<color name="marker_blue">#2196f3</color>
|
||||
<color name="marker_green">#73b825</color>
|
||||
<color name="marker_orange">#ff9800</color>
|
||||
<color name="marker_red">#e53935</color>
|
||||
<color name="marker_yellow">#FDD835</color>
|
||||
<color name="marker_teal">#26a69a</color>
|
||||
<color name="marker_purple">#ab47bc</color>
|
||||
|
||||
<color name="popup_bg_color">#EE666666</color>
|
||||
<color name="popup_separator_color">#BBBBBB</color>
|
||||
<color name="popup_text_color">#FFFFFF</color>
|
||||
|
||||
<color name="primary_text_light">#de000000</color>
|
||||
<color name="secondary_text_light">#8a000000</color>
|
||||
<color name="primary_text_dark">#ffffffff</color>
|
||||
<color name="secondary_text_dark">#b3ffffff</color>
|
||||
|
||||
<color name="audio_video_icon_color">#128a89</color>
|
||||
<color name="created_poi_icon_color">#4caf50</color>
|
||||
<color name="osm_bug_unresolved_icon_color">#d44a4a</color>
|
||||
<color name="osm_bug_resolved_icon_color">#4caf50</color>
|
||||
|
||||
<color name="osmand_orange">#ff8f00</color>
|
||||
<color name="app_mode_icon_color">#33B4E4</color>
|
||||
<color name="recording_color">#F44336</color>
|
||||
|
||||
<color name="dash_search_icon_light">#536DFE</color>
|
||||
<color name="dash_search_icon_dark">#7a8c99</color>
|
||||
|
||||
<color name="parking_outdated_color">#f41a34</color>
|
||||
<color name="osmo_header_dark">#2d383d</color>
|
||||
<color name="osmo_header_light">#b36d12</color>
|
||||
|
||||
<color name="dashboard_parking_light_selected">#007888</color>
|
||||
<color name="dashboard_parking_light_color">#009688</color>
|
||||
<color name="dashboard_parking_dark_color">#54778c</color>
|
||||
<color name="dashboard_parking_dark_selected">#446072</color>
|
||||
|
||||
<color name="plugin_details_install_header_bg_light">#dbdbdb</color>
|
||||
<color name="plugin_details_install_header_bg_dark">#2d3438</color>
|
||||
|
||||
<color name="list_divider_dark">#1f2326</color>
|
||||
<color name="list_divider_light">@color/color_white</color>
|
||||
<color name="list_sub_menu_background_dark">#475259</color>
|
||||
<!-- <color name="list_item_light">@color/color_white</color>
|
||||
<color name="list_item_background_dark">#333b40</color> -->
|
||||
<color name="list_item_light">#00000000</color>
|
||||
<color name="list_item_dark">#00000000</color>
|
||||
<color name="list_item_light_pressed">#8cd0d0d0</color>
|
||||
<color name="list_item_dark_pressed">#be39464d</color>
|
||||
<color name="bg_color_light">#fff</color>
|
||||
<color name="bg_color_dark">#333b40</color>
|
||||
|
||||
<color name="fab_color">#ff8f00</color>
|
||||
<color name="fab_color_pressed">#e58200</color>
|
||||
|
||||
<color name="map_widget_icon_color">#ff8f00</color>
|
||||
<color name="map_widget_stroke">#4C000000</color>
|
||||
<color name="map_widget_light">#fff</color>
|
||||
<color name="map_widget_dark">#a0000000</color>
|
||||
<color name="map_widget_dark_stroke">#80ffffff</color>
|
||||
<color name="map_widget_dark_pressed">#80aaaaaa</color>
|
||||
<color name="map_widget_light_trans">#80ffffff</color>
|
||||
<color name="map_widget_light_pressed">#e5e5e5</color>
|
||||
<color name="map_widget_blue">#536dfe</color>
|
||||
<color name="map_widget_blue_pressed">#485dd9</color>
|
||||
|
||||
|
||||
<color name="actionbar_dark_color">#39464d</color>
|
||||
<color name="tool_bar_color_dark">#CC080B0D</color>
|
||||
<color name="actionbar_light_color">#ff8f00</color>
|
||||
<color name="tool_bar_color_light">#b4ff8f00</color>
|
||||
|
||||
<color name="download_pressed_light">#8cff8f00</color>
|
||||
<color name="download_pressed_dark">#be39464d</color>
|
||||
|
||||
<color name="search_background_dark">#292f33</color>
|
||||
|
||||
<color name="icon_color">#727272</color>
|
||||
<color name="icon_color_light">#ccc</color>
|
||||
|
||||
<color name="on_map_icon_color">#505050</color>
|
||||
|
||||
<color name="ctx_menu_info_view_bg_light">#eaeaea</color>
|
||||
<color name="ctx_menu_info_view_bg_dark">#292f33</color>
|
||||
<color name="ctx_menu_info_text_light">#212121</color>
|
||||
<color name="ctx_menu_info_text_dark">#b4c3cc</color>
|
||||
<color name="ctx_menu_info_divider_light">#d9d9d9</color>
|
||||
<color name="ctx_menu_info_divider_dark">#333b40</color>
|
||||
|
||||
<color name="dashboard_gpx_on_map">#448AFF</color>
|
||||
<color name="dashboard_background">#eaeaea</color>
|
||||
<color name="dashboard_divider_light">#F0F0F0</color>
|
||||
<color name="dashboard_divider_dark">#3d474c</color>
|
||||
<color name="dashboard_black">#212121</color>
|
||||
<color name="dashboard_blue">#536DFE</color>
|
||||
<color name="dashboard_subheader_text_dark">#b4c3cc</color>
|
||||
<color name="dashboard_subheader_text_light">#727272</color>
|
||||
<color name="dashboard_general_button_text_dark">#ff8f00</color>
|
||||
<color name="dashboard_general_button_text_light">#536DFE</color>
|
||||
|
||||
|
||||
<color name="color_transparent">#0000</color>
|
||||
<color name="widgettext_night">#ffC8C8C8</color>
|
||||
<!-- widgettext_shadow_night is the same as widget background color for non-transparent night skin (from box_night_free_simple.9.png) -->
|
||||
<color name="widgettext_shadow_night">#dc262626</color>
|
||||
|
||||
<!-- style colors -->
|
||||
<color name="group_background">#A5A5A5</color>
|
||||
<color name="background_tab_pressed">#1AFFFFFF</color>
|
||||
<!-- <color name="activity_background">#666666</color> -->
|
||||
|
||||
<!-- Distance to object suitable for all themes -->
|
||||
<color name="color_distance">#FD9822</color>
|
||||
|
||||
<color name="color_myloc_distance">#0080FF</color>
|
||||
<color name="wpt_distance_color">#dd6CB336</color>
|
||||
<!-- Old dialogs colors -->
|
||||
<color name="color_white">#FFF</color>
|
||||
<color name="color_black">#000</color>
|
||||
|
||||
<color name="row_selection_color">#CC33BBE0</color>
|
||||
|
||||
<!-- GPX analysis colors -->
|
||||
<color name="gpx_color_point">#cd2c33</color>
|
||||
<color name="gpx_speed">#c79c00</color>
|
||||
<color name="gpx_altitude_desc">#32CD32</color>
|
||||
<color name="gpx_altitude_asc">#EE3232</color>
|
||||
<color name="gpx_distance_color">#ffa500</color>
|
||||
<color name="gpx_time_span_color">#0080FF</color>
|
||||
|
||||
<color name="color_favorite">#eecc22</color>
|
||||
|
||||
<!-- Themed color list items -->
|
||||
<!-- invalid -red, localindex not supported, -->
|
||||
<color name="color_invalid">#EE3232</color>
|
||||
<!-- warning -red, localindex is corrupted, poi closed, osm_delete -->
|
||||
<color name="color_warning">#EE3232</color>
|
||||
<!-- normal state, localindex unknown, poi unknown, index_unknown -->
|
||||
<color name="color_unknown">#C8C8C8</color>
|
||||
<!-- good state, localindex loaded, poi_open, osm_create, index_ok -->
|
||||
<color name="color_ok">#32CD32</color>
|
||||
<!-- intermediate state - poi is going to be closed -->
|
||||
<color name="color_intermediate">#FFDD00</color>
|
||||
<!-- update good state, osm_modify, index_update -->
|
||||
<color name="color_update">#0080FF</color>
|
||||
|
||||
<!-- Map colors, layers, special purpose consistency colors -->
|
||||
<color name="pos_heading">#320000FF</color>
|
||||
<!-- color name="pos_heading_night">#880000FF</color -->
|
||||
<color name="pos_heading_night">#88536dfe</color>
|
||||
<color name="pos_area">#280000FF</color>
|
||||
<!-- color name="pos_area_night">#660000FF</color -->
|
||||
<color name="pos_area_night">#66536dfe</color>
|
||||
<color name="pos_around">#707CDC</color> <!-- family blue similar to above -->
|
||||
|
||||
<color name="gpx_track">#B4B319FF</color>
|
||||
<color name="gpx_track_fluorescent">#B400FFFF</color>
|
||||
|
||||
<color name="nav_track">#CCaa0088</color>
|
||||
<color name="nav_track_fluorescent">#CC00ddff</color>
|
||||
<color name="transport_route_line">#CC2f7af5</color>
|
||||
|
||||
|
||||
<color name="nav_arrow_distant">#C0C0C0</color>
|
||||
<color name="nav_arrow">#FADE23</color>
|
||||
<color name="nav_arrow_imminent">#2EFF00</color>
|
||||
|
||||
<color name="nav_point">#FA5050</color>
|
||||
<color name="poi_background">#A0FF8000</color>
|
||||
|
||||
<color name="transport_stop">#960000FF</color>
|
||||
<color name="transport_int">#9632C832</color>
|
||||
<color name="transport_end">#96FF0000</color>
|
||||
|
||||
<color name="osmbug_opened">#C8FF0000</color> <!-- standard RED -->
|
||||
<color name="osmbug_closed">#C800FF00</color> <!-- standard GREEN -->
|
||||
<color name="osmbug_not_submitted">#C8FFFF00</color> <!-- standard YELLOW -->
|
||||
|
||||
|
||||
<color name="shadow_color">#33888888</color>
|
||||
|
||||
<color name="sherpafy_selection">#ff33b5e5</color>
|
||||
<color name="sherpafy_add_text">#b9b9b9</color>
|
||||
|
||||
<color name="spinner_list_background_light">#eeeeee</color>
|
||||
<color name="spinner_list_background_dark">#303030</color>
|
||||
|
||||
<color name="inactive_item_orange">#ffc87f</color>
|
||||
<color name="osmand_orange_dark">#e68200</color>
|
||||
<color name="divider_color">#ccc</color>
|
||||
|
||||
<color name="color_dialog_buttons_light">#2f7af5</color>
|
||||
<color name="color_dialog_buttons_dark">#ff8800</color>
|
||||
|
||||
<color name="dialog_inactive_text_color_dark">#78909c</color>
|
||||
|
||||
<!-- DownloadedRegionsLayer -->
|
||||
<color name="region_uptodate">#5532C832</color>
|
||||
<color name="region_backuped">#55FF8F00</color>
|
||||
<color name="region_selected">#55FFFF00</color>
|
||||
<color name="region_downloading">#44FF61FF</color>
|
||||
|
||||
<!-- Dialog Live Updates Settings -->
|
||||
<color name="white_50_transparent">#8FFF</color>
|
||||
<color name="white_80_transparent">#CFFF</color>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -2,5 +2,4 @@
|
|||
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
<dimen name="list_content_padding">16dp</dimen>
|
||||
</resources>
|
||||
|
|
137
OsmAndCore-sample/res/values/sizes.xml
Normal file
|
@ -0,0 +1,137 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<dimen name="dialog_button_height">36dp</dimen>
|
||||
<dimen name="undo_bottom_offset">15dp</dimen>
|
||||
<dimen name="touch_slop">32dp</dimen>
|
||||
|
||||
<dimen name="list_item_height">50dp</dimen>
|
||||
<dimen name="list_header_height">40dp</dimen>
|
||||
<dimen name="dashboard_map_top_padding">240dp</dimen>
|
||||
<dimen name="dashboard_land_width">360dp</dimen>
|
||||
<dimen name="dashboard_map_toolbar">56dp</dimen>
|
||||
<dimen name="dash_parking_height">78dp</dimen>
|
||||
|
||||
<dimen name="subHeaderPadding">2dp</dimen>
|
||||
<dimen name="subHeaderMarginLeft">15dp</dimen>
|
||||
<dimen name="showAllButtonMarginRight">14dp</dimen>
|
||||
<dimen name="showAllButtonHeight">36dp</dimen>
|
||||
<dimen name="dashFavIconSize">28dp</dimen>
|
||||
<dimen name="dashFavIconMargin">12dp</dimen>
|
||||
<dimen name="dashFavDirectionSize">10dp</dimen>
|
||||
<dimen name="directionIconSize">14dp</dimen>
|
||||
|
||||
<dimen name="dashNoteIconSize">28dp</dimen>
|
||||
<dimen name="dashPluginPadding">4dp</dimen>
|
||||
<dimen name="dashPluginMargin">8dp</dimen>
|
||||
<dimen name="dashSearchBtnHeight">90dp</dimen>
|
||||
<dimen name="dashSearchPaddingTop">17dp</dimen>
|
||||
<dimen name="dashSearchPaddingBot">11dp</dimen>
|
||||
<dimen name="dashPadding">6dp</dimen>
|
||||
<dimen name="dashCardMargin">4dp</dimen>
|
||||
<dimen name="abp__shadow_height">4dp</dimen>
|
||||
<dimen name="dashFABMargin">0dp</dimen>
|
||||
|
||||
<dimen name="list_content_padding">16dp</dimen>
|
||||
<dimen name="list_header_padding">8dp</dimen>
|
||||
|
||||
<dimen name="list_header_top_margin">16dp</dimen>
|
||||
<dimen name="list_header_settings_top_margin">10dp</dimen>
|
||||
<dimen name="list_header_text_left_margin">12dp</dimen>
|
||||
<dimen name="list_header_bottom_margin">8dp</dimen>
|
||||
|
||||
<dimen name="favorites_icon_right_margin">24dp</dimen>
|
||||
<dimen name="local_index_check_right_margin">10dp</dimen>
|
||||
<dimen name="favorites_icon_top_margin">13dp</dimen>
|
||||
<dimen name="dialog_elements_vertical_margin">16dp</dimen>
|
||||
<dimen name="dialog_content_margin">24dp</dimen>
|
||||
<dimen name="dialog_content_bottom_margin">16dp</dimen>
|
||||
<dimen name="local_size_height">34dp</dimen>
|
||||
<dimen name="standard_icon_size">24dp</dimen>
|
||||
<dimen name="gpx_small_icon_margin">3dp</dimen>
|
||||
<dimen name="gpx_small_text_margin">14dp</dimen>
|
||||
<dimen name="gpx_text_top_margin">6dp</dimen>
|
||||
|
||||
|
||||
<dimen name="dashboard_parking_left_margin">16dp</dimen>
|
||||
<dimen name="dashboard_parking_icon_size">48dp</dimen>
|
||||
<!-- map buttons -->
|
||||
<dimen name="map_trans_seek_size">80dp</dimen>
|
||||
<dimen name="map_route_buttons_width">60dp</dimen>
|
||||
<dimen name="map_route_buttons_height">54dp</dimen>
|
||||
<dimen name="map_route_buttons_height_land">48dp</dimen>
|
||||
<dimen name="map_mode_button_width">56dp</dimen>
|
||||
|
||||
<dimen name="map_address_height">40dp</dimen>
|
||||
<dimen name="map_button_size">52dp</dimen>
|
||||
<dimen name="map_small_button_size">44dp</dimen>
|
||||
<dimen name="map_small_button_margin">5dp</dimen>
|
||||
|
||||
<dimen name="map_ruler_width">120dp</dimen>
|
||||
<dimen name="map_ruler_bottom_margin">9dp</dimen>
|
||||
<dimen name="map_alarm_size">78dp</dimen>
|
||||
|
||||
|
||||
<dimen name="map_alarm_bottom_margin">87dp</dimen>
|
||||
<dimen name="map_alarm_bottom_margin_land">57dp</dimen>
|
||||
<dimen name="map_button_shadow_height">85dp</dimen>
|
||||
<dimen name="map_button_shadow_width">56dp</dimen>
|
||||
<dimen name="map_button_shadow_margin">4dp</dimen>
|
||||
<dimen name="map_widget_icon">24dp</dimen>
|
||||
<dimen name="map_widget_height">32dp</dimen>
|
||||
<dimen name="map_widget_image">80dp</dimen>
|
||||
<dimen name="map_button_spacing">11dp</dimen>
|
||||
<dimen name="map_button_spacing_land">6dp</dimen>
|
||||
<dimen name="map_button_margin">6dp</dimen>
|
||||
<dimen name="map_routing_progress_width">100dp</dimen>
|
||||
|
||||
|
||||
<dimen name="map_button_inset_shadow">2dp</dimen>
|
||||
<dimen name="map_button_inset">2dp</dimen>
|
||||
<dimen name="map_button_rect_rad">3dp</dimen>
|
||||
<dimen name="map_button_stroke">1dp</dimen>
|
||||
<dimen name="map_button_stroke_dark">1dp</dimen>
|
||||
<dimen name="map_route_planning_land_width">320dp</dimen>
|
||||
<dimen name="map_route_planning_land_width_minus_shadow">306dp</dimen>
|
||||
<dimen name="map_route_planning_max_height">330dp</dimen>
|
||||
<dimen name="map_minwidth_widget">100dp</dimen>
|
||||
|
||||
|
||||
|
||||
<dimen name="map_widget_text_size">23sp</dimen>
|
||||
<dimen name="map_widget_text_size_small">15sp</dimen>
|
||||
<dimen name="map_button_text_size">18sp</dimen>
|
||||
<dimen name="map_alarm_text_size">25sp</dimen>
|
||||
<dimen name="map_widget_text_bottom_margin">1sp</dimen>
|
||||
<dimen name="map_widget_text_small_bottom_margin">3sp</dimen>
|
||||
<dimen name="map_widget_icon_margin">2dp</dimen>
|
||||
|
||||
<dimen name="dash_margin">2dp</dimen>
|
||||
<dimen name="dash_margin_h">6dp</dimen>
|
||||
|
||||
|
||||
<!-- ContextMenu -->
|
||||
<dimen name="context_menu_top_shadow_h">20dp</dimen>
|
||||
<dimen name="context_menu_icon_top_padding">17dp</dimen>
|
||||
<dimen name="context_menu_first_line_top_margin">14dp</dimen>
|
||||
<dimen name="context_menu_first_line_bottom_margin">16dp</dimen>
|
||||
<dimen name="context_menu_second_line_top_margin">4dp</dimen>
|
||||
<dimen name="context_menu_top_right_button_min_width">76dp</dimen>
|
||||
<dimen name="context_menu_button_padding_x">10dp</dimen>
|
||||
<dimen name="context_menu_buttons_top_margin">-16dp</dimen>
|
||||
<dimen name="context_menu_buttons_padding_bottom">4dp</dimen>
|
||||
<dimen name="context_menu_progress_min_height">54dp</dimen>
|
||||
<dimen name="context_menu_progress_cancel_button_size">44dp</dimen>
|
||||
<dimen name="context_menu_action_buttons_h">54dp</dimen>
|
||||
|
||||
<dimen name="fab_size_with_shadow">62dp</dimen>
|
||||
<dimen name="fab_margin_right">12dp</dimen>
|
||||
|
||||
<!-- TextSizes -->
|
||||
<dimen name="default_list_text_size_large">19sp</dimen>
|
||||
<dimen name="default_list_text_size">16sp</dimen>
|
||||
<dimen name="default_desc_text_size">14sp</dimen>
|
||||
<dimen name="default_sub_text_size">12sp</dimen>
|
||||
<dimen name="welcome_header_text_size">23sp</dimen>
|
||||
|
||||
<dimen name="dialog_header_text_size">20sp</dimen>
|
||||
</resources>
|
|
@ -1,5 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="shared_string_search">Search</string>
|
||||
<string name="yard">yd</string>
|
||||
<string name="foot">ft</string>
|
||||
<string name="mile">mi</string>
|
||||
<string name="km">km</string>
|
||||
<string name="m">m</string>
|
||||
<string name="nm">nmi</string>
|
||||
<string name="min_mile">min/m</string>
|
||||
<string name="min_km">min/km</string>
|
||||
<string name="nm_h">nmi/h</string>
|
||||
<string name="m_s">m/s</string>
|
||||
<string name="km_h">km/h</string>
|
||||
<string name="mile_per_hour">mph</string>
|
||||
<string name="si_kmh">Kilometers per hour</string>
|
||||
<string name="si_mph">Miles per hour</string>
|
||||
<string name="si_m_s">Meters per second</string>
|
||||
<string name="si_min_km">Minutes per kilometer</string>
|
||||
<string name="si_min_m">Minutes per mile</string>
|
||||
<string name="si_nm_h">Nautical miles per hour (knot)</string>
|
||||
<string name="si_mi_feet">Miles/feet</string>
|
||||
<string name="si_mi_yard">Miles/yards</string>
|
||||
<string name="si_km_m">Kilometers/meters</string>
|
||||
<string name="si_nm">Nautical miles</string>
|
||||
<string name="si_mi_meters">Miles/meters</string>
|
||||
<string name="shared_string_hour_short">h</string>
|
||||
<string name="shared_string_minute_short">min</string>
|
||||
<string name="install_maps_title">Install maps</string>
|
||||
<string name="install_maps_desc">You do not have maps in the OsmAnd application. Please download map(s) first and restart the Sample.\n\nDo not forget to set OsmAnd General settings > Data storage folder to Shared memory.</string>
|
||||
<string name="shared_string_cancel">Cancel</string>
|
||||
|
|
|
@ -2,10 +2,61 @@
|
|||
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
|
||||
<item name="android:windowBackground">@color/windowBackgroundColor</item>
|
||||
<item name="android:colorBackground">@color/windowBackgroundColor</item>
|
||||
|
||||
<item name="toolbar_theme">@style/AppTheme.Toolbar</item>
|
||||
<item name="bg_color">@color/bg_color_light</item>
|
||||
<item name="ctx_menu_info_divider">@color/ctx_menu_info_divider_light</item>
|
||||
<item name="searchbar_text">@color/searchbar_text_light</item>
|
||||
<item name="searchbar_text_hint">@color/searchbar_text_hint_light</item>
|
||||
<item name="list_divider">@color/list_divider_dark</item>
|
||||
<item name="expandable_category_color">?android:attr/colorBackground</item>
|
||||
<item name="bottomToolBarColor">@color/tool_bar_color_light</item>
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
<item name="actionModeBackground">@color/actionbar_light_color</item>
|
||||
<item name="dashboard_divider">@color/dashboard_divider_light</item>
|
||||
<item name="divider_color">@color/divider_color</item>
|
||||
<item name="ctx_menu_info_view_bg">@color/ctx_menu_info_view_bg_light</item>
|
||||
<item name="search_background">@color/search_background_dark</item>
|
||||
<item name="actionMenuTextColor">@color/color_white</item>
|
||||
<item name="expandable_list_background">@color/list_item_light</item>
|
||||
<item name="osmo_header_background">@color/osmo_header_light</item>
|
||||
<item name="dashboard_subheader_text_color">@color/dashboard_subheader_text_light</item>
|
||||
<item name="dashboard_general_button_text_color">
|
||||
@color/dashboard_general_button_text_light
|
||||
</item>
|
||||
<item name="android:textColorPrimary">@color/color_black</item>
|
||||
<item name="spinnerItemTextColor">@color/color_black</item>
|
||||
<item name="spinnerListBackground">@color/spinner_list_background_light</item>
|
||||
<item name="colorButtonNormal">@color/color_white</item>
|
||||
|
||||
<item name="android:actionModeBackground">@color/actionbar_light_color</item>
|
||||
<item name="android:actionMenuTextColor">@color/color_white</item>
|
||||
|
||||
<item name="dialog_inactive_text_color">@color/icon_color_light</item>
|
||||
<item name="secondary_icon_color">@color/icon_color_light</item>
|
||||
<item name="android:textColorSecondary">@color/icon_color</item>
|
||||
<item name="contextMenuButtonColor">@color/map_widget_blue</item>
|
||||
|
||||
<item name="color_dialog_buttons">@color/color_dialog_buttons_light</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.Toolbar">
|
||||
<item name="android:textColorPrimary">@color/color_white</item>
|
||||
<item name="android:textColorSecondary">@color/color_white</item>
|
||||
</style>
|
||||
|
||||
<style name="Dialog_Fullscreen" parent="android:Theme">
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
<item name="android:windowBackground">@color/color_transparent</item>
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
<item name="android:backgroundDimEnabled">false</item>
|
||||
</style>
|
||||
|
||||
<style name="OsmandListView" parent="@android:style/Widget.ListView">
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
|
215
OsmAndCore-sample/src/net/osmand/AndroidUtils.java
Normal file
|
@ -0,0 +1,215 @@
|
|||
package net.osmand;
|
||||
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.PointF;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateFormat;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.view.ViewParent;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.R;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static android.util.TypedValue.COMPLEX_UNIT_DIP;
|
||||
|
||||
public class AndroidUtils {
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @return true if Hardware keyboard is available
|
||||
*/
|
||||
public static boolean isHardwareKeyboardAvailable(Context context) {
|
||||
return context.getResources().getConfiguration().keyboard != Configuration.KEYBOARD_NOKEYS;
|
||||
}
|
||||
|
||||
public static void softKeyboardDelayed(final View view) {
|
||||
view.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!isHardwareKeyboardAvailable(view.getContext())) {
|
||||
InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (imm != null) {
|
||||
imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void hideSoftKeyboard(final Activity activity, final View input) {
|
||||
InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
|
||||
if (inputMethodManager != null) {
|
||||
if (input != null) {
|
||||
IBinder windowToken = input.getWindowToken();
|
||||
if (windowToken != null) {
|
||||
inputMethodManager.hideSoftInputFromWindow(windowToken, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static String formatDate(Context ctx, long time) {
|
||||
return DateFormat.getDateFormat(ctx).format(new Date(time));
|
||||
}
|
||||
|
||||
public static String formatDateTime(Context ctx, long time) {
|
||||
Date d = new Date(time);
|
||||
return DateFormat.getDateFormat(ctx).format(d) +
|
||||
" " + DateFormat.getTimeFormat(ctx).format(d);
|
||||
}
|
||||
|
||||
public static String formatTime(Context ctx, long time) {
|
||||
return DateFormat.getTimeFormat(ctx).format(new Date(time));
|
||||
}
|
||||
|
||||
public static View findParentViewById(View view, int id) {
|
||||
ViewParent viewParent = view.getParent();
|
||||
|
||||
while (viewParent != null && viewParent instanceof View) {
|
||||
View parentView = (View)viewParent;
|
||||
if (parentView.getId() == id)
|
||||
return parentView;
|
||||
|
||||
viewParent = parentView.getParent();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void setBackground(Context ctx, View view, boolean night, int lightResId, int darkResId) {
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
|
||||
view.setBackground(ctx.getResources().getDrawable(night ? darkResId : lightResId,
|
||||
ctx.getTheme()));
|
||||
} else {
|
||||
view.setBackgroundDrawable(ctx.getResources().getDrawable(night ? darkResId : lightResId));
|
||||
}
|
||||
}
|
||||
|
||||
public static void setBackgroundColor(Context ctx, View view, boolean night, int lightResId, int darkResId) {
|
||||
view.setBackgroundColor(ctx.getResources().getColor(night ? darkResId : lightResId));
|
||||
}
|
||||
|
||||
public static void setListItemBackground(Context ctx, View view, boolean night) {
|
||||
setBackgroundColor(ctx, view, night, R.color.bg_color_light, R.color.bg_color_dark);
|
||||
}
|
||||
|
||||
public static void setListBackground(Context ctx, View view, boolean night) {
|
||||
setBackgroundColor(ctx, view, night, R.color.ctx_menu_info_view_bg_light, R.color.ctx_menu_info_view_bg_dark);
|
||||
}
|
||||
|
||||
public static void setTextPrimaryColor(Context ctx, TextView textView, boolean night) {
|
||||
textView.setTextColor(night ?
|
||||
ctx.getResources().getColor(R.color.primary_text_dark)
|
||||
: ctx.getResources().getColor(R.color.primary_text_light));
|
||||
}
|
||||
|
||||
public static void setTextSecondaryColor(Context ctx, TextView textView, boolean night) {
|
||||
textView.setTextColor(night ?
|
||||
ctx.getResources().getColor(R.color.secondary_text_dark)
|
||||
: ctx.getResources().getColor(R.color.secondary_text_light));
|
||||
}
|
||||
|
||||
public static void setHintTextSecondaryColor(Context ctx, TextView textView, boolean night) {
|
||||
textView.setHintTextColor(night ?
|
||||
ctx.getResources().getColor(R.color.secondary_text_dark)
|
||||
: ctx.getResources().getColor(R.color.secondary_text_light));
|
||||
}
|
||||
|
||||
public static int dpToPx(Context ctx, float dp) {
|
||||
Resources r = ctx.getResources();
|
||||
return (int) TypedValue.applyDimension(
|
||||
COMPLEX_UNIT_DIP,
|
||||
dp,
|
||||
r.getDisplayMetrics()
|
||||
);
|
||||
}
|
||||
|
||||
public static int getStatusBarHeight(Context ctx) {
|
||||
int result = 0;
|
||||
int resourceId = ctx.getResources().getIdentifier("status_bar_height", "dimen", "android");
|
||||
if (resourceId > 0) {
|
||||
result = ctx.getResources().getDimensionPixelSize(resourceId);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int getScreenHeight(Activity activity) {
|
||||
DisplayMetrics dm = new DisplayMetrics();
|
||||
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
|
||||
return dm.heightPixels;
|
||||
}
|
||||
|
||||
public static boolean isValidEmail(CharSequence target) {
|
||||
return !TextUtils.isEmpty(target) && android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
|
||||
}
|
||||
|
||||
public static String getFileAsString(File file) {
|
||||
try {
|
||||
FileInputStream fin = new FileInputStream(file);
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(fin, "UTF-8"));
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append("\n");
|
||||
}
|
||||
sb.append(line);
|
||||
}
|
||||
reader.close();
|
||||
fin.close();
|
||||
return sb.toString();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static PointF centroidForPoly(PointF[] points) {
|
||||
float centroidX = 0, centroidY = 0;
|
||||
|
||||
for (PointF point : points) {
|
||||
centroidX += point.x / points.length;
|
||||
centroidY += point.y / points.length;
|
||||
}
|
||||
return new PointF(centroidX, centroidY);
|
||||
}
|
||||
|
||||
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
|
||||
List<Map.Entry<K, V>> list = new LinkedList<>(map.entrySet());
|
||||
Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
|
||||
public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
|
||||
return (o1.getValue()).compareTo(o2.getValue());
|
||||
}
|
||||
});
|
||||
|
||||
Map<K, V> result = new LinkedHashMap<>();
|
||||
for (Map.Entry<K, V> entry : list) {
|
||||
result.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -1,16 +1,28 @@
|
|||
package net.osmand.core.samples.android.sample1;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.ColorRes;
|
||||
import android.support.annotation.DrawableRes;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.graphics.drawable.DrawableCompat;
|
||||
|
||||
import net.osmand.core.android.CoreResourcesFromAndroidAssets;
|
||||
|
||||
import gnu.trove.map.hash.TLongObjectHashMap;
|
||||
|
||||
public class IconsCache {
|
||||
|
||||
private TLongObjectHashMap<Drawable> drawable = new TLongObjectHashMap<>();
|
||||
private TLongObjectHashMap<Drawable> osmandDrawable = new TLongObjectHashMap<>();
|
||||
private SampleApplication app;
|
||||
private CoreResourcesFromAndroidAssets assets;
|
||||
private float displayDensityFactor;
|
||||
|
||||
public IconsCache(CoreResourcesFromAndroidAssets assets) {
|
||||
public IconsCache(CoreResourcesFromAndroidAssets assets, SampleApplication app) {
|
||||
this.assets = assets;
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
public float getDisplayDensityFactor() {
|
||||
|
@ -24,4 +36,154 @@ public class IconsCache {
|
|||
public Drawable getMapIcon(String name) {
|
||||
return assets.getIcon("map/icons/" + name + ".png", displayDensityFactor);
|
||||
}
|
||||
|
||||
private Drawable getDrawable(@DrawableRes int resId, @ColorRes int clrId) {
|
||||
long hash = ((long)resId << 31L) + clrId;
|
||||
Drawable d = drawable.get(hash);
|
||||
if (d == null) {
|
||||
d = ContextCompat.getDrawable(app, resId);
|
||||
d = DrawableCompat.wrap(d);
|
||||
d.mutate();
|
||||
if (clrId != 0) {
|
||||
DrawableCompat.setTint(d, ContextCompat.getColor(app, clrId));
|
||||
}
|
||||
drawable.put(hash, d);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
private Drawable getPaintedDrawable(@DrawableRes int resId, @ColorInt int color){
|
||||
long hash = ((long)resId << 31L) + color;
|
||||
Drawable d = drawable.get(hash);
|
||||
if(d == null) {
|
||||
d = ContextCompat.getDrawable(app, resId);
|
||||
d = DrawableCompat.wrap(d);
|
||||
d.mutate();
|
||||
DrawableCompat.setTint(d, color);
|
||||
|
||||
drawable.put(hash, d);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
public Drawable getPaintedIcon(@DrawableRes int id, @ColorInt int color){
|
||||
return getPaintedDrawable(id, color);
|
||||
}
|
||||
|
||||
public Drawable getIcon(@DrawableRes int id, @ColorRes int colorId) {
|
||||
return getDrawable(id, colorId);
|
||||
}
|
||||
|
||||
public Drawable getIcon(@DrawableRes int backgroundId, @DrawableRes int id, @ColorRes int colorId) {
|
||||
Drawable b = getDrawable(backgroundId, 0);
|
||||
Drawable f = getDrawable(id, colorId);
|
||||
Drawable[] layers = new Drawable[2];
|
||||
layers[0] = b;
|
||||
layers[1] = f;
|
||||
return new LayerDrawable(layers);
|
||||
}
|
||||
|
||||
public Drawable getThemedIcon(@DrawableRes int id) {
|
||||
return getDrawable(id, R.color.icon_color);
|
||||
}
|
||||
|
||||
public Drawable getIcon(@DrawableRes int id) {
|
||||
return getDrawable(id, 0);
|
||||
}
|
||||
|
||||
public Drawable getIcon(@DrawableRes int id, boolean light) {
|
||||
return getDrawable(id, light ? R.color.icon_color : 0);
|
||||
}
|
||||
|
||||
|
||||
// Osmand resources
|
||||
private Drawable getOsmandDrawable(int resId, @ColorRes int clrId) {
|
||||
long hash = ((long)resId << 31L) + clrId;
|
||||
Drawable d = osmandDrawable.get(hash);
|
||||
if (d == null) {
|
||||
d = OsmandResources.getDrawable(resId);
|
||||
if (d != null) {
|
||||
d = DrawableCompat.wrap(d);
|
||||
d.mutate();
|
||||
if (clrId != 0) {
|
||||
DrawableCompat.setTint(d, ContextCompat.getColor(app, clrId));
|
||||
}
|
||||
osmandDrawable.put(hash, d);
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
private Drawable getPaintedOsmandDrawable(int resId, @ColorInt int color){
|
||||
long hash = ((long)resId << 31L) + color;
|
||||
Drawable d = osmandDrawable.get(hash);
|
||||
if(d == null) {
|
||||
d = OsmandResources.getDrawable(resId);
|
||||
if (d != null) {
|
||||
d = DrawableCompat.wrap(d);
|
||||
d.mutate();
|
||||
DrawableCompat.setTint(d, color);
|
||||
osmandDrawable.put(hash, d);
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
public Drawable getPaintedIcon(String osmandId, @ColorInt int color){
|
||||
int id = OsmandResources.getDrawableId(osmandId);
|
||||
if (id != 0) {
|
||||
return getPaintedOsmandDrawable(id, color);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Drawable getOsmandIcon(@DrawableRes int id, @ColorRes int colorId) {
|
||||
return getOsmandDrawable(id, colorId);
|
||||
}
|
||||
|
||||
public Drawable getIcon(String osmandId, @ColorRes int colorId) {
|
||||
int id = OsmandResources.getDrawableId(osmandId);
|
||||
if (id != 0) {
|
||||
return getOsmandDrawable(id, colorId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Drawable getIcon(String osmandBackgroundId, String osmandId, @ColorRes int colorId) {
|
||||
int backgroundId = OsmandResources.getDrawableId(osmandBackgroundId);
|
||||
int id = OsmandResources.getDrawableId(osmandId);
|
||||
if (backgroundId != 0 && id != 0) {
|
||||
Drawable b = getOsmandDrawable(backgroundId, 0);
|
||||
Drawable f = getOsmandDrawable(id, colorId);
|
||||
Drawable[] layers = new Drawable[2];
|
||||
layers[0] = b;
|
||||
layers[1] = f;
|
||||
return new LayerDrawable(layers);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Drawable getThemedIcon(String osmandId) {
|
||||
int id = OsmandResources.getDrawableId(osmandId);
|
||||
if (id != 0) {
|
||||
return getOsmandDrawable(id, R.color.icon_color);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Drawable getIcon(String osmandId) {
|
||||
int id = OsmandResources.getDrawableId(osmandId);
|
||||
if (id != 0) {
|
||||
return getOsmandDrawable(id, 0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Drawable getIcon(String osmandId, boolean light) {
|
||||
int id = OsmandResources.getDrawableId(osmandId);
|
||||
if (id != 0) {
|
||||
return getOsmandDrawable(id, light ? R.color.icon_color : 0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.content.ActivityNotFoundException;
|
|||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
|
@ -14,8 +13,8 @@ import android.support.v7.app.AlertDialog;
|
|||
import android.support.v7.app.AppCompatDialogFragment;
|
||||
import android.view.View;
|
||||
|
||||
public class InstallOsmAndAppDialog extends AppCompatDialogFragment {
|
||||
private static final String TAG = "InstallOsmAndAppDialog";
|
||||
public class InstallOsmandAppDialog extends AppCompatDialogFragment {
|
||||
private static final String TAG = "InstallOsmandAppDialog";
|
||||
private static final String OSMAND_PLUS_PACKAGE_NAME = "net.osmand.plus";
|
||||
private static final String OSMAND_PACKAGE_NAME = "net.osmand";
|
||||
private static boolean wasChecked = false;
|
||||
|
@ -70,7 +69,7 @@ public class InstallOsmAndAppDialog extends AppCompatDialogFragment {
|
|||
wasChecked = true;
|
||||
if (!SampleUtils.isPackageInstalled(OSMAND_PACKAGE_NAME, ctx)
|
||||
&& !SampleUtils.isPackageInstalled(OSMAND_PLUS_PACKAGE_NAME, ctx)) {
|
||||
new InstallOsmAndAppDialog().show(manager, TAG);
|
||||
new InstallOsmandAppDialog().show(manager, TAG);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
|
|
@ -7,38 +7,24 @@ import android.content.SharedPreferences;
|
|||
import android.content.SharedPreferences.Editor;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.PointF;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.support.v4.view.ViewPropertyAnimatorListener;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.GestureDetector.SimpleOnGestureListener;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.core.android.AtlasMapRendererView;
|
||||
import net.osmand.core.jni.IMapLayerProvider;
|
||||
import net.osmand.core.jni.IMapStylesCollection;
|
||||
import net.osmand.core.jni.IQueryController;
|
||||
import net.osmand.core.jni.ISearch;
|
||||
import net.osmand.core.jni.Logger;
|
||||
import net.osmand.core.jni.MapObjectsSymbolsProvider;
|
||||
import net.osmand.core.jni.MapPresentationEnvironment;
|
||||
|
@ -46,34 +32,20 @@ import net.osmand.core.jni.MapPrimitivesProvider;
|
|||
import net.osmand.core.jni.MapPrimitiviser;
|
||||
import net.osmand.core.jni.MapRasterLayerProvider_Software;
|
||||
import net.osmand.core.jni.MapStylesCollection;
|
||||
import net.osmand.core.jni.NullablePointI;
|
||||
import net.osmand.core.jni.ObfMapObjectsProvider;
|
||||
import net.osmand.core.jni.ObfsCollection;
|
||||
import net.osmand.core.jni.OsmAndCoreJNI;
|
||||
import net.osmand.core.jni.PointI;
|
||||
import net.osmand.core.jni.QIODeviceLogSink;
|
||||
import net.osmand.core.jni.ResolvedMapStyle;
|
||||
import net.osmand.core.jni.ReverseGeocoder;
|
||||
import net.osmand.core.jni.RoadLocator;
|
||||
import net.osmand.core.jni.Utilities;
|
||||
import net.osmand.core.samples.android.sample1.MultiTouchSupport.MultiTouchZoomListener;
|
||||
import net.osmand.core.samples.android.sample1.adapters.SearchListAdapter;
|
||||
import net.osmand.core.samples.android.sample1.adapters.SearchListItem;
|
||||
import net.osmand.core.samples.android.sample1.search.QuickSearchDialogFragment;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.search.SearchUICore;
|
||||
import net.osmand.search.SearchUICore.SearchResultCollection;
|
||||
import net.osmand.search.core.ObjectType;
|
||||
import net.osmand.search.core.SearchResult;
|
||||
import net.osmand.search.core.SearchSettings;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
private static final String TAG = "OsmAndCoreSample";
|
||||
|
@ -95,6 +67,7 @@ public class MainActivity extends AppCompatActivity {
|
|||
|
||||
private AtlasMapRendererView mapView;
|
||||
private TextView textZoom;
|
||||
private ImageButton searchButton;
|
||||
private ImageButton azimuthNorthButton;
|
||||
|
||||
private GestureDetector gestureDetector;
|
||||
|
@ -104,18 +77,6 @@ public class MainActivity extends AppCompatActivity {
|
|||
private float elevationAngle;
|
||||
private MultiTouchSupport multiTouchSupport;
|
||||
|
||||
private SearchUICore searchUICore;
|
||||
|
||||
private EditText searchEditText;
|
||||
private ImageView searchIcon;
|
||||
private ProgressBar progressBar;
|
||||
|
||||
private final static int MAX_SEARCH_RESULTS_CORE = 0;
|
||||
private final static int MAX_SEARCH_RESULTS_IU = 150;
|
||||
private ListView searchListView;
|
||||
private SearchListAdapter adapter;
|
||||
private String queryText = "";
|
||||
|
||||
private boolean noMapsFound;
|
||||
|
||||
// Germany
|
||||
|
@ -136,14 +97,8 @@ public class MainActivity extends AppCompatActivity {
|
|||
private static final String PREF_MAP_ZOOM = "MAP_ZOOM";
|
||||
private static final String PREF_MAP_ELEVATION_ANGLE = "MAP_ELEVATION_ANGLE";
|
||||
|
||||
public static final String LANGUAGE;
|
||||
|
||||
static {
|
||||
String langCode = Locale.getDefault().getLanguage();
|
||||
if (langCode.isEmpty()) {
|
||||
langCode = "en";
|
||||
}
|
||||
LANGUAGE = langCode;
|
||||
public SampleApplication getMyApplication() {
|
||||
return (SampleApplication) getApplication();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -179,8 +134,16 @@ public class MainActivity extends AppCompatActivity {
|
|||
mapView = (AtlasMapRendererView) findViewById(R.id.mapRendererView);
|
||||
|
||||
textZoom = (TextView) findViewById(R.id.text_zoom);
|
||||
azimuthNorthButton = (ImageButton) findViewById(R.id.map_azimuth_north_button);
|
||||
|
||||
searchButton = (ImageButton) findViewById(R.id.search_button);
|
||||
searchButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
showQuickSearch(ShowQuickSearchMode.NEW_IF_EXPIRED, false);
|
||||
}
|
||||
});
|
||||
|
||||
azimuthNorthButton = (ImageButton) findViewById(R.id.map_azimuth_north_button);
|
||||
azimuthNorthButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
@ -237,7 +200,7 @@ public class MainActivity extends AppCompatActivity {
|
|||
displayDensityFactor,
|
||||
1.0f,
|
||||
1.0f,
|
||||
LANGUAGE);
|
||||
SampleApplication.LANGUAGE);
|
||||
//mapPresentationEnvironment->setSettings(configuration.styleSettings);
|
||||
mapPrimitiviser = new MapPrimitiviser(
|
||||
mapPresentationEnvironment);
|
||||
|
@ -261,94 +224,7 @@ public class MainActivity extends AppCompatActivity {
|
|||
|
||||
app.getIconsCache().setDisplayDensityFactor(displayDensityFactor);
|
||||
|
||||
setupSearch();
|
||||
|
||||
searchEditText = (EditText) findViewById(R.id.searchEditText);
|
||||
searchEditText.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
String newQueryText = s.toString();
|
||||
if (!queryText.equalsIgnoreCase(newQueryText)) {
|
||||
queryText = newQueryText;
|
||||
showProgressBar();
|
||||
runSearch();
|
||||
}
|
||||
}
|
||||
});
|
||||
searchEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
if (hasFocus) {
|
||||
net.osmand.core.jni.LatLon latLon = Utilities.convert31ToLatLon(target31);
|
||||
SearchSettings settings = searchUICore.getPhrase().getSettings().setOriginalLocation(
|
||||
new LatLon(latLon.getLatitude(), latLon.getLongitude()));
|
||||
settings = settings.setLang(LANGUAGE, false);
|
||||
searchUICore.updateSettings(settings);
|
||||
|
||||
adapter.setLocation(new LatLon(latLon.getLatitude(), latLon.getLongitude()));
|
||||
|
||||
if (isSearchListHidden()) {
|
||||
showSearchList();
|
||||
if (adapter.getCount() > 0) {
|
||||
adapter.updateDistance(latLon.getLatitude(), latLon.getLongitude());
|
||||
adapter.notifyDataSetChanged();
|
||||
} else {
|
||||
runSearch();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
searchIcon = (ImageView) findViewById(R.id.searchIcon);
|
||||
progressBar = (ProgressBar) findViewById(R.id.searchProgressBar);
|
||||
|
||||
ImageButton clearButton = (ImageButton) findViewById(R.id.clearButton);
|
||||
clearButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
searchEditText.setText("");
|
||||
adapter.clear();
|
||||
adapter.notifyDataSetChanged();
|
||||
hideSearchList();
|
||||
}
|
||||
});
|
||||
|
||||
searchListView = (ListView) findViewById(android.R.id.list);
|
||||
adapter = new SearchListAdapter(this);
|
||||
searchListView.setAdapter(adapter);
|
||||
searchListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
SearchListItem item = adapter.getItem(position);
|
||||
SearchResult sr = item.getSearchResult();
|
||||
|
||||
boolean updateEditText = true;
|
||||
if (sr.objectType == ObjectType.POI
|
||||
|| sr.objectType == ObjectType.LOCATION
|
||||
|| sr.objectType == ObjectType.HOUSE
|
||||
|| sr.objectType == ObjectType.FAVORITE
|
||||
|| sr.objectType == ObjectType.RECENT_OBJ
|
||||
|| sr.objectType == ObjectType.WPT
|
||||
|| sr.objectType == ObjectType.STREET_INTERSECTION) {
|
||||
|
||||
hideSearchList();
|
||||
mapView.requestFocus();
|
||||
updateEditText = false;
|
||||
}
|
||||
completeQueryWithObject(item.getSearchResult(), updateEditText);
|
||||
}
|
||||
});
|
||||
|
||||
if (!InstallOsmAndAppDialog.showIfNeeded(getSupportFragmentManager(), this)
|
||||
if (!InstallOsmandAppDialog.showIfNeeded(getSupportFragmentManager(), this)
|
||||
&& externalStoragePermissionGranted) {
|
||||
checkMapsInstalled();
|
||||
}
|
||||
|
@ -381,41 +257,6 @@ public class MainActivity extends AppCompatActivity {
|
|||
}
|
||||
}
|
||||
|
||||
private void setupSearch() {
|
||||
final SampleApplication app = getSampleApplication();
|
||||
List<BinaryMapIndexReader> files = new ArrayList<>();
|
||||
File file = new File(app.getAbsoluteAppPath());
|
||||
if (file.exists() && file.listFiles() != null) {
|
||||
for (File obf : file.listFiles()) {
|
||||
if (!obf.isDirectory() && obf.getName().endsWith(".obf")) {
|
||||
try {
|
||||
BinaryMapIndexReader bmir = new BinaryMapIndexReader(new RandomAccessFile(obf, "r"), obf);
|
||||
files.add(bmir);
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
searchUICore = new SearchUICore(app.getPoiTypes(), LANGUAGE, false);
|
||||
searchUICore.getSearchSettings().setOfflineIndexes(Arrays.asList(files.toArray(new BinaryMapIndexReader[files.size()])));
|
||||
searchUICore.init();
|
||||
|
||||
searchUICore.setOnResultsComplete(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
app.runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
hideProgressBar();
|
||||
updateSearchResult(searchUICore.getCurrentSearchResult(), true);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
@ -439,7 +280,7 @@ public class MainActivity extends AppCompatActivity {
|
|||
return (SampleApplication) getApplication();
|
||||
}
|
||||
|
||||
private void showOnMap(LatLon latLon, int zoom) {
|
||||
public void showOnMap(LatLon latLon, int zoom) {
|
||||
if (latLon != null) {
|
||||
PointI target = Utilities.convertLatLonTo31(
|
||||
new net.osmand.core.jni.LatLon(latLon.getLatitude(), latLon.getLongitude()));
|
||||
|
@ -448,51 +289,17 @@ public class MainActivity extends AppCompatActivity {
|
|||
}
|
||||
}
|
||||
|
||||
private PointI getScreenCenter31() {
|
||||
public PointI getScreenCenter31() {
|
||||
PointI point = new PointI();
|
||||
mapView.getLocationFromScreenPoint(new PointI(mapView.getWidth() / 2, mapView.getHeight() / 2), point);
|
||||
return point;
|
||||
}
|
||||
|
||||
private void showProgressBar() {
|
||||
searchIcon.setVisibility(View.GONE);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void hideProgressBar() {
|
||||
progressBar.setVisibility(View.GONE);
|
||||
searchIcon.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private boolean isSearchListHidden() {
|
||||
return searchListView.getVisibility() != View.VISIBLE;
|
||||
}
|
||||
|
||||
private void showSearchList() {
|
||||
if (isSearchListHidden()) {
|
||||
ViewCompat.setAlpha(searchListView, 0f);
|
||||
searchListView.setVisibility(View.VISIBLE);
|
||||
ViewCompat.animate(searchListView).alpha(1f).setListener(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void hideSearchList() {
|
||||
ViewCompat.animate(searchListView).alpha(0f).setListener(new ViewPropertyAnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationStart(View view) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(View view) {
|
||||
searchListView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(View view) {
|
||||
searchListView.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
public LatLon getScreenCenter() {
|
||||
PointI point = new PointI();
|
||||
mapView.getLocationFromScreenPoint(new PointI(mapView.getWidth() / 2, mapView.getHeight() / 2), point);
|
||||
net.osmand.core.jni.LatLon jniLatLon = Utilities.convert31ToLatLon(point);
|
||||
return new LatLon(jniLatLon.getLatitude(), jniLatLon.getLongitude());
|
||||
}
|
||||
|
||||
public void saveMapState() {
|
||||
|
@ -565,126 +372,6 @@ public class MainActivity extends AppCompatActivity {
|
|||
|| gestureDetector.onTouchEvent(event);
|
||||
}
|
||||
|
||||
private void runSearch() {
|
||||
runSearch(queryText);
|
||||
}
|
||||
|
||||
private void runSearch(String text) {
|
||||
|
||||
SearchSettings settings = searchUICore.getPhrase().getSettings();
|
||||
if (settings.getRadiusLevel() != 1) {
|
||||
searchUICore.updateSettings(settings.setRadiusLevel(1));
|
||||
}
|
||||
searchUICore.search(text, null);
|
||||
SearchResultCollection c = searchUICore.search(text, null);
|
||||
updateSearchResult(c, false);
|
||||
}
|
||||
|
||||
private void completeQueryWithObject(SearchResult sr, boolean updateEditText) {
|
||||
|
||||
if (sr.location != null) {
|
||||
showOnMap(sr.location, sr.preferredZoom);
|
||||
}
|
||||
searchUICore.selectSearchResult(sr);
|
||||
String txt = searchUICore.getPhrase().getText(true);
|
||||
if (updateEditText) {
|
||||
queryText = txt;
|
||||
searchEditText.setText(txt);
|
||||
searchEditText.setSelection(txt.length());
|
||||
}
|
||||
|
||||
searchUICore.search(txt, null);
|
||||
}
|
||||
|
||||
private void updateSearchResult(SearchResultCollection res, boolean addMore) {
|
||||
|
||||
SampleApplication app = getSampleApplication();
|
||||
|
||||
if (res.getCurrentSearchResults().size() > 0) {
|
||||
List<SearchListItem> rows = new ArrayList<>();
|
||||
for (final SearchResult sr : res.getCurrentSearchResults()) {
|
||||
|
||||
int count = 30;
|
||||
/*
|
||||
if(addMore) {
|
||||
JMenuItem mi = new JMenuItem();
|
||||
mi.setText("Results " + res.getCurrentSearchResults().size() + ", radius " + res.getPhrase().getRadiusLevel()+
|
||||
" (show more...)");
|
||||
mi.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
SearchSettings settings = searchUICore.getPhrase().getSettings();
|
||||
searchUICore.updateSettings(settings.setRadiusLevel(settings.getRadiusLevel() + 1));
|
||||
searchUICore.search(statusField.getText(), null);
|
||||
updateSearchResult(statusField, new SearchResultCollection(), false);
|
||||
}
|
||||
});
|
||||
popup.add(mi);
|
||||
}
|
||||
*/
|
||||
|
||||
count--;
|
||||
if (count == 0) {
|
||||
// break;
|
||||
}
|
||||
//LatLon location = res.getPhrase().getLastTokenLocation();
|
||||
//String locationString = "";
|
||||
//if (sr.location != null) {
|
||||
// locationString = ((int) MapUtils.getDistance(location, sr.location)) + " m";
|
||||
//}
|
||||
//mi.setText(sr.localeName + " [" + sr.objectType + "] " + locationString);
|
||||
|
||||
SearchListItem listItem = new SearchListItem(app, sr);
|
||||
if (sr.location != null) {
|
||||
LatLon location = res.getPhrase().getLastTokenLocation();
|
||||
listItem.setDistance(MapUtils.getDistance(location, sr.location));
|
||||
}
|
||||
rows.add(listItem);
|
||||
}
|
||||
updateListAdapter(rows);
|
||||
showSearchList();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateListAdapter(List<SearchListItem> listItems) {
|
||||
adapter.setListItems(listItems);
|
||||
if (adapter.getCount() > 0) {
|
||||
searchListView.setSelection(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void geocode(@NonNull PointI point31) {
|
||||
new AsyncTask<PointI, Void, String>() {
|
||||
@Override
|
||||
protected String doInBackground(PointI... params) {
|
||||
final String[] resultString = {null};
|
||||
ReverseGeocoder geocoder = new ReverseGeocoder(obfsCollection, roadLocator);
|
||||
final ReverseGeocoder.Criteria criteria = new ReverseGeocoder.Criteria();
|
||||
criteria.setPosition31(new NullablePointI(params[0]));
|
||||
ISearch.INewResultEntryCallback geocoderResultCallback = new ISearch.INewResultEntryCallback() {
|
||||
@Override
|
||||
public void method(ISearch.Criteria criteria, ISearch.IResultEntry resultEntry) {
|
||||
ReverseGeocoderResultEntry result = new ReverseGeocoderResultEntry(resultEntry);
|
||||
resultString[0] = result.toString();
|
||||
}
|
||||
};
|
||||
geocoder.performSearch(criteria, geocoderResultCallback.getBinding(), new IQueryController() {
|
||||
@Override
|
||||
public boolean isAborted() {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return resultString[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String s) {
|
||||
Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}.execute(point31);
|
||||
}
|
||||
|
||||
private class MapViewOnGestureListener extends SimpleOnGestureListener {
|
||||
|
||||
@Override
|
||||
|
@ -796,10 +483,68 @@ public class MainActivity extends AppCompatActivity {
|
|||
}
|
||||
}
|
||||
|
||||
private class ReverseGeocoderResultEntry extends ReverseGeocoder.ResultEntry {
|
||||
protected ReverseGeocoderResultEntry(ISearch.IResultEntry resultEntry) {
|
||||
super(OsmAndCoreJNI.ReverseGeocoder_ResultEntry_SWIGUpcast(ISearch.IResultEntry.getCPtr(resultEntry)), false);
|
||||
public void showQuickSearch(double latitude, double longitude) {
|
||||
hideContextMenu();
|
||||
QuickSearchDialogFragment fragment = getQuickSearchDialogFragment();
|
||||
if (fragment != null) {
|
||||
fragment.dismiss();
|
||||
//refreshMap();
|
||||
}
|
||||
QuickSearchDialogFragment.showInstance(this, "", null, true, new LatLon(latitude, longitude));
|
||||
}
|
||||
|
||||
public void showQuickSearch(Object object) {
|
||||
hideContextMenu();
|
||||
QuickSearchDialogFragment fragment = getQuickSearchDialogFragment();
|
||||
if (fragment != null) {
|
||||
fragment.dismiss();
|
||||
//refreshMap();
|
||||
}
|
||||
QuickSearchDialogFragment.showInstance(this, "", object, true, null);
|
||||
}
|
||||
|
||||
public void showQuickSearch(ShowQuickSearchMode mode, boolean showCategories) {
|
||||
hideContextMenu();
|
||||
QuickSearchDialogFragment fragment = getQuickSearchDialogFragment();
|
||||
if (fragment != null) {
|
||||
if (mode == ShowQuickSearchMode.NEW || (mode == ShowQuickSearchMode.NEW_IF_EXPIRED && fragment.isExpired())) {
|
||||
fragment.dismiss();
|
||||
QuickSearchDialogFragment.showInstance(this, "", null, showCategories, null);
|
||||
} else {
|
||||
fragment.show();
|
||||
}
|
||||
//refreshMap();
|
||||
} else {
|
||||
QuickSearchDialogFragment.showInstance(this, "", null, showCategories, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void closeQuickSearch() {
|
||||
QuickSearchDialogFragment fragment = getQuickSearchDialogFragment();
|
||||
if (fragment != null) {
|
||||
fragment.closeSearch();
|
||||
//refreshMap();
|
||||
}
|
||||
}
|
||||
|
||||
public QuickSearchDialogFragment getQuickSearchDialogFragment() {
|
||||
Fragment fragment = getSupportFragmentManager().findFragmentByTag(QuickSearchDialogFragment.TAG);
|
||||
return fragment != null && !fragment.isDetached() && !fragment.isRemoving() ? (QuickSearchDialogFragment) fragment : null;
|
||||
}
|
||||
|
||||
private void hideContextMenu() {
|
||||
/* todo
|
||||
if (mapContextMenu.isVisible()) {
|
||||
mapContextMenu.hide();
|
||||
} else if (mapContextMenu.getMultiSelectionMenu().isVisible()) {
|
||||
mapContextMenu.getMultiSelectionMenu().hide();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public enum ShowQuickSearchMode {
|
||||
NEW,
|
||||
NEW_IF_EXPIRED,
|
||||
CURRENT,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
package net.osmand.core.samples.android.sample1;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
public class OsmandResources {
|
||||
|
||||
private static Resources osmandResources;
|
||||
private static String packageName;
|
||||
|
||||
public static void init(Context ctx) {
|
||||
String packageName = "net.osmand";
|
||||
try {
|
||||
osmandResources = ctx.getPackageManager().getResourcesForApplication(packageName);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
//ignore
|
||||
}
|
||||
if (osmandResources == null) {
|
||||
packageName = "net.osmand.plus";
|
||||
try {
|
||||
osmandResources = ctx.getPackageManager().getResourcesForApplication(packageName);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
if (osmandResources == null) {
|
||||
packageName = "net.osmand.dev";
|
||||
try {
|
||||
osmandResources = ctx.getPackageManager().getResourcesForApplication(packageName);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
if (osmandResources != null) {
|
||||
OsmandResources.packageName = packageName;
|
||||
}
|
||||
}
|
||||
|
||||
public static Resources getOsmandResources() {
|
||||
return osmandResources;
|
||||
}
|
||||
|
||||
public static String getString(String id) {
|
||||
if (osmandResources != null) {
|
||||
int resolvedId = osmandResources.getIdentifier(id, "string", packageName);
|
||||
return osmandResources.getString(resolvedId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getString(String id, Object... formatArgs) {
|
||||
if (osmandResources != null) {
|
||||
int resolvedId = osmandResources.getIdentifier(id, "string", packageName);
|
||||
return osmandResources.getString(resolvedId, formatArgs);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Drawable getDrawable(String id) {
|
||||
if (osmandResources != null) {
|
||||
int resolvedId = osmandResources.getIdentifier(id, "drawable", packageName);
|
||||
return osmandResources.getDrawable(resolvedId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Drawable getDrawable(int id) {
|
||||
if (osmandResources != null) {
|
||||
return osmandResources.getDrawable(id);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int getDrawableId(String id) {
|
||||
if (osmandResources != null) {
|
||||
return osmandResources.getIdentifier(id, "drawable", packageName);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,10 @@ package net.osmand.core.samples.android.sample1;
|
|||
|
||||
import android.Manifest;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
|
@ -11,32 +14,58 @@ import net.osmand.core.android.CoreResourcesFromAndroidAssets;
|
|||
import net.osmand.core.android.NativeCore;
|
||||
import net.osmand.core.jni.LogSeverityLevel;
|
||||
import net.osmand.core.jni.Logger;
|
||||
import net.osmand.core.samples.android.sample1.SampleFormatter.MetricsConstants;
|
||||
import net.osmand.core.samples.android.sample1.SampleFormatter.SpeedConstants;
|
||||
import net.osmand.core.samples.android.sample1.search.QuickSearchHelper;
|
||||
import net.osmand.osm.AbstractPoiType;
|
||||
import net.osmand.osm.MapPoiTypes;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Locale;
|
||||
|
||||
import static net.osmand.core.samples.android.sample1.data.PointDescription.FORMAT_DEGREES;
|
||||
|
||||
public class SampleApplication extends Application {
|
||||
public static final int PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 5 ;
|
||||
private CoreResourcesFromAndroidAssets assetsCustom;
|
||||
private MapPoiTypes poiTypes;
|
||||
private IconsCache iconsCache;
|
||||
Handler uiHandler;
|
||||
private Handler uiHandler;
|
||||
private long lastTimeInternetConnectionChecked = 0;
|
||||
private boolean internetConnectionAvailable = true;
|
||||
|
||||
private int coordinatesFormat = FORMAT_DEGREES;
|
||||
private MetricsConstants metricsConstants = MetricsConstants.KILOMETERS_AND_METERS;
|
||||
private SpeedConstants speedConstants = SpeedConstants.KILOMETERS_PER_HOUR;
|
||||
|
||||
private SampleLocationProvider locationProvider;
|
||||
private QuickSearchHelper searchUICore;
|
||||
|
||||
public static final String LANGUAGE;
|
||||
|
||||
static {
|
||||
String langCode = Locale.getDefault().getLanguage();
|
||||
if (langCode.isEmpty()) {
|
||||
langCode = "en";
|
||||
}
|
||||
LANGUAGE = langCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate()
|
||||
{
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
OsmandResources.init(this);
|
||||
locationProvider = new SampleLocationProvider(this);
|
||||
searchUICore = new QuickSearchHelper(this);
|
||||
uiHandler = new Handler();
|
||||
|
||||
poiTypes = MapPoiTypes.getDefaultNoInit();
|
||||
if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
== PackageManager.PERMISSION_GRANTED) {
|
||||
initPoiTypes();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Initialize native core
|
||||
if (NativeCore.isAvailable() && !NativeCore.isLoaded()) {
|
||||
assetsCustom = CoreResourcesFromAndroidAssets.loadFromCurrentApplication(this);
|
||||
|
@ -44,7 +73,27 @@ public class SampleApplication extends Application {
|
|||
}
|
||||
Logger.get().setSeverityLevelThreshold(LogSeverityLevel.Debug);
|
||||
|
||||
iconsCache = new IconsCache(assetsCustom);
|
||||
iconsCache = new IconsCache(assetsCustom, this);
|
||||
}
|
||||
|
||||
public int getCoordinatesFormat() {
|
||||
return coordinatesFormat;
|
||||
}
|
||||
|
||||
public MetricsConstants getMetricsConstants() {
|
||||
return metricsConstants;
|
||||
}
|
||||
|
||||
public SpeedConstants getSpeedConstants() {
|
||||
return speedConstants;
|
||||
}
|
||||
|
||||
public SampleLocationProvider getLocationProvider() {
|
||||
return locationProvider;
|
||||
}
|
||||
|
||||
public QuickSearchHelper getSearchUICore() {
|
||||
return searchUICore;
|
||||
}
|
||||
|
||||
public MapPoiTypes getPoiTypes() {
|
||||
|
@ -86,6 +135,8 @@ public class SampleApplication extends Application {
|
|||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
searchUICore.initSearchUICore();
|
||||
}
|
||||
|
||||
public String getAbsoluteAppPath() {
|
||||
|
@ -119,4 +170,46 @@ public class SampleApplication extends Application {
|
|||
public void runInUIThread(Runnable run, long delay) {
|
||||
uiHandler.postDelayed(run, delay);
|
||||
}
|
||||
|
||||
// Check internet connection available every 15 seconds
|
||||
public boolean isInternetConnectionAvailable() {
|
||||
return isInternetConnectionAvailable(false);
|
||||
}
|
||||
|
||||
public boolean isInternetConnectionAvailable(boolean update) {
|
||||
long delta = System.currentTimeMillis() - lastTimeInternetConnectionChecked;
|
||||
if (delta < 0 || delta > 15000 || update) {
|
||||
internetConnectionAvailable = isInternetConnected();
|
||||
}
|
||||
return internetConnectionAvailable;
|
||||
}
|
||||
|
||||
public boolean isWifiConnected() {
|
||||
ConnectivityManager mgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo ni = mgr.getActiveNetworkInfo();
|
||||
return ni != null && ni.getType() == ConnectivityManager.TYPE_WIFI;
|
||||
}
|
||||
|
||||
private boolean isInternetConnected() {
|
||||
ConnectivityManager mgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo active = mgr.getActiveNetworkInfo();
|
||||
if (active == null) {
|
||||
return false;
|
||||
} else {
|
||||
NetworkInfo.State state = active.getState();
|
||||
return state != NetworkInfo.State.DISCONNECTED && state != NetworkInfo.State.DISCONNECTING;
|
||||
}
|
||||
}
|
||||
|
||||
public static SampleApplication getApp(Context ctx) {
|
||||
return (SampleApplication) ctx.getApplicationContext();
|
||||
}
|
||||
|
||||
public String getString(String osmandId) {
|
||||
return OsmandResources.getString(osmandId);
|
||||
}
|
||||
|
||||
public String getString(String osmandId, Object... formatArgs) {
|
||||
return OsmandResources.getString(osmandId, formatArgs);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,355 @@
|
|||
package net.osmand.core.samples.android.sample1;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.City.CityType;
|
||||
import net.osmand.osm.AbstractPoiType;
|
||||
import net.osmand.osm.MapPoiTypes;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.osm.PoiType;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class SampleFormatter {
|
||||
public final static float METERS_IN_KILOMETER = 1000f;
|
||||
public final static float METERS_IN_ONE_MILE = 1609.344f; // 1609.344
|
||||
public final static float METERS_IN_ONE_NAUTICALMILE = 1852f; // 1852
|
||||
|
||||
public final static float YARDS_IN_ONE_METER = 1.0936f;
|
||||
public final static float FEET_IN_ONE_METER = YARDS_IN_ONE_METER * 3f;
|
||||
private static final DecimalFormat fixed2 = new DecimalFormat("0.00");
|
||||
private static final DecimalFormat fixed1 = new DecimalFormat("0.0");
|
||||
{
|
||||
fixed2.setMinimumFractionDigits(2);
|
||||
fixed1.setMinimumFractionDigits(1);
|
||||
fixed1.setMinimumIntegerDigits(1);
|
||||
fixed2.setMinimumIntegerDigits(1);
|
||||
}
|
||||
|
||||
public static String getFormattedDuration(int seconds, SampleApplication ctx) {
|
||||
int hours = seconds / (60 * 60);
|
||||
int minutes = (seconds / 60) % 60;
|
||||
if (hours > 0) {
|
||||
return hours + " "
|
||||
+ ctx.getString(R.string.shared_string_hour_short)
|
||||
+ (minutes > 0 ? " " + minutes + " "
|
||||
+ ctx.getString(R.string.shared_string_minute_short) : "");
|
||||
} else {
|
||||
return minutes + " " + ctx.getString(R.string.shared_string_minute_short);
|
||||
}
|
||||
}
|
||||
|
||||
public static double calculateRoundedDist(double distInMeters, SampleApplication ctx) {
|
||||
MetricsConstants mc = ctx.getMetricsConstants();
|
||||
double mainUnitInMeter = 1;
|
||||
double metersInSecondUnit = METERS_IN_KILOMETER;
|
||||
if (mc == MetricsConstants.MILES_AND_FEET) {
|
||||
mainUnitInMeter = FEET_IN_ONE_METER;
|
||||
metersInSecondUnit = METERS_IN_ONE_MILE;
|
||||
} else if (mc == MetricsConstants.MILES_AND_METERS) {
|
||||
mainUnitInMeter = 1;
|
||||
metersInSecondUnit = METERS_IN_ONE_MILE;
|
||||
} else if (mc == MetricsConstants.NAUTICAL_MILES) {
|
||||
mainUnitInMeter = 1;
|
||||
metersInSecondUnit = METERS_IN_ONE_NAUTICALMILE;
|
||||
} else if (mc == MetricsConstants.MILES_AND_YARDS) {
|
||||
mainUnitInMeter = YARDS_IN_ONE_METER;
|
||||
metersInSecondUnit = METERS_IN_ONE_MILE;
|
||||
}
|
||||
|
||||
// 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000 ...
|
||||
int generator = 1;
|
||||
byte pointer = 1;
|
||||
double point = mainUnitInMeter;
|
||||
double roundDist = 1;
|
||||
while (distInMeters * point > generator) {
|
||||
roundDist = (generator / point);
|
||||
if (pointer++ % 3 == 2) {
|
||||
generator = generator * 5 / 2;
|
||||
} else {
|
||||
generator *= 2;
|
||||
}
|
||||
|
||||
if (point == mainUnitInMeter && metersInSecondUnit * mainUnitInMeter * 0.9f <= generator) {
|
||||
point = 1 / metersInSecondUnit;
|
||||
generator = 1;
|
||||
pointer = 1;
|
||||
}
|
||||
}
|
||||
//Miles exceptions: 2000ft->0.5mi, 1000ft->0.25mi, 1000yd->0.5mi, 500yd->0.25mi, 1000m ->0.5mi, 500m -> 0.25mi
|
||||
if (mc == MetricsConstants.MILES_AND_METERS && roundDist == 1000) {
|
||||
roundDist = 0.5f * METERS_IN_ONE_MILE;
|
||||
} else if (mc == MetricsConstants.MILES_AND_METERS && roundDist == 500) {
|
||||
roundDist = 0.25f * METERS_IN_ONE_MILE;
|
||||
} else if (mc == MetricsConstants.MILES_AND_FEET && roundDist == 2000 / (double) FEET_IN_ONE_METER) {
|
||||
roundDist = 0.5f * METERS_IN_ONE_MILE;
|
||||
} else if (mc == MetricsConstants.MILES_AND_FEET && roundDist == 1000 / (double) FEET_IN_ONE_METER) {
|
||||
roundDist = 0.25f * METERS_IN_ONE_MILE;
|
||||
} else if (mc == MetricsConstants.MILES_AND_YARDS && roundDist == 1000 / (double) YARDS_IN_ONE_METER) {
|
||||
roundDist = 0.5f * METERS_IN_ONE_MILE;
|
||||
} else if (mc == MetricsConstants.MILES_AND_YARDS && roundDist == 500 / (double) YARDS_IN_ONE_METER) {
|
||||
roundDist = 0.25f * METERS_IN_ONE_MILE;
|
||||
}
|
||||
return roundDist;
|
||||
}
|
||||
|
||||
public static String getFormattedRoundDistanceKm(float meters, int digits, SampleApplication ctx) {
|
||||
int mainUnitStr = R.string.km;
|
||||
float mainUnitInMeters = METERS_IN_KILOMETER;
|
||||
if (digits == 0) {
|
||||
return (int) (meters / mainUnitInMeters + 0.5) + " " + ctx.getString(mainUnitStr); //$NON-NLS-1$
|
||||
} else if (digits == 1) {
|
||||
return fixed1.format(((float) meters) / mainUnitInMeters) + " " + ctx.getString(mainUnitStr);
|
||||
} else {
|
||||
return fixed2.format(((float) meters) / mainUnitInMeters) + " " + ctx.getString(mainUnitStr);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getFormattedDistance(float meters, SampleApplication ctx) {
|
||||
return getFormattedDistance(meters, ctx, true);
|
||||
}
|
||||
|
||||
public static String getFormattedDistance(float meters, SampleApplication ctx, boolean forceTrailingZeros) {
|
||||
String format1 = forceTrailingZeros ? "{0,number,0.0} " : "{0,number,0.#} ";
|
||||
String format2 = forceTrailingZeros ? "{0,number,0.00} " : "{0,number,0.##} ";
|
||||
|
||||
MetricsConstants mc = ctx.getMetricsConstants();
|
||||
int mainUnitStr;
|
||||
float mainUnitInMeters;
|
||||
if (mc == MetricsConstants.KILOMETERS_AND_METERS) {
|
||||
mainUnitStr = R.string.km;
|
||||
mainUnitInMeters = METERS_IN_KILOMETER;
|
||||
} else if (mc == MetricsConstants.NAUTICAL_MILES) {
|
||||
mainUnitStr = R.string.nm;
|
||||
mainUnitInMeters = METERS_IN_ONE_NAUTICALMILE;
|
||||
} else {
|
||||
mainUnitStr = R.string.mile;
|
||||
mainUnitInMeters = METERS_IN_ONE_MILE;
|
||||
}
|
||||
|
||||
if (meters >= 100 * mainUnitInMeters) {
|
||||
return (int) (meters / mainUnitInMeters + 0.5) + " " + ctx.getString(mainUnitStr); //$NON-NLS-1$
|
||||
} else if (meters > 9.99f * mainUnitInMeters) {
|
||||
return MessageFormat.format(format1 + ctx.getString(mainUnitStr), ((float) meters) / mainUnitInMeters).replace('\n', ' '); //$NON-NLS-1$
|
||||
} else if (meters > 0.999f * mainUnitInMeters) {
|
||||
return MessageFormat.format(format2 + ctx.getString(mainUnitStr), ((float) meters) / mainUnitInMeters).replace('\n', ' '); //$NON-NLS-1$
|
||||
} else if (mc == MetricsConstants.MILES_AND_FEET && meters > 0.249f * mainUnitInMeters) {
|
||||
return MessageFormat.format(format2 + ctx.getString(mainUnitStr), ((float) meters) / mainUnitInMeters).replace('\n', ' '); //$NON-NLS-1$
|
||||
} else if (mc == MetricsConstants.MILES_AND_METERS && meters > 0.249f * mainUnitInMeters) {
|
||||
return MessageFormat.format(format2 + ctx.getString(mainUnitStr), ((float) meters) / mainUnitInMeters).replace('\n', ' '); //$NON-NLS-1$
|
||||
} else if (mc == MetricsConstants.MILES_AND_YARDS && meters > 0.249f * mainUnitInMeters) {
|
||||
return MessageFormat.format(format2 + ctx.getString(mainUnitStr), ((float) meters) / mainUnitInMeters).replace('\n', ' '); //$NON-NLS-1$
|
||||
} else if (mc == MetricsConstants.NAUTICAL_MILES && meters > 0.99f * mainUnitInMeters) {
|
||||
return MessageFormat.format(format2 + ctx.getString(mainUnitStr), ((float) meters) / mainUnitInMeters).replace('\n', ' '); //$NON-NLS-1$
|
||||
} else {
|
||||
if (mc == MetricsConstants.KILOMETERS_AND_METERS || mc == MetricsConstants.MILES_AND_METERS) {
|
||||
return ((int) (meters + 0.5)) + " " + ctx.getString(R.string.m); //$NON-NLS-1$
|
||||
} else if (mc == MetricsConstants.MILES_AND_FEET) {
|
||||
int feet = (int) (meters * FEET_IN_ONE_METER + 0.5);
|
||||
return feet + " " + ctx.getString(R.string.foot); //$NON-NLS-1$
|
||||
} else if (mc == MetricsConstants.MILES_AND_YARDS) {
|
||||
int yards = (int) (meters * YARDS_IN_ONE_METER + 0.5);
|
||||
return yards + " " + ctx.getString(R.string.yard); //$NON-NLS-1$
|
||||
}
|
||||
return ((int) (meters + 0.5)) + " " + ctx.getString(R.string.m); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
public static String getFormattedAlt(double alt, SampleApplication ctx) {
|
||||
MetricsConstants mc = ctx.getMetricsConstants();
|
||||
if (mc == MetricsConstants.KILOMETERS_AND_METERS) {
|
||||
return ((int) (alt + 0.5)) + " " + ctx.getString(R.string.m);
|
||||
} else {
|
||||
return ((int) (alt * FEET_IN_ONE_METER + 0.5)) + " " + ctx.getString(R.string.foot);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getFormattedSpeed(float metersperseconds, SampleApplication ctx) {
|
||||
SpeedConstants mc = ctx.getSpeedConstants();
|
||||
float kmh = metersperseconds * 3.6f;
|
||||
if (mc == SpeedConstants.KILOMETERS_PER_HOUR) {
|
||||
// e.g. car case and for high-speeds: Display rounded to 1 km/h (5% precision at 20 km/h)
|
||||
if (kmh >= 20) {
|
||||
return ((int) Math.round(kmh)) + " " + mc.toShortString(ctx);
|
||||
}
|
||||
// for smaller values display 1 decimal digit x.y km/h, (0.5% precision at 20 km/h)
|
||||
int kmh10 = (int) Math.round(kmh * 10f);
|
||||
return (kmh10 / 10f) + " " + mc.toShortString(ctx);
|
||||
} else if (mc == SpeedConstants.MILES_PER_HOUR) {
|
||||
float mph = kmh * METERS_IN_KILOMETER / METERS_IN_ONE_MILE;
|
||||
if (mph >= 20) {
|
||||
return ((int) Math.round(mph)) + " " + mc.toShortString(ctx);
|
||||
} else {
|
||||
int mph10 = (int) Math.round(mph * 10f);
|
||||
return (mph10 / 10f) + " " + mc.toShortString(ctx);
|
||||
}
|
||||
} else if (mc == SpeedConstants.NAUTICALMILES_PER_HOUR) {
|
||||
float mph = kmh * METERS_IN_KILOMETER / METERS_IN_ONE_NAUTICALMILE;
|
||||
if (mph >= 20) {
|
||||
return ((int) Math.round(mph)) + " " + mc.toShortString(ctx);
|
||||
} else {
|
||||
int mph10 = (int) Math.round(mph * 10f);
|
||||
return (mph10 / 10f) + " " + mc.toShortString(ctx);
|
||||
}
|
||||
} else if (mc == SpeedConstants.MINUTES_PER_KILOMETER) {
|
||||
if (metersperseconds < 0.111111111) {
|
||||
return "-" + mc.toShortString(ctx);
|
||||
}
|
||||
float minperkm = METERS_IN_KILOMETER / (metersperseconds * 60);
|
||||
if (minperkm >= 10) {
|
||||
return ((int) Math.round(minperkm)) + " " + mc.toShortString(ctx);
|
||||
} else {
|
||||
int mph10 = (int) Math.round(minperkm * 10f);
|
||||
return (mph10 / 10f) + " " + mc.toShortString(ctx);
|
||||
}
|
||||
} else if (mc == SpeedConstants.MINUTES_PER_MILE) {
|
||||
if (metersperseconds < 0.111111111) {
|
||||
return "-" + mc.toShortString(ctx);
|
||||
}
|
||||
float minperm = (METERS_IN_ONE_MILE) / (metersperseconds * 60);
|
||||
if (minperm >= 10) {
|
||||
return ((int) Math.round(minperm)) + " " + mc.toShortString(ctx);
|
||||
} else {
|
||||
int mph10 = (int) Math.round(minperm * 10f);
|
||||
return (mph10 / 10f) + " " + mc.toShortString(ctx);
|
||||
}
|
||||
} else /*if (mc == SpeedConstants.METERS_PER_SECOND) */ {
|
||||
if (metersperseconds >= 10) {
|
||||
return ((int) Math.round(metersperseconds)) + " " + SpeedConstants.METERS_PER_SECOND.toShortString(ctx);
|
||||
}
|
||||
// for smaller values display 1 decimal digit x.y km/h, (0.5% precision at 20 km/h)
|
||||
int kmh10 = (int) Math.round(metersperseconds * 10f);
|
||||
return (kmh10 / 10f) + " " + SpeedConstants.METERS_PER_SECOND.toShortString(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String toPublicString(CityType t, SampleApplication ctx) {
|
||||
switch (t) {
|
||||
case CITY:
|
||||
return ctx.getString("city_type_city");
|
||||
case HAMLET:
|
||||
return ctx.getString("city_type_hamlet");
|
||||
case TOWN:
|
||||
return ctx.getString("city_type_town");
|
||||
case VILLAGE:
|
||||
return ctx.getString("city_type_village");
|
||||
case SUBURB:
|
||||
return ctx.getString("city_type_suburb");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String getPoiStringWithoutType(Amenity amenity, String locale, boolean transliterate) {
|
||||
PoiCategory pc = amenity.getType();
|
||||
PoiType pt = pc.getPoiTypeByKeyName(amenity.getSubType());
|
||||
String nm = amenity.getSubType();
|
||||
if (pt != null) {
|
||||
nm = pt.getTranslation();
|
||||
} else if(nm != null){
|
||||
nm = Algorithms.capitalizeFirstLetterAndLowercase(nm.replace('_', ' '));
|
||||
}
|
||||
String n = amenity.getName(locale, transliterate);
|
||||
if (n.indexOf(nm) != -1) {
|
||||
// type is contained in name e.g.
|
||||
// n = "Bakery the Corner"
|
||||
// type = "Bakery"
|
||||
// no need to repeat this
|
||||
return n;
|
||||
}
|
||||
if (n.length() == 0) {
|
||||
return nm;
|
||||
}
|
||||
return nm + " " + n; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public static String getAmenityDescriptionContent(SampleApplication ctx, Amenity amenity, boolean shortDescription) {
|
||||
StringBuilder d = new StringBuilder();
|
||||
if(amenity.getType().isWiki()) {
|
||||
return "";
|
||||
}
|
||||
MapPoiTypes poiTypes = ctx.getPoiTypes();
|
||||
for(Entry<String, String> e : amenity.getAdditionalInfo().entrySet()) {
|
||||
String key = e.getKey();
|
||||
String vl = e.getValue();
|
||||
if(key.startsWith("name:")) {
|
||||
continue;
|
||||
} else if(vl.length() >= 150) {
|
||||
if(shortDescription) {
|
||||
continue;
|
||||
}
|
||||
} else if(Amenity.OPENING_HOURS.equals(key)) {
|
||||
d.append(ctx.getString("opening_hours") + ": ");
|
||||
} else if(Amenity.PHONE.equals(key)) {
|
||||
d.append(ctx.getString("phone") + ": ");
|
||||
} else if(Amenity.WEBSITE.equals(key)) {
|
||||
d.append(ctx.getString("website") + ": ");
|
||||
} else {
|
||||
AbstractPoiType pt = poiTypes.getAnyPoiAdditionalTypeByKey(e.getKey());
|
||||
if (pt != null) {
|
||||
if(pt instanceof PoiType && !((PoiType) pt).isText()) {
|
||||
vl = pt.getTranslation();
|
||||
} else {
|
||||
vl = pt.getTranslation() + ": " + amenity.unzipContent(e.getValue());
|
||||
}
|
||||
} else {
|
||||
vl = Algorithms.capitalizeFirstLetterAndLowercase(e.getKey()) +
|
||||
": " + amenity.unzipContent(e.getValue());
|
||||
}
|
||||
}
|
||||
d.append(vl).append('\n');
|
||||
}
|
||||
return d.toString().trim();
|
||||
}
|
||||
|
||||
public enum MetricsConstants {
|
||||
KILOMETERS_AND_METERS(R.string.si_km_m),
|
||||
MILES_AND_FEET(R.string.si_mi_feet),
|
||||
MILES_AND_METERS(R.string.si_mi_meters),
|
||||
MILES_AND_YARDS(R.string.si_mi_yard),
|
||||
NAUTICAL_MILES(R.string.si_nm);
|
||||
|
||||
private final int key;
|
||||
|
||||
MetricsConstants(int key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String toHumanString(Context ctx) {
|
||||
return ctx.getString(key);
|
||||
}
|
||||
}
|
||||
|
||||
public enum SpeedConstants {
|
||||
KILOMETERS_PER_HOUR(R.string.km_h, R.string.si_kmh),
|
||||
MILES_PER_HOUR(R.string.mile_per_hour, R.string.si_mph),
|
||||
METERS_PER_SECOND(R.string.m_s, R.string.si_m_s),
|
||||
MINUTES_PER_MILE(R.string.min_mile, R.string.si_min_m),
|
||||
MINUTES_PER_KILOMETER(R.string.min_km, R.string.si_min_km),
|
||||
NAUTICALMILES_PER_HOUR(R.string.nm_h, R.string.si_nm_h);
|
||||
|
||||
private final int key;
|
||||
private int descr;
|
||||
|
||||
SpeedConstants(int key, int descr) {
|
||||
this.key = key;
|
||||
this.descr = descr;
|
||||
}
|
||||
|
||||
public String toHumanString(Context ctx) {
|
||||
return ctx.getString(descr);
|
||||
}
|
||||
|
||||
public String toShortString(Context ctx) {
|
||||
return ctx.getString(key);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,571 @@
|
|||
package net.osmand.core.samples.android.sample1;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.GeomagneticField;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.location.GpsSatellite;
|
||||
import android.location.GpsStatus;
|
||||
import android.location.GpsStatus.Listener;
|
||||
import android.location.Location;
|
||||
import android.location.LocationListener;
|
||||
import android.location.LocationManager;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.util.Log;
|
||||
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class SampleLocationProvider implements SensorEventListener {
|
||||
|
||||
public interface SampleLocationListener {
|
||||
void updateLocation(net.osmand.Location location);
|
||||
}
|
||||
|
||||
public interface SampleCompassListener {
|
||||
void updateCompassValue(float value);
|
||||
}
|
||||
|
||||
private static final int INTERVAL_TO_CLEAR_SET_LOCATION = 30 * 1000;
|
||||
|
||||
private static final int GPS_TIMEOUT_REQUEST = 0;
|
||||
private static final int GPS_DIST_REQUEST = 0;
|
||||
private static final int NOT_SWITCH_TO_NETWORK_WHEN_GPS_LOST_MS = 12000;
|
||||
|
||||
private long lastTimeGPSLocationFixed = 0;
|
||||
private boolean gpsSignalLost;
|
||||
|
||||
private boolean sensorRegistered = false;
|
||||
private float[] mGravs = new float[3];
|
||||
private float[] mGeoMags = new float[3];
|
||||
private float previousCorrectionValue = 360;
|
||||
|
||||
float avgValSin = 0;
|
||||
float avgValCos = 0;
|
||||
float lastValSin = 0;
|
||||
float lastValCos = 0;
|
||||
private float[] previousCompassValuesA = new float[50];
|
||||
private float[] previousCompassValuesB = new float[50];
|
||||
private int previousCompassIndA = 0;
|
||||
private int previousCompassIndB = 0;
|
||||
private boolean inUpdateValue = false;
|
||||
|
||||
private Float heading = null;
|
||||
|
||||
// Current screen orientation
|
||||
private int currentScreenOrientation;
|
||||
|
||||
private SampleApplication app;
|
||||
//private CurrentPositionHelper currentPositionHelper;
|
||||
|
||||
private net.osmand.Location location = null;
|
||||
|
||||
private GPSInfo gpsInfo = new GPSInfo();
|
||||
|
||||
private List<SampleLocationListener> locationListeners = new ArrayList<>();
|
||||
private List<SampleCompassListener> compassListeners = new ArrayList<>();
|
||||
private Listener gpsStatusListener;
|
||||
private float[] mRotationM = new float[9];
|
||||
private static final long AGPS_TO_REDOWNLOAD = 16 * 60 * 60 * 1000; // 16 hours
|
||||
private long agpsDataLastTimeDownloaded;
|
||||
private boolean useMagneticFieldSensorCompass = false;
|
||||
|
||||
public SampleLocationProvider(SampleApplication app) {
|
||||
this.app = app;
|
||||
//currentPositionHelper = new CurrentPositionHelper(app);
|
||||
}
|
||||
|
||||
public void resumeAllUpdates() {
|
||||
final LocationManager service = (LocationManager) app.getSystemService(Context.LOCATION_SERVICE);
|
||||
if (app.isInternetConnectionAvailable()) {
|
||||
if (System.currentTimeMillis() - agpsDataLastTimeDownloaded > AGPS_TO_REDOWNLOAD) {
|
||||
//force an updated check for internet connectivity here before destroying A-GPS-data
|
||||
if (app.isInternetConnectionAvailable(true)) {
|
||||
redownloadAGPS();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isLocationPermissionAvailable(app)) {
|
||||
service.addGpsStatusListener(getGpsStatusListener(service));
|
||||
try {
|
||||
service.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, gpsListener);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.d(PlatformUtil.TAG, "GPS location provider not available"); //$NON-NLS-1$
|
||||
}
|
||||
// try to always ask for network provide : it is faster way to find location
|
||||
|
||||
List<String> providers = service.getProviders(true);
|
||||
if (providers == null) {
|
||||
return;
|
||||
}
|
||||
for (String provider : providers) {
|
||||
if (provider == null || provider.equals(LocationManager.GPS_PROVIDER)) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
NetworkListener networkListener = new NetworkListener();
|
||||
service.requestLocationUpdates(provider, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, networkListener);
|
||||
networkListeners.add(networkListener);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.d(PlatformUtil.TAG, provider + " location provider not available"); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void redownloadAGPS() {
|
||||
try {
|
||||
final LocationManager service = (LocationManager) app.getSystemService(Context.LOCATION_SERVICE);
|
||||
service.sendExtraCommand(LocationManager.GPS_PROVIDER, "delete_aiding_data", null);
|
||||
Bundle bundle = new Bundle();
|
||||
service.sendExtraCommand("gps", "force_xtra_injection", bundle);
|
||||
service.sendExtraCommand("gps", "force_time_injection", bundle);
|
||||
agpsDataLastTimeDownloaded = System.currentTimeMillis();
|
||||
} catch (Exception e) {
|
||||
agpsDataLastTimeDownloaded = 0L;
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private Listener getGpsStatusListener(final LocationManager service) {
|
||||
gpsStatusListener = new Listener() {
|
||||
private GpsStatus gpsStatus;
|
||||
|
||||
@Override
|
||||
public void onGpsStatusChanged(int event) {
|
||||
gpsStatus = service.getGpsStatus(gpsStatus);
|
||||
updateGPSInfo(gpsStatus);
|
||||
updateLocation(location);
|
||||
}
|
||||
};
|
||||
return gpsStatusListener;
|
||||
}
|
||||
|
||||
private void updateGPSInfo(GpsStatus s) {
|
||||
boolean fixed = false;
|
||||
int n = 0;
|
||||
int u = 0;
|
||||
if (s != null) {
|
||||
Iterator<GpsSatellite> iterator = s.getSatellites().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
GpsSatellite g = iterator.next();
|
||||
n++;
|
||||
if (g.usedInFix()) {
|
||||
u++;
|
||||
fixed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
gpsInfo.fixed = fixed;
|
||||
gpsInfo.foundSatellites = n;
|
||||
gpsInfo.usedSatellites = u;
|
||||
}
|
||||
|
||||
public GPSInfo getGPSInfo() {
|
||||
return gpsInfo;
|
||||
}
|
||||
|
||||
public void updateScreenOrientation(int orientation) {
|
||||
currentScreenOrientation = orientation;
|
||||
}
|
||||
|
||||
public void addLocationListener(SampleLocationListener listener) {
|
||||
if (!locationListeners.contains(listener)) {
|
||||
locationListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeLocationListener(SampleLocationListener listener) {
|
||||
locationListeners.remove(listener);
|
||||
}
|
||||
|
||||
public void addCompassListener(SampleCompassListener listener) {
|
||||
if (!compassListeners.contains(listener)) {
|
||||
compassListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeCompassListener(SampleCompassListener listener) {
|
||||
compassListeners.remove(listener);
|
||||
}
|
||||
|
||||
public net.osmand.Location getFirstTimeRunDefaultLocation() {
|
||||
if (!isLocationPermissionAvailable(app)) {
|
||||
return null;
|
||||
}
|
||||
LocationManager service = (LocationManager) app.getSystemService(Context.LOCATION_SERVICE);
|
||||
List<String> ps = service.getProviders(true);
|
||||
if (ps == null) {
|
||||
return null;
|
||||
}
|
||||
List<String> providers = new ArrayList<String>(ps);
|
||||
// note, passive provider is from API_LEVEL 8 but it is a constant, we can check for it.
|
||||
// constant should not be changed in future
|
||||
int passiveFirst = providers.indexOf("passive"); // LocationManager.PASSIVE_PROVIDER
|
||||
// put passive provider to first place
|
||||
if (passiveFirst > -1) {
|
||||
providers.add(0, providers.remove(passiveFirst));
|
||||
}
|
||||
// find location
|
||||
for (String provider : providers) {
|
||||
net.osmand.Location location = convertLocation(service.getLastKnownLocation(provider), app);
|
||||
if (location != null) {
|
||||
return location;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public synchronized void registerOrUnregisterCompassListener(boolean register) {
|
||||
if (sensorRegistered && !register) {
|
||||
Log.d(PlatformUtil.TAG, "Disable sensor"); //$NON-NLS-1$
|
||||
((SensorManager) app.getSystemService(Context.SENSOR_SERVICE)).unregisterListener(this);
|
||||
sensorRegistered = false;
|
||||
heading = null;
|
||||
} else if (!sensorRegistered && register) {
|
||||
Log.d(PlatformUtil.TAG, "Enable sensor"); //$NON-NLS-1$
|
||||
SensorManager sensorMgr = (SensorManager) app.getSystemService(Context.SENSOR_SERVICE);
|
||||
if (useMagneticFieldSensorCompass) {
|
||||
Sensor s = sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
||||
if (s == null || !sensorMgr.registerListener(this, s, SensorManager.SENSOR_DELAY_UI)) {
|
||||
Log.e(PlatformUtil.TAG, "Sensor accelerometer could not be enabled");
|
||||
}
|
||||
s = sensorMgr.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
|
||||
if (s == null || !sensorMgr.registerListener(this, s, SensorManager.SENSOR_DELAY_UI)) {
|
||||
Log.e(PlatformUtil.TAG, "Sensor magnetic field could not be enabled");
|
||||
}
|
||||
} else {
|
||||
Sensor s = sensorMgr.getDefaultSensor(Sensor.TYPE_ORIENTATION);
|
||||
if (s == null || !sensorMgr.registerListener(this, s, SensorManager.SENSOR_DELAY_UI)) {
|
||||
Log.e(PlatformUtil.TAG, "Sensor orientation could not be enabled");
|
||||
}
|
||||
}
|
||||
sensorRegistered = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
// Attention : sensor produces a lot of events & can hang the system
|
||||
if (inUpdateValue) {
|
||||
return;
|
||||
}
|
||||
synchronized (this) {
|
||||
if (!sensorRegistered) {
|
||||
return;
|
||||
}
|
||||
inUpdateValue = true;
|
||||
try {
|
||||
float val = 0;
|
||||
switch (event.sensor.getType()) {
|
||||
case Sensor.TYPE_ACCELEROMETER:
|
||||
System.arraycopy(event.values, 0, mGravs, 0, 3);
|
||||
break;
|
||||
case Sensor.TYPE_MAGNETIC_FIELD:
|
||||
System.arraycopy(event.values, 0, mGeoMags, 0, 3);
|
||||
break;
|
||||
case Sensor.TYPE_ORIENTATION:
|
||||
val = event.values[0];
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
if (useMagneticFieldSensorCompass) {
|
||||
if (mGravs != null && mGeoMags != null) {
|
||||
boolean success = SensorManager.getRotationMatrix(mRotationM, null, mGravs, mGeoMags);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
float[] orientation = SensorManager.getOrientation(mRotationM, new float[3]);
|
||||
val = (float) Math.toDegrees(orientation[0]);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
val = calcScreenOrientationCorrection(val);
|
||||
val = calcGeoMagneticCorrection(val);
|
||||
|
||||
float valRad = (float) (val / 180f * Math.PI);
|
||||
lastValSin = (float) Math.sin(valRad);
|
||||
lastValCos = (float) Math.cos(valRad);
|
||||
|
||||
avgValSin = lastValSin;
|
||||
avgValCos = lastValCos;
|
||||
|
||||
updateCompassVal();
|
||||
} finally {
|
||||
inUpdateValue = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float calcGeoMagneticCorrection(float val) {
|
||||
if (previousCorrectionValue == 360 && getLastKnownLocation() != null) {
|
||||
net.osmand.Location l = getLastKnownLocation();
|
||||
GeomagneticField gf = new GeomagneticField((float) l.getLatitude(), (float) l.getLongitude(), (float) l.getAltitude(),
|
||||
System.currentTimeMillis());
|
||||
previousCorrectionValue = gf.getDeclination();
|
||||
}
|
||||
if (previousCorrectionValue != 360) {
|
||||
val += previousCorrectionValue;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
private float calcScreenOrientationCorrection(float val) {
|
||||
if (currentScreenOrientation == 1) {
|
||||
val += 90;
|
||||
} else if (currentScreenOrientation == 2) {
|
||||
val += 180;
|
||||
} else if (currentScreenOrientation == 3) {
|
||||
val -= 90;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
private void filterCompassValue() {
|
||||
if (heading == null && previousCompassIndA == 0) {
|
||||
Arrays.fill(previousCompassValuesA, lastValSin);
|
||||
Arrays.fill(previousCompassValuesB, lastValCos);
|
||||
avgValSin = lastValSin;
|
||||
avgValCos = lastValCos;
|
||||
} else {
|
||||
int l = previousCompassValuesA.length;
|
||||
previousCompassIndA = (previousCompassIndA + 1) % l;
|
||||
previousCompassIndB = (previousCompassIndB + 1) % l;
|
||||
// update average
|
||||
avgValSin = avgValSin + (-previousCompassValuesA[previousCompassIndA] + lastValSin) / l;
|
||||
previousCompassValuesA[previousCompassIndA] = lastValSin;
|
||||
avgValCos = avgValCos + (-previousCompassValuesB[previousCompassIndB] + lastValCos) / l;
|
||||
previousCompassValuesB[previousCompassIndB] = lastValCos;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCompassVal() {
|
||||
heading = getAngle(avgValSin, avgValCos);
|
||||
for (SampleCompassListener c : compassListeners) {
|
||||
c.updateCompassValue(heading);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized Float getHeading() {
|
||||
// if (heading != null && lastValSin != avgValSin && System.currentTimeMillis() - lastHeadingCalcTime > 700) {
|
||||
// avgValSin = lastValSin;
|
||||
// avgValCos = lastValCos;
|
||||
// Arrays.fill(previousCompassValuesA, avgValSin);
|
||||
// Arrays.fill(previousCompassValuesB, avgValCos);
|
||||
// updateCompassVal();
|
||||
// }
|
||||
return heading;
|
||||
}
|
||||
|
||||
private float getAngle(float sinA, float cosA) {
|
||||
return MapUtils.unifyRotationTo360((float) (Math.atan2(sinA, cosA) * 180 / Math.PI));
|
||||
}
|
||||
|
||||
|
||||
private void updateLocation(net.osmand.Location loc) {
|
||||
for (SampleLocationListener l : locationListeners) {
|
||||
l.updateLocation(loc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private LocationListener gpsListener = new LocationListener() {
|
||||
@Override
|
||||
public void onLocationChanged(Location location) {
|
||||
if (location != null) {
|
||||
lastTimeGPSLocationFixed = location.getTime();
|
||||
}
|
||||
setLocation(convertLocation(location, app));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderDisabled(String provider) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderEnabled(String provider) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(String provider, int status, Bundle extras) {
|
||||
}
|
||||
};
|
||||
private LinkedList<LocationListener> networkListeners = new LinkedList<LocationListener>();
|
||||
|
||||
private boolean useOnlyGPS() {
|
||||
if ((System.currentTimeMillis() - lastTimeGPSLocationFixed) < NOT_SWITCH_TO_NETWORK_WHEN_GPS_LOST_MS) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Working with location checkListeners
|
||||
private class NetworkListener implements LocationListener {
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(Location location) {
|
||||
if (!useOnlyGPS()) {
|
||||
setLocation(convertLocation(location, app));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderDisabled(String provider) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderEnabled(String provider) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(String provider, int status, Bundle extras) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
private void stopLocationRequests() {
|
||||
LocationManager service = (LocationManager) app.getSystemService(Context.LOCATION_SERVICE);
|
||||
service.removeGpsStatusListener(gpsStatusListener);
|
||||
service.removeUpdates(gpsListener);
|
||||
while (!networkListeners.isEmpty()) {
|
||||
service.removeUpdates(networkListeners.poll());
|
||||
}
|
||||
}
|
||||
|
||||
public void pauseAllUpdates() {
|
||||
stopLocationRequests();
|
||||
registerOrUnregisterCompassListener(false);
|
||||
}
|
||||
|
||||
public static net.osmand.Location convertLocation(Location l, SampleApplication app) {
|
||||
if (l == null) {
|
||||
return null;
|
||||
}
|
||||
net.osmand.Location r = new net.osmand.Location(l.getProvider());
|
||||
r.setLatitude(l.getLatitude());
|
||||
r.setLongitude(l.getLongitude());
|
||||
r.setTime(l.getTime());
|
||||
if (l.hasAccuracy()) {
|
||||
r.setAccuracy(l.getAccuracy());
|
||||
}
|
||||
if (l.hasSpeed()) {
|
||||
r.setSpeed(l.getSpeed());
|
||||
}
|
||||
if (l.hasAltitude()) {
|
||||
r.setAltitude(l.getAltitude());
|
||||
}
|
||||
if (l.hasBearing()) {
|
||||
r.setBearing(l.getBearing());
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
private void setLocation(net.osmand.Location location) {
|
||||
if (location == null) {
|
||||
updateGPSInfo(null);
|
||||
}
|
||||
if (location != null) {
|
||||
if (gpsSignalLost) {
|
||||
gpsSignalLost = false;
|
||||
}
|
||||
}
|
||||
this.location = location;
|
||||
|
||||
// Update information
|
||||
updateLocation(this.location);
|
||||
}
|
||||
|
||||
public void checkIfLastKnownLocationIsValid() {
|
||||
net.osmand.Location loc = getLastKnownLocation();
|
||||
if (loc != null && (System.currentTimeMillis() - loc.getTime()) > INTERVAL_TO_CLEAR_SET_LOCATION) {
|
||||
setLocation(null);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public RouteDataObject getLastKnownRouteSegment() {
|
||||
return currentPositionHelper.getLastKnownRouteSegment(getLastKnownLocation());
|
||||
}
|
||||
|
||||
public boolean getRouteSegment(net.osmand.Location loc, ResultMatcher<RouteDataObject> result) {
|
||||
return currentPositionHelper.getRouteSegment(loc, result);
|
||||
}
|
||||
|
||||
public boolean getGeocodingResult(net.osmand.Location loc, ResultMatcher<GeocodingResult> result) {
|
||||
return currentPositionHelper.getGeocodingResult(loc, result);
|
||||
}
|
||||
*/
|
||||
|
||||
public net.osmand.Location getLastKnownLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
|
||||
public static class GPSInfo {
|
||||
public int foundSatellites = 0;
|
||||
public int usedSatellites = 0;
|
||||
public boolean fixed = false;
|
||||
}
|
||||
|
||||
|
||||
public boolean checkGPSEnabled(final Context context) {
|
||||
LocationManager lm = (LocationManager) app.getSystemService(Context.LOCATION_SERVICE);
|
||||
boolean gpsenabled = false;
|
||||
boolean networkenabled = false;
|
||||
|
||||
try {
|
||||
gpsenabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
|
||||
try {
|
||||
networkenabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
|
||||
if (!gpsenabled && !networkenabled) {
|
||||
// notify user
|
||||
AlertDialog.Builder dialog = new AlertDialog.Builder(context);
|
||||
dialog.setMessage(app.getString("gps_network_not_enabled"));
|
||||
dialog.setPositiveButton(app.getString("shared_string_settings"), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
|
||||
Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
|
||||
context.startActivity(myIntent);
|
||||
}
|
||||
});
|
||||
dialog.setNegativeButton(context.getString(R.string.shared_string_cancel), null);
|
||||
dialog.show();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isLocationPermissionAvailable(Context context) {
|
||||
return ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)
|
||||
== PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
}
|
|
@ -1,13 +1,22 @@
|
|||
package net.osmand.core.samples.android.sample1;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorManager;
|
||||
import android.view.WindowManager;
|
||||
|
||||
public class SampleUtils {
|
||||
|
||||
private static final int ORIENTATION_0 = 0;
|
||||
private static final int ORIENTATION_90 = 3;
|
||||
private static final int ORIENTATION_270 = 1;
|
||||
private static final int ORIENTATION_180 = 2;
|
||||
|
||||
public static void doRestart(Context c) {
|
||||
boolean res = false;
|
||||
try {
|
||||
|
@ -59,4 +68,28 @@ public class SampleUtils {
|
|||
}
|
||||
return installed;
|
||||
}
|
||||
|
||||
public static int getScreenOrientation(Activity a) {
|
||||
int screenOrientation = ((WindowManager) a.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
|
||||
switch (screenOrientation) {
|
||||
case ORIENTATION_0: // Device default (normally portrait)
|
||||
screenOrientation = 0;
|
||||
break;
|
||||
case ORIENTATION_90: // Landscape right
|
||||
screenOrientation = 90;
|
||||
break;
|
||||
case ORIENTATION_270: // Landscape left
|
||||
screenOrientation = 270;
|
||||
break;
|
||||
case ORIENTATION_180: // Upside down
|
||||
screenOrientation = 180;
|
||||
break;
|
||||
}
|
||||
//Looks like screenOrientation correction must not be applied for devices without compass?
|
||||
Sensor compass = ((SensorManager) a.getSystemService(Context.SENSOR_SERVICE)).getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
|
||||
if (compass == null) {
|
||||
screenOrientation = 0;
|
||||
}
|
||||
return screenOrientation;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,114 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.R;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.search.core.SearchResult;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.List;
|
||||
|
||||
public class SearchListAdapter extends ArrayAdapter<SearchListItem> {
|
||||
|
||||
private Context ctx;
|
||||
private LatLon location;
|
||||
|
||||
public SearchListAdapter(Context ctx) {
|
||||
super(ctx, R.layout.search_list_item);
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
public void setListItems(List<SearchListItem> items) {
|
||||
setNotifyOnChange(false);
|
||||
clear();
|
||||
for (SearchListItem item : items) {
|
||||
add(item);
|
||||
}
|
||||
setNotifyOnChange(true);
|
||||
notifyDataSetInvalidated();
|
||||
}
|
||||
|
||||
public LatLon getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(LatLon location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchListItem getItem(int position) {
|
||||
return super.getItem(position);
|
||||
}
|
||||
|
||||
public void updateDistance(double latitude, double longitude) {
|
||||
/*
|
||||
for (int i = 0; i < getCount(); i++) {
|
||||
SearchListItem item = getItem(i);
|
||||
if (item instanceof SearchListPositionItem) {
|
||||
SearchListPositionItem positionItem = (SearchListPositionItem) item;
|
||||
positionItem.setDistance(Utilities.distance(
|
||||
longitude, latitude, positionItem.getLongitude(), positionItem.getLatitude()));
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
SearchListItem listItem = getItem(position);
|
||||
|
||||
LinearLayout view;
|
||||
if (convertView == null) {
|
||||
LayoutInflater inflater = (LayoutInflater) ctx
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
view = (LinearLayout) inflater.inflate(
|
||||
R.layout.search_list_item, null);
|
||||
} else {
|
||||
view = (LinearLayout) convertView;
|
||||
}
|
||||
|
||||
ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
|
||||
TextView title = (TextView) view.findViewById(R.id.title);
|
||||
TextView subtitle = (TextView) view.findViewById(R.id.subtitle);
|
||||
TextView distance = (TextView) view.findViewById(R.id.distance);
|
||||
|
||||
imageView.setImageDrawable(listItem.getIcon());
|
||||
title.setText(listItem.getName());
|
||||
subtitle.setText(listItem.getTypeName());
|
||||
if (location != null && listItem.getSearchResult().location != null) {
|
||||
double dist = listItem.getDistance();
|
||||
if (dist == 0) {
|
||||
distance.setText("");
|
||||
} else {
|
||||
distance.setText(getFormattedDistance(dist));
|
||||
}
|
||||
distance.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
distance.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
public static String getFormattedDistance(double meters) {
|
||||
double mainUnitInMeters = 1000;
|
||||
String mainUnitStr = "km";
|
||||
if (meters >= 100 * mainUnitInMeters) {
|
||||
return (int) (meters / mainUnitInMeters + 0.5) + " " + mainUnitStr;
|
||||
} else if (meters > 9.99f * mainUnitInMeters) {
|
||||
return MessageFormat.format("{0,number,#.#} " + mainUnitStr, ((float) meters) / mainUnitInMeters).replace('\n', ' ');
|
||||
} else if (meters > 0.999f * mainUnitInMeters) {
|
||||
return MessageFormat.format("{0,number,#.##} " + mainUnitStr, ((float) meters) / mainUnitInMeters).replace('\n', ' ');
|
||||
} else {
|
||||
return ((int) (meters + 0.5)) + " m";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,152 +0,0 @@
|
|||
package net.osmand.core.samples.android.sample1.adapters;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.City;
|
||||
import net.osmand.data.Street;
|
||||
import net.osmand.osm.AbstractPoiType;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.osm.PoiFilter;
|
||||
import net.osmand.osm.PoiType;
|
||||
import net.osmand.search.core.SearchResult;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
public class SearchListItem {
|
||||
|
||||
protected SampleApplication app;
|
||||
private SearchResult searchResult;
|
||||
private double distance;
|
||||
|
||||
public SearchListItem(SampleApplication app, SearchResult searchResult) {
|
||||
this.app = app;
|
||||
this.searchResult = searchResult;
|
||||
}
|
||||
|
||||
public SearchResult getSearchResult() {
|
||||
return searchResult;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return searchResult.localeName;
|
||||
}
|
||||
|
||||
public String getTypeName() {
|
||||
switch (searchResult.objectType) {
|
||||
case CITY:
|
||||
case POSTCODE:
|
||||
City city = (City) searchResult.object;
|
||||
return Algorithms.capitalizeFirstLetterAndLowercase(city.getType().toString());
|
||||
case VILLAGE:
|
||||
city = (City) searchResult.object;
|
||||
if (!Algorithms.isEmpty(searchResult.localeRelatedObjectName)) {
|
||||
return Algorithms.capitalizeFirstLetterAndLowercase(city.getType().toString())
|
||||
+ " near "
|
||||
+ searchResult.localeRelatedObjectName
|
||||
+ (searchResult.distRelatedObjectName > 0 ? " (" + SearchListAdapter.getFormattedDistance(searchResult.distRelatedObjectName) + ")" : "");
|
||||
} else {
|
||||
return Algorithms.capitalizeFirstLetterAndLowercase(city.getType().toString());
|
||||
}
|
||||
case STREET:
|
||||
Street street = (Street) searchResult.object;
|
||||
City streetCity = street.getCity();
|
||||
if (!Algorithms.isEmpty(searchResult.localeRelatedObjectName)) {
|
||||
return searchResult.localeRelatedObjectName
|
||||
+ (searchResult.distRelatedObjectName > 0 ? "(" + SearchListAdapter.getFormattedDistance(searchResult.distRelatedObjectName) + ")" : "");
|
||||
} else {
|
||||
return streetCity.getName() + " - " + Algorithms.capitalizeFirstLetterAndLowercase(streetCity.getType().name());
|
||||
}
|
||||
case HOUSE:
|
||||
return "House";
|
||||
case STREET_INTERSECTION:
|
||||
return "Street intersection";
|
||||
case POI_TYPE:
|
||||
AbstractPoiType abstractPoiType = (AbstractPoiType) searchResult.object;
|
||||
String res;
|
||||
if (abstractPoiType instanceof PoiCategory) {
|
||||
res = "POI category";
|
||||
} else if (abstractPoiType instanceof PoiFilter) {
|
||||
PoiFilter poiFilter = (PoiFilter) abstractPoiType;
|
||||
res = poiFilter.getPoiCategory() != null ? poiFilter.getPoiCategory().getTranslation() : "POI filter";
|
||||
|
||||
} else if (abstractPoiType instanceof PoiType) {
|
||||
PoiType poiType = (PoiType) abstractPoiType;
|
||||
res = poiType.getParentType() != null ? poiType.getParentType().getTranslation() : null;
|
||||
if (res == null) {
|
||||
res = poiType.getCategory() != null ? poiType.getCategory().getTranslation() : null;
|
||||
}
|
||||
if (res == null) {
|
||||
res = "POI type";
|
||||
}
|
||||
} else {
|
||||
res = "POI type";
|
||||
}
|
||||
return res;
|
||||
case POI:
|
||||
Amenity amenity = (Amenity) searchResult.object;
|
||||
return amenity.getType().toString();
|
||||
case LOCATION:
|
||||
break;
|
||||
case FAVORITE:
|
||||
break;
|
||||
case REGION:
|
||||
break;
|
||||
case RECENT_OBJ:
|
||||
break;
|
||||
case WPT:
|
||||
break;
|
||||
case UNKNOWN_NAME_FILTER:
|
||||
break;
|
||||
}
|
||||
return searchResult.objectType.name();
|
||||
}
|
||||
|
||||
public Drawable getIcon() {
|
||||
switch (searchResult.objectType) {
|
||||
case CITY:
|
||||
break;
|
||||
case VILLAGE:
|
||||
break;
|
||||
case POSTCODE:
|
||||
break;
|
||||
case STREET:
|
||||
break;
|
||||
case HOUSE:
|
||||
break;
|
||||
case STREET_INTERSECTION:
|
||||
break;
|
||||
case POI_TYPE:
|
||||
break;
|
||||
case POI:
|
||||
Amenity amenity = (Amenity) searchResult.object;
|
||||
Drawable drawable = null;
|
||||
PoiType st = amenity.getType().getPoiTypeByKeyName(amenity.getSubType());
|
||||
if (st != null) {
|
||||
drawable = app.getIconsCache().getMapIcon(st.getOsmTag() + "_" + st.getOsmValue());
|
||||
}
|
||||
return drawable;
|
||||
case LOCATION:
|
||||
break;
|
||||
case FAVORITE:
|
||||
break;
|
||||
case REGION:
|
||||
break;
|
||||
case RECENT_OBJ:
|
||||
break;
|
||||
case WPT:
|
||||
break;
|
||||
case UNKNOWN_NAME_FILTER:
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public double getDistance() {
|
||||
return distance;
|
||||
}
|
||||
|
||||
public void setDistance(double distance) {
|
||||
this.distance = distance;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package net.osmand.core.samples.android.sample1.customcontrols;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.Button;
|
||||
|
||||
public class OsmandButton extends Button {
|
||||
|
||||
public OsmandButton(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public OsmandButton(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
OsmandTextView.parseAttributes(this, attrs, 0, 0);
|
||||
}
|
||||
|
||||
public OsmandButton(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
OsmandTextView.parseAttributes(this, attrs, defStyleAttr, 0);
|
||||
}
|
||||
|
||||
@TargetApi(21)
|
||||
public OsmandButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
OsmandTextView.parseAttributes(this, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package net.osmand.core.samples.android.sample1.customcontrols;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.ImageButton;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.OsmandResources;
|
||||
import net.osmand.core.samples.android.sample1.R;
|
||||
|
||||
|
||||
public class OsmandImageButton extends ImageButton {
|
||||
|
||||
public OsmandImageButton(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public OsmandImageButton(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
parseAttributes(this, attrs, 0, 0);
|
||||
}
|
||||
|
||||
public OsmandImageButton(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
parseAttributes(this, attrs, defStyleAttr, 0);
|
||||
}
|
||||
|
||||
@TargetApi(21)
|
||||
public OsmandImageButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
parseAttributes(this, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
static void parseAttributes(ImageButton target, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
if (attrs == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
TypedArray resolvedAttrs = target.getContext().getTheme().obtainStyledAttributes(attrs,
|
||||
R.styleable.OsmandButton, defStyleAttr, defStyleRes);
|
||||
applyAttributes(resolvedAttrs, target);
|
||||
resolvedAttrs.recycle();
|
||||
}
|
||||
|
||||
private static void applyAttributes(TypedArray resolvedAttributes, ImageButton target) {
|
||||
applyAttribute_osmandSrc(resolvedAttributes, target);
|
||||
}
|
||||
|
||||
static void applyAttribute_osmandSrc(TypedArray resolvedAttributes, ImageButton target) {
|
||||
if (!resolvedAttributes.hasValue(R.styleable.OsmandImageButton_osmandSrc)
|
||||
|| target.isInEditMode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String osmandSrc = resolvedAttributes.getString(R.styleable.OsmandImageButton_osmandSrc);
|
||||
target.setImageDrawable(OsmandResources.getDrawable(osmandSrc));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package net.osmand.core.samples.android.sample1.customcontrols;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.OsmandResources;
|
||||
import net.osmand.core.samples.android.sample1.R;
|
||||
|
||||
public class OsmandImageView extends ImageView {
|
||||
public OsmandImageView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public OsmandImageView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
parseAttributes(this, attrs, 0, 0);
|
||||
}
|
||||
|
||||
public OsmandImageView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
parseAttributes(this, attrs, defStyleAttr, 0);
|
||||
}
|
||||
|
||||
@TargetApi(21)
|
||||
public OsmandImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
parseAttributes(this, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
static void parseAttributes(ImageView target, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
if (attrs == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
TypedArray resolvedAttrs = target.getContext().getTheme().obtainStyledAttributes(attrs,
|
||||
R.styleable.OsmandButton, defStyleAttr, defStyleRes);
|
||||
applyAttributes(resolvedAttrs, target);
|
||||
resolvedAttrs.recycle();
|
||||
}
|
||||
|
||||
private static void applyAttributes(TypedArray resolvedAttributes, ImageView target) {
|
||||
applyAttribute_osmandSrc(resolvedAttributes, target);
|
||||
}
|
||||
|
||||
static void applyAttribute_osmandSrc(TypedArray resolvedAttributes, ImageView target) {
|
||||
if (!resolvedAttributes.hasValue(R.styleable.OsmandImageButton_osmandSrc)
|
||||
|| target.isInEditMode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String osmandSrc = resolvedAttributes.getString(R.styleable.OsmandImageButton_osmandSrc);
|
||||
target.setImageDrawable(OsmandResources.getDrawable(osmandSrc));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package net.osmand.core.samples.android.sample1.customcontrols;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.OsmandResources;
|
||||
import net.osmand.core.samples.android.sample1.R;
|
||||
|
||||
public class OsmandTextView extends TextView {
|
||||
|
||||
public OsmandTextView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public OsmandTextView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
parseAttributes(this, attrs, 0, 0);
|
||||
}
|
||||
|
||||
public OsmandTextView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
parseAttributes(this, attrs, defStyleAttr, 0);
|
||||
}
|
||||
|
||||
@TargetApi(21)
|
||||
public OsmandTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
parseAttributes(this, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
static void parseAttributes(TextView target, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
if (attrs == null) {
|
||||
return;
|
||||
}
|
||||
TypedArray resolvedAttrs = target.getContext().getTheme().obtainStyledAttributes(attrs,
|
||||
R.styleable.OsmandTextView, defStyleAttr, defStyleRes);
|
||||
applyAttributes(resolvedAttrs, target);
|
||||
resolvedAttrs.recycle();
|
||||
}
|
||||
|
||||
private static void applyAttributes(TypedArray resolvedAttributes, TextView target) {
|
||||
applyAttribute_osmandText(resolvedAttributes, target);
|
||||
}
|
||||
|
||||
static void applyAttribute_osmandText(TypedArray resolvedAttributes, TextView target) {
|
||||
if (!resolvedAttributes.hasValue(R.styleable.OsmandTextView_osmandText)
|
||||
|| target.isInEditMode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String osmandText = resolvedAttributes.getString(R.styleable.OsmandTextView_osmandText);
|
||||
target.setText(OsmandResources.getString(osmandText));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package net.osmand.core.samples.android.sample1.data;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
public interface LocationPoint {
|
||||
|
||||
public double getLatitude();
|
||||
|
||||
public double getLongitude();
|
||||
|
||||
public int getColor();
|
||||
|
||||
public boolean isVisible();
|
||||
|
||||
public PointDescription getPointDescription(Context ctx);
|
||||
|
||||
// public String getSpeakableName();
|
||||
|
||||
//public void prepareCommandPlayer(CommandBuilder cmd, String names);
|
||||
|
||||
}
|
|
@ -0,0 +1,357 @@
|
|||
package net.osmand.core.samples.android.sample1.data;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.jwetherell.openmap.common.LatLonPoint;
|
||||
import com.jwetherell.openmap.common.UTMPoint;
|
||||
|
||||
import net.osmand.LocationConvert;
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
public class PointDescription {
|
||||
private String type = "";
|
||||
private String name = "";
|
||||
private String typeName;
|
||||
private String iconName;
|
||||
|
||||
private double lat = 0;
|
||||
private double lon = 0;
|
||||
|
||||
public static final String POINT_TYPE_FAVORITE = "favorite";
|
||||
public static final String POINT_TYPE_WPT = "wpt";
|
||||
public static final String POINT_TYPE_POI = "poi";
|
||||
public static final String POINT_TYPE_ADDRESS = "address";
|
||||
public static final String POINT_TYPE_OSM_NOTE= "osm_note";
|
||||
public static final String POINT_TYPE_MARKER = "marker";
|
||||
public static final String POINT_TYPE_PARKING_MARKER = "parking_marker";
|
||||
public static final String POINT_TYPE_AUDIO_NOTE = "audionote";
|
||||
public static final String POINT_TYPE_VIDEO_NOTE = "videonote";
|
||||
public static final String POINT_TYPE_PHOTO_NOTE = "photonote";
|
||||
public static final String POINT_TYPE_LOCATION = "location";
|
||||
public static final String POINT_TYPE_MY_LOCATION = "my_location";
|
||||
public static final String POINT_TYPE_ALARM = "alarm";
|
||||
public static final String POINT_TYPE_TARGET = "destination";
|
||||
public static final String POINT_TYPE_MAP_MARKER = "map_marker";
|
||||
public static final String POINT_TYPE_OSM_BUG = "bug";
|
||||
public static final String POINT_TYPE_WORLD_REGION = "world_region";
|
||||
public static final String POINT_TYPE_GPX_ITEM = "gpx_item";
|
||||
public static final String POINT_TYPE_WORLD_REGION_SHOW_ON_MAP = "world_region_show_on_map";
|
||||
public static final String POINT_TYPE_BLOCKED_ROAD = "blocked_road";
|
||||
public static final String POINT_TYPE_TRANSPORT_ROUTE = "transport_route";
|
||||
public static final String POINT_TYPE_TRANSPORT_STOP = "transport_stop";
|
||||
|
||||
|
||||
public static final PointDescription LOCATION_POINT = new PointDescription(POINT_TYPE_LOCATION, "");
|
||||
|
||||
public PointDescription(double lat, double lon) {
|
||||
this(POINT_TYPE_LOCATION, "");
|
||||
this.lat = lat;
|
||||
this.lon = lon;
|
||||
}
|
||||
|
||||
public PointDescription(String type, String name) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
if (this.name == null) {
|
||||
this.name = "";
|
||||
}
|
||||
}
|
||||
|
||||
public PointDescription(String type, String typeName, String name) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.typeName = typeName;
|
||||
if (this.name == null) {
|
||||
this.name = "";
|
||||
}
|
||||
}
|
||||
|
||||
public void setLat(double lat) {
|
||||
this.lat = lat;
|
||||
}
|
||||
|
||||
public void setLon(double lon) {
|
||||
this.lon = lon;
|
||||
}
|
||||
|
||||
public void setTypeName(String typeName){
|
||||
this.typeName = typeName;
|
||||
}
|
||||
|
||||
public void setName(String name){
|
||||
this.name = name;
|
||||
if (this.name == null) {
|
||||
this.name = "";
|
||||
}
|
||||
}
|
||||
|
||||
public String getTypeName() {
|
||||
return typeName;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getIconName() {
|
||||
return iconName;
|
||||
}
|
||||
|
||||
public void setIconName(String iconName) {
|
||||
this.iconName = iconName;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getSimpleName(SampleApplication ctx, boolean addTypeName) {
|
||||
if (isLocation()) {
|
||||
if (!Algorithms.isEmpty(name) && !name.equals(ctx.getString("no_address_found"))) {
|
||||
return name;
|
||||
} else {
|
||||
return getLocationName(ctx, lat, lon, true).replace('\n', ' ');
|
||||
}
|
||||
}
|
||||
if (!Algorithms.isEmpty(typeName)) {
|
||||
if (Algorithms.isEmpty(name)) {
|
||||
return typeName;
|
||||
} else if(addTypeName){
|
||||
return typeName.trim() + ": " + name;
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getFullPlainName(SampleApplication ctx) {
|
||||
if (isLocation()) {
|
||||
return getLocationName(ctx, lat, lon, false);
|
||||
} else {
|
||||
String typeName = this.typeName;
|
||||
if (isFavorite()) {
|
||||
typeName = ctx.getString("favorite");
|
||||
} else if (isPoi()) {
|
||||
typeName = ctx.getString("poi");
|
||||
} else if (isWpt()) {
|
||||
return ctx.getString("gpx_wpt");
|
||||
}
|
||||
if (!Algorithms.isEmpty(typeName)) {
|
||||
if (Algorithms.isEmpty(name)) {
|
||||
return typeName;
|
||||
} else {
|
||||
return typeName.trim() + ": " + name;
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getLocationName(SampleApplication ctx, double lat, double lon, boolean sh) {
|
||||
SampleApplication app = SampleApplication.getApp(ctx);
|
||||
int f = app.getCoordinatesFormat();
|
||||
if (f == PointDescription.UTM_FORMAT) {
|
||||
UTMPoint pnt = new UTMPoint(new LatLonPoint(lat, lon));
|
||||
return pnt.zone_number + "" + pnt.zone_letter + " " + ((long) pnt.easting) + " "
|
||||
+ ((long) pnt.northing);
|
||||
} else {
|
||||
try {
|
||||
return ctx.getString(sh ? "short_location_on_map" : "location_on_map", LocationConvert.convert(lat, f),
|
||||
LocationConvert.convert(lon, f));
|
||||
} catch(RuntimeException e) {
|
||||
e.printStackTrace();
|
||||
return ctx.getString(sh ? "short_location_on_map" : "location_on_map", 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String getLocationNamePlain(Context ctx, double lat, double lon) {
|
||||
SampleApplication app = SampleApplication.getApp(ctx);
|
||||
int f = app.getCoordinatesFormat();
|
||||
if (f == PointDescription.UTM_FORMAT) {
|
||||
UTMPoint pnt = new UTMPoint(new LatLonPoint(lat, lon));
|
||||
return pnt.zone_number + "" + pnt.zone_letter + " " + ((long) pnt.easting) + " "
|
||||
+ ((long) pnt.northing);
|
||||
} else {
|
||||
try {
|
||||
return LocationConvert.convert(lat, f) + ", " + LocationConvert.convert(lon, f);
|
||||
} catch(RuntimeException e) {
|
||||
e.printStackTrace();
|
||||
return "0, 0";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean contextMenuDisabled() {
|
||||
return POINT_TYPE_WORLD_REGION_SHOW_ON_MAP.equals(type);
|
||||
}
|
||||
|
||||
public boolean isLocation() {
|
||||
return POINT_TYPE_LOCATION.equals(type);
|
||||
}
|
||||
|
||||
public boolean isAddress() {
|
||||
return POINT_TYPE_ADDRESS.equals(type);
|
||||
}
|
||||
|
||||
public boolean isWpt() {
|
||||
return POINT_TYPE_WPT.equals(type);
|
||||
}
|
||||
|
||||
public boolean isPoi() {
|
||||
return POINT_TYPE_POI.equals(type);
|
||||
}
|
||||
|
||||
public boolean isFavorite() {
|
||||
return POINT_TYPE_FAVORITE.equals(type);
|
||||
}
|
||||
|
||||
public boolean isAudioNote() {
|
||||
return POINT_TYPE_AUDIO_NOTE.equals(type);
|
||||
}
|
||||
|
||||
public boolean isVideoNote() {
|
||||
return POINT_TYPE_VIDEO_NOTE.equals(type);
|
||||
}
|
||||
|
||||
public boolean isPhotoNote() {
|
||||
return POINT_TYPE_PHOTO_NOTE.equals(type);
|
||||
}
|
||||
|
||||
public boolean isDestination() {
|
||||
return POINT_TYPE_TARGET.equals(type);
|
||||
}
|
||||
|
||||
public boolean isMapMarker() {
|
||||
return POINT_TYPE_MAP_MARKER.equals(type);
|
||||
}
|
||||
|
||||
public boolean isParking() {
|
||||
return POINT_TYPE_PARKING_MARKER.equals(type);
|
||||
}
|
||||
|
||||
public boolean isMyLocation() {
|
||||
return POINT_TYPE_MY_LOCATION.equals(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((type == null) ? 0 : type.hashCode());
|
||||
result = prime * result + ((typeName == null) ? 0 : typeName.hashCode());
|
||||
result = prime * result + ((lat == 0) ? 0 : new Double(lat).hashCode());
|
||||
result = prime * result + ((lon == 0) ? 0 : new Double(lon).hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
PointDescription other = (PointDescription) obj;
|
||||
if (Algorithms.objectEquals(other.name, name)
|
||||
&& Algorithms.objectEquals(other.type, type)
|
||||
&& Algorithms.objectEquals(other.lat, lat)
|
||||
&& Algorithms.objectEquals(other.lon, lon)
|
||||
&& Algorithms.objectEquals(other.typeName, typeName)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static String getSimpleName(LocationPoint o, SampleApplication ctx) {
|
||||
PointDescription pd = o.getPointDescription(ctx);
|
||||
return pd.getSimpleName(ctx, true);
|
||||
// return o.getPointDescription(ctx).getFullPlainName(ctx, o.getLatitude(), o.getLongitude());
|
||||
}
|
||||
|
||||
public boolean isSearchingAddress(SampleApplication ctx) {
|
||||
return !Algorithms.isEmpty(name) && isLocation() && name.equals(getSearchAddressStr(ctx));
|
||||
}
|
||||
|
||||
public static String getSearchAddressStr(SampleApplication ctx) {
|
||||
return ctx.getString("looking_up_address") + ctx.getString("shared_string_ellipsis");
|
||||
}
|
||||
|
||||
public static String getAddressNotFoundStr(SampleApplication ctx) {
|
||||
return ctx.getString("no_address_found");
|
||||
}
|
||||
|
||||
public static String serializeToString(PointDescription p) {
|
||||
if (p == null) {
|
||||
return "";
|
||||
}
|
||||
String tp = p.type ;
|
||||
if(!Algorithms.isEmpty(p.typeName)) {
|
||||
tp = tp +'.' + p.typeName;
|
||||
}
|
||||
String res = tp + "#" + p.name;
|
||||
if (!Algorithms.isEmpty(p.iconName)) {
|
||||
res += "#" + p.iconName;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static PointDescription deserializeFromString(String s, LatLon l) {
|
||||
PointDescription pd = null ;
|
||||
if (s != null && s.length() > 0) {
|
||||
int in = s.indexOf('#');
|
||||
if (in >= 0) {
|
||||
int ii = s.indexOf('#', in + 1);
|
||||
String name;
|
||||
String icon = null;
|
||||
if (ii > 0) {
|
||||
name = s.substring(in + 1, ii).trim();
|
||||
icon = s.substring(ii + 1).trim();
|
||||
} else {
|
||||
name = s.substring(in + 1).trim();
|
||||
}
|
||||
String tp = s.substring(0, in);
|
||||
if(tp.contains(".")) {
|
||||
pd = new PointDescription(tp.substring(0, tp.indexOf('.')), tp.substring(tp.indexOf('.') + 1), name);
|
||||
} else {
|
||||
pd = new PointDescription(tp, name);
|
||||
}
|
||||
if (!Algorithms.isEmpty(icon)) {
|
||||
pd.setIconName(icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(pd == null) {
|
||||
pd = new PointDescription(POINT_TYPE_LOCATION, "");
|
||||
}
|
||||
if(pd.isLocation() && l != null) {
|
||||
pd.setLat(l.getLatitude());
|
||||
pd.setLon(l.getLongitude());
|
||||
}
|
||||
return pd;
|
||||
}
|
||||
|
||||
public static final int FORMAT_DEGREES = LocationConvert.FORMAT_DEGREES;
|
||||
public static final int FORMAT_MINUTES = LocationConvert.FORMAT_MINUTES;
|
||||
public static final int FORMAT_SECONDS = LocationConvert.FORMAT_SECONDS;
|
||||
public static final int UTM_FORMAT = LocationConvert.UTM_FORMAT;
|
||||
|
||||
public static String formatToHumanString(SampleApplication ctx, int format) {
|
||||
switch (format) {
|
||||
case LocationConvert.FORMAT_DEGREES:
|
||||
return ctx.getString("navigate_point_format_D");
|
||||
case LocationConvert.FORMAT_MINUTES:
|
||||
return ctx.getString("navigate_point_format_DM");
|
||||
case LocationConvert.FORMAT_SECONDS:
|
||||
return ctx.getString("navigate_point_format_DMS");
|
||||
case LocationConvert.UTM_FORMAT:
|
||||
return "UTM";
|
||||
default:
|
||||
return "Unknown format";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,961 @@
|
|||
package net.osmand.core.samples.android.sample1.search;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.Location;
|
||||
import net.osmand.ResultMatcher;
|
||||
import net.osmand.core.samples.android.sample1.MainActivity;
|
||||
import net.osmand.core.samples.android.sample1.R;
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
import net.osmand.core.samples.android.sample1.SampleFormatter;
|
||||
import net.osmand.core.samples.android.sample1.SampleLocationProvider.SampleCompassListener;
|
||||
import net.osmand.core.samples.android.sample1.SampleLocationProvider.SampleLocationListener;
|
||||
import net.osmand.core.samples.android.sample1.data.PointDescription;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.search.SearchUICore;
|
||||
import net.osmand.search.SearchUICore.SearchResultCollection;
|
||||
import net.osmand.search.core.ObjectType;
|
||||
import net.osmand.search.core.SearchCoreAPI;
|
||||
import net.osmand.search.core.SearchCoreFactory.SearchAmenityTypesAPI;
|
||||
import net.osmand.search.core.SearchPhrase;
|
||||
import net.osmand.search.core.SearchResult;
|
||||
import net.osmand.search.core.SearchSettings;
|
||||
import net.osmand.search.core.SearchWord;
|
||||
import net.osmand.util.Algorithms;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static net.osmand.search.core.ObjectType.POI_TYPE;
|
||||
import static net.osmand.search.core.SearchCoreFactory.SEARCH_AMENITY_TYPE_PRIORITY;
|
||||
|
||||
public class QuickSearchDialogFragment extends DialogFragment implements SampleCompassListener, SampleLocationListener {
|
||||
|
||||
public static final String TAG = "QuickSearchDialogFragment";
|
||||
private static final String QUICK_SEARCH_QUERY_KEY = "quick_search_query_key";
|
||||
private static final String QUICK_SEARCH_LAT_KEY = "quick_search_lat_key";
|
||||
private static final String QUICK_SEARCH_LON_KEY = "quick_search_lon_key";
|
||||
private static final String QUICK_SEARCH_INTERRUPTED_SEARCH_KEY = "quick_search_interrupted_search_key";
|
||||
private static final String QUICK_SEARCH_SHOW_CATEGORIES_KEY = "quick_search_show_categories_key";
|
||||
private static final String QUICK_SEARCH_HIDDEN_KEY = "quick_search_hidden_key";
|
||||
private static final String QUICK_SEARCH_TOOLBAR_TITLE_KEY = "quick_search_toolbar_title_key";
|
||||
private static final String QUICK_SEARCH_TOOLBAR_VISIBLE_KEY = "quick_search_toolbar_visible_key";
|
||||
private static final String QUICK_SEARCH_RUN_SEARCH_FIRST_TIME_KEY = "quick_search_run_search_first_time_key";
|
||||
private static final String QUICK_SEARCH_PHRASE_DEFINED_KEY = "quick_search_phrase_defined_key";
|
||||
|
||||
private Toolbar toolbar;
|
||||
private View searchView;
|
||||
private View buttonToolbarView;
|
||||
private ImageView buttonToolbarImage;
|
||||
private TextView buttonToolbarText;
|
||||
private QuickSearchMainListFragment mainSearchFragment;
|
||||
private QuickSearchCategoriesListFragment categoriesSearchFragment;
|
||||
//private QuickSearchToolbarController toolbarController;
|
||||
|
||||
private EditText searchEditText;
|
||||
private ProgressBar progressBar;
|
||||
private ImageButton clearButton;
|
||||
|
||||
private SampleApplication app;
|
||||
private QuickSearchHelper searchHelper;
|
||||
private SearchUICore searchUICore;
|
||||
private String searchQuery;
|
||||
|
||||
private LatLon centerLatLon;
|
||||
private Location location = null;
|
||||
private Float heading = null;
|
||||
private boolean useMapCenter;
|
||||
private boolean paused;
|
||||
private boolean cancelPrev;
|
||||
private boolean searching;
|
||||
private boolean hidden;
|
||||
private String toolbarTitle;
|
||||
private boolean toolbarVisible;
|
||||
|
||||
private boolean newSearch;
|
||||
private boolean interruptedSearch;
|
||||
private long hideTimeMs;
|
||||
private boolean runSearchFirstTime;
|
||||
private boolean phraseDefined;
|
||||
|
||||
private static final double DISTANCE_THRESHOLD = 70000; // 70km
|
||||
private static final int EXPIRATION_TIME_MIN = 10; // 10 minutes
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
app = getMyApplication();
|
||||
setStyle(STYLE_NO_FRAME, R.style.AppTheme);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressLint("PrivateResource, ValidFragment")
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
final MainActivity mainActivity = getMainActivity();
|
||||
final View view = inflater.inflate(R.layout.search_dialog_fragment, container, false);
|
||||
|
||||
/*
|
||||
toolbarController = new QuickSearchToolbarController();
|
||||
toolbarController.setOnBackButtonClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mainActivity.showQuickSearch(ShowQuickSearchMode.CURRENT, false);
|
||||
}
|
||||
});
|
||||
toolbarController.setOnTitleClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mainActivity.showQuickSearch(ShowQuickSearchMode.CURRENT, false);
|
||||
}
|
||||
});
|
||||
toolbarController.setOnCloseButtonClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mainActivity.closeQuickSearch();
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
Bundle arguments = getArguments();
|
||||
if (savedInstanceState != null) {
|
||||
searchQuery = savedInstanceState.getString(QUICK_SEARCH_QUERY_KEY);
|
||||
double lat = savedInstanceState.getDouble(QUICK_SEARCH_LAT_KEY, Double.NaN);
|
||||
double lon = savedInstanceState.getDouble(QUICK_SEARCH_LON_KEY, Double.NaN);
|
||||
if (!Double.isNaN(lat) && !Double.isNaN(lon)) {
|
||||
centerLatLon = new LatLon(lat, lon);
|
||||
}
|
||||
interruptedSearch = savedInstanceState.getBoolean(QUICK_SEARCH_INTERRUPTED_SEARCH_KEY, false);
|
||||
hidden = savedInstanceState.getBoolean(QUICK_SEARCH_HIDDEN_KEY, false);
|
||||
toolbarTitle = savedInstanceState.getString(QUICK_SEARCH_TOOLBAR_TITLE_KEY);
|
||||
toolbarVisible = savedInstanceState.getBoolean(QUICK_SEARCH_TOOLBAR_VISIBLE_KEY, false);
|
||||
}
|
||||
if (searchQuery == null && arguments != null) {
|
||||
searchQuery = arguments.getString(QUICK_SEARCH_QUERY_KEY);
|
||||
runSearchFirstTime = arguments.getBoolean(QUICK_SEARCH_RUN_SEARCH_FIRST_TIME_KEY, false);
|
||||
phraseDefined = arguments.getBoolean(QUICK_SEARCH_PHRASE_DEFINED_KEY, false);
|
||||
double lat = arguments.getDouble(QUICK_SEARCH_LAT_KEY, Double.NaN);
|
||||
double lon = arguments.getDouble(QUICK_SEARCH_LON_KEY, Double.NaN);
|
||||
if (!Double.isNaN(lat) && !Double.isNaN(lon)) {
|
||||
centerLatLon = new LatLon(lat, lon);
|
||||
}
|
||||
newSearch = true;
|
||||
}
|
||||
if (searchQuery == null)
|
||||
searchQuery = "";
|
||||
|
||||
boolean showCategories = false;
|
||||
if (arguments != null) {
|
||||
showCategories = arguments.getBoolean(QUICK_SEARCH_SHOW_CATEGORIES_KEY, false);
|
||||
}
|
||||
|
||||
searchView = view.findViewById(R.id.search_view);
|
||||
|
||||
buttonToolbarView = view.findViewById(R.id.button_toolbar_layout);
|
||||
buttonToolbarImage = (ImageView) view.findViewById(R.id.buttonToolbarImage);
|
||||
buttonToolbarImage.setImageDrawable(app.getIconsCache().getThemedIcon("ic_action_marker_dark"));
|
||||
|
||||
buttonToolbarText = (TextView) view.findViewById(R.id.buttonToolbarTitle);
|
||||
view.findViewById(R.id.buttonToolbar).setOnClickListener(
|
||||
new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
SearchPhrase searchPhrase = searchUICore.getPhrase();
|
||||
if (!searchPhrase.isNoSelectedType() && !searchPhrase.isLastWord(POI_TYPE)) {
|
||||
SearchWord word = searchPhrase.getLastSelectedWord();
|
||||
if (word != null && word.getLocation() != null) {
|
||||
SearchResult searchResult = word.getResult();
|
||||
String name = QuickSearchListItem.getName(app, searchResult);
|
||||
String typeName = QuickSearchListItem.getTypeName(app, searchResult);
|
||||
PointDescription pointDescription = new PointDescription(PointDescription.POINT_TYPE_ADDRESS, typeName, name);
|
||||
|
||||
mainActivity.showOnMap(searchResult.location, searchResult.preferredZoom);
|
||||
/* todo
|
||||
app.getSettings().setMapLocationToShow(
|
||||
searchResult.location.getLatitude(), searchResult.location.getLongitude(),
|
||||
searchResult.preferredZoom, pointDescription, true, searchResult.object);
|
||||
|
||||
hideToolbar();
|
||||
MainActivity.launchMainActivityMoveToTop(getActivity());
|
||||
*/
|
||||
hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
toolbar = (Toolbar) view.findViewById(R.id.toolbar);
|
||||
toolbar.setNavigationIcon(app.getIconsCache().getThemedIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha));
|
||||
toolbar.setNavigationContentDescription(app.getString("access_shared_string_navigate_up"));
|
||||
toolbar.setNavigationOnClickListener(
|
||||
new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
searchEditText = (EditText) view.findViewById(R.id.searchEditText);
|
||||
searchEditText.addTextChangedListener(
|
||||
new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
String newQueryText = s.toString();
|
||||
updateClearButtonAndHint();
|
||||
updateClearButtonVisibility(true);
|
||||
boolean textEmpty = newQueryText.length() == 0;
|
||||
updateTabbarVisibility(textEmpty);
|
||||
if (!searchQuery.equalsIgnoreCase(newQueryText)) {
|
||||
searchQuery = newQueryText;
|
||||
if (Algorithms.isEmpty(searchQuery)) {
|
||||
searchUICore.resetPhrase();
|
||||
} else {
|
||||
runSearch();
|
||||
}
|
||||
} else if (runSearchFirstTime) {
|
||||
runSearchFirstTime = false;
|
||||
runSearch();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
progressBar = (ProgressBar) view.findViewById(R.id.searchProgressBar);
|
||||
clearButton = (ImageButton) view.findViewById(R.id.clearButton);
|
||||
clearButton.setImageDrawable(app.getIconsCache().getThemedIcon(R.drawable.ic_action_remove_dark));
|
||||
clearButton.setOnClickListener(
|
||||
new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (searchEditText.getText().length() > 0) {
|
||||
String newText = searchUICore.getPhrase().getTextWithoutLastWord();
|
||||
searchEditText.setText(newText);
|
||||
searchEditText.setSelection(newText.length());
|
||||
} else if (useMapCenter && location != null) {
|
||||
useMapCenter = false;
|
||||
centerLatLon = null;
|
||||
updateUseMapCenterUI();
|
||||
LatLon centerLatLon = new LatLon(location.getLatitude(), location.getLongitude());
|
||||
SearchSettings ss = searchUICore.getSearchSettings().setOriginalLocation(
|
||||
new LatLon(centerLatLon.getLatitude(), centerLatLon.getLongitude()));
|
||||
searchUICore.updateSettings(ss);
|
||||
updateClearButtonAndHint();
|
||||
updateClearButtonVisibility(true);
|
||||
startLocationUpdate();
|
||||
}
|
||||
updateToolbarButton();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
setupSearch(mainActivity);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
updateToolbarButton();
|
||||
updateClearButtonAndHint();
|
||||
updateClearButtonVisibility(true);
|
||||
addMainSearchFragment();
|
||||
|
||||
if (centerLatLon == null) {
|
||||
searchEditText.requestFocus();
|
||||
AndroidUtils.softKeyboardDelayed(searchEditText);
|
||||
}
|
||||
}
|
||||
|
||||
public void restoreToolbar() {
|
||||
if (toolbarVisible) {
|
||||
if (toolbarTitle != null) {
|
||||
showToolbar(toolbarTitle);
|
||||
} else {
|
||||
showToolbar();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void showToolbar() {
|
||||
showToolbar(getText());
|
||||
}
|
||||
|
||||
public void showToolbar(String title) {
|
||||
toolbarVisible = true;
|
||||
toolbarTitle = title;
|
||||
//todo
|
||||
//toolbarController.setTitle(toolbarTitle);
|
||||
//getMainActivity().showTopToolbar(toolbarController);
|
||||
}
|
||||
|
||||
public void hideToolbar() {
|
||||
toolbarVisible = false;
|
||||
//getMainActivity().hideTopToolbar(toolbarController); todo
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return searchEditText.getText().toString();
|
||||
}
|
||||
|
||||
public void hideKeyboard() {
|
||||
if (searchEditText.hasFocus()) {
|
||||
AndroidUtils.hideSoftKeyboard(getActivity(), searchEditText);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSearchHidden() {
|
||||
return hidden;
|
||||
}
|
||||
|
||||
public boolean isExpired() {
|
||||
return hideTimeMs > 0 && System.currentTimeMillis() - hideTimeMs > EXPIRATION_TIME_MIN * 60 * 1000;
|
||||
}
|
||||
|
||||
public void show() {
|
||||
if (useMapCenter) {
|
||||
LatLon mapCenter = getMainActivity().getScreenCenter();
|
||||
SearchSettings ss = searchUICore.getSearchSettings().setOriginalLocation(
|
||||
new LatLon(mapCenter.getLatitude(), mapCenter.getLongitude()));
|
||||
searchUICore.updateSettings(ss);
|
||||
updateUseMapCenterUI();
|
||||
updateLocationUI(mapCenter, null);
|
||||
}
|
||||
getDialog().show();
|
||||
paused = false;
|
||||
hidden = false;
|
||||
if (interruptedSearch) {
|
||||
interruptedSearch = false;
|
||||
addMoreButton();
|
||||
}
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
paused = true;
|
||||
hidden = true;
|
||||
hideTimeMs = System.currentTimeMillis();
|
||||
interruptedSearch = searching;
|
||||
searching = false;
|
||||
hideProgressBar();
|
||||
updateClearButtonVisibility(true);
|
||||
getDialog().hide();
|
||||
}
|
||||
|
||||
public void closeSearch() {
|
||||
dismiss();
|
||||
}
|
||||
|
||||
public void addMainSearchFragment() {
|
||||
mainSearchFragment = (QuickSearchMainListFragment) Fragment.instantiate(this.getContext(), QuickSearchMainListFragment.class.getName());
|
||||
FragmentManager childFragMan = getChildFragmentManager();
|
||||
FragmentTransaction childFragTrans = childFragMan.beginTransaction();
|
||||
childFragTrans.replace(R.id.search_view, mainSearchFragment);
|
||||
childFragTrans.commit();
|
||||
}
|
||||
|
||||
private void updateToolbarButton() {
|
||||
SearchWord word = searchUICore.getPhrase().getLastSelectedWord();
|
||||
if (searchEditText.getText().length() > 0) {
|
||||
if (word != null && word.getResult() != null) {
|
||||
buttonToolbarText.setText(app.getString("show_something_on_map", word.getResult().localeName).toUpperCase());
|
||||
} else {
|
||||
buttonToolbarText.setText(app.getString("shared_string_show_on_map").toUpperCase());
|
||||
}
|
||||
} else {
|
||||
buttonToolbarText.setText(app.getString("shared_string_show_on_map").toUpperCase());
|
||||
}
|
||||
}
|
||||
|
||||
private void setupSearch(final MainActivity mainActivity) {
|
||||
// Setup search core
|
||||
String locale = ""; //app.getSettings().MAP_PREFERRED_LOCALE.get();
|
||||
boolean transliterate = false; //app.getSettings().MAP_TRANSLITERATE_NAMES.get();
|
||||
searchHelper = app.getSearchUICore();
|
||||
searchUICore = searchHelper.getCore();
|
||||
if (newSearch) {
|
||||
setResultCollection(null);
|
||||
if (!phraseDefined) {
|
||||
searchUICore.resetPhrase();
|
||||
}
|
||||
phraseDefined = false;
|
||||
}
|
||||
|
||||
location = app.getLocationProvider().getLastKnownLocation();
|
||||
|
||||
LatLon searchLatLon;
|
||||
if (centerLatLon == null) {
|
||||
LatLon clt = mainActivity.getScreenCenter();
|
||||
searchLatLon = clt;
|
||||
searchEditText.setHint(app.getString("search_poi_category_hint"));
|
||||
if (location != null) {
|
||||
double d = MapUtils.getDistance(clt, location.getLatitude(), location.getLongitude());
|
||||
if (d < DISTANCE_THRESHOLD) {
|
||||
searchLatLon = new LatLon(location.getLatitude(), location.getLongitude());
|
||||
} else {
|
||||
useMapCenter = true;
|
||||
}
|
||||
} else {
|
||||
useMapCenter = true;
|
||||
}
|
||||
} else {
|
||||
searchLatLon = centerLatLon;
|
||||
useMapCenter = true;
|
||||
}
|
||||
SearchSettings settings = searchUICore.getSearchSettings().setOriginalLocation(
|
||||
new LatLon(searchLatLon.getLatitude(), searchLatLon.getLongitude()));
|
||||
settings = settings.setLang(locale, transliterate);
|
||||
searchUICore.updateSettings(settings);
|
||||
searchUICore.setOnSearchStart(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
cancelPrev = false;
|
||||
}
|
||||
});
|
||||
searchUICore.setOnResultsComplete(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
app.runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
searching = false;
|
||||
if (!paused && !cancelPrev) {
|
||||
hideProgressBar();
|
||||
if (searchUICore.isSearchMoreAvailable(searchUICore.getPhrase())) {
|
||||
addMoreButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
setShowsDialog(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
outState.putString(QUICK_SEARCH_QUERY_KEY, searchQuery);
|
||||
outState.putBoolean(QUICK_SEARCH_INTERRUPTED_SEARCH_KEY, interruptedSearch = searching);
|
||||
outState.putBoolean(QUICK_SEARCH_HIDDEN_KEY, hidden);
|
||||
if (toolbarTitle != null) {
|
||||
outState.putString(QUICK_SEARCH_TOOLBAR_TITLE_KEY, toolbarTitle);
|
||||
}
|
||||
outState.putBoolean(QUICK_SEARCH_TOOLBAR_VISIBLE_KEY, toolbarVisible);
|
||||
if (centerLatLon != null) {
|
||||
outState.putDouble(QUICK_SEARCH_LAT_KEY, centerLatLon.getLatitude());
|
||||
outState.putDouble(QUICK_SEARCH_LON_KEY, centerLatLon.getLongitude());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (!useMapCenter) {
|
||||
startLocationUpdate();
|
||||
}
|
||||
paused = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
paused = true;
|
||||
hideTimeMs = System.currentTimeMillis();
|
||||
stopLocationUpdate();
|
||||
hideProgressBar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
MainActivity mainActivity = getMainActivity();
|
||||
if (mainActivity != null) {
|
||||
hideToolbar();
|
||||
getChildFragmentManager().popBackStack();
|
||||
}
|
||||
super.onDismiss(dialog);
|
||||
}
|
||||
|
||||
public Toolbar getToolbar() {
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
public boolean isUseMapCenter() {
|
||||
return useMapCenter;
|
||||
}
|
||||
|
||||
private void startLocationUpdate() {
|
||||
app.getLocationProvider().addCompassListener(this);
|
||||
app.getLocationProvider().addLocationListener(this);
|
||||
location = app.getLocationProvider().getLastKnownLocation();
|
||||
updateLocation(location);
|
||||
}
|
||||
|
||||
private void stopLocationUpdate() {
|
||||
app.getLocationProvider().removeLocationListener(this);
|
||||
app.getLocationProvider().removeCompassListener(this);
|
||||
}
|
||||
|
||||
private void showProgressBar() {
|
||||
updateClearButtonVisibility(false);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void hideProgressBar() {
|
||||
updateClearButtonVisibility(true);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
private void updateClearButtonAndHint() {
|
||||
if (useMapCenter && location != null && searchEditText.length() == 0) {
|
||||
LatLon latLon = searchUICore.getSearchSettings().getOriginalLocation();
|
||||
double d = MapUtils.getDistance(latLon, location.getLatitude(), location.getLongitude());
|
||||
String dist = SampleFormatter.getFormattedDistance((float) d, app);
|
||||
searchEditText.setHint(app.getString("dist_away_from_my_location", dist));
|
||||
clearButton.setImageDrawable(app.getIconsCache().getIcon("ic_action_get_my_location", R.color.color_myloc_distance));
|
||||
} else {
|
||||
searchEditText.setHint(app.getString("search_poi_category_hint"));
|
||||
clearButton.setImageDrawable(app.getIconsCache().getThemedIcon(R.drawable.ic_action_remove_dark));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateClearButtonVisibility(boolean show) {
|
||||
if (show) {
|
||||
clearButton.setVisibility(searchEditText.length() > 0 || (useMapCenter && location != null) ? View.VISIBLE : View.GONE);
|
||||
} else {
|
||||
clearButton.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTabbarVisibility(boolean show) {
|
||||
if (show) {
|
||||
buttonToolbarView.setVisibility(View.GONE);
|
||||
searchView.setVisibility(View.GONE);
|
||||
} else {
|
||||
buttonToolbarView.setVisibility(View.VISIBLE);
|
||||
searchView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
public void setResultCollection(SearchResultCollection resultCollection) {
|
||||
searchHelper.setResultCollection(resultCollection);
|
||||
}
|
||||
|
||||
public SearchResultCollection getResultCollection() {
|
||||
return searchHelper.getResultCollection();
|
||||
}
|
||||
|
||||
public void onSearchListFragmentResume(QuickSearchListFragment searchListFragment) {
|
||||
switch (searchListFragment.getType()) {
|
||||
case CATEGORIES:
|
||||
categoriesSearchFragment = (QuickSearchCategoriesListFragment) searchListFragment;
|
||||
reloadCategories();
|
||||
break;
|
||||
|
||||
case MAIN:
|
||||
if (!Algorithms.isEmpty(searchQuery)) {
|
||||
searchEditText.setText(searchQuery);
|
||||
searchEditText.setSelection(searchQuery.length());
|
||||
}
|
||||
if (getResultCollection() != null) {
|
||||
updateSearchResult(getResultCollection(), false);
|
||||
if (interruptedSearch || searchUICore.isSearchMoreAvailable(searchUICore.getPhrase())) {
|
||||
addMoreButton();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
LatLon mapCenter = getMainActivity().getScreenCenter();
|
||||
if (useMapCenter) {
|
||||
updateUseMapCenterUI();
|
||||
searchListFragment.updateLocation(mapCenter, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void reloadCategories() {
|
||||
try {
|
||||
SearchResultCollection res = searchUICore.shallowSearch(SearchAmenityTypesAPI.class,
|
||||
"", null);
|
||||
if (res != null) {
|
||||
List<QuickSearchListItem> rows = new ArrayList<>();
|
||||
for (SearchResult sr : res.getCurrentSearchResults()) {
|
||||
rows.add(new QuickSearchListItem(app, sr));
|
||||
}
|
||||
categoriesSearchFragment.updateListAdapter(rows, false);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void runSearch() {
|
||||
runSearch(searchQuery);
|
||||
}
|
||||
|
||||
private void runSearch(String text) {
|
||||
showProgressBar();
|
||||
SearchSettings settings = searchUICore.getPhrase().getSettings();
|
||||
if (settings.getRadiusLevel() != 1) {
|
||||
searchUICore.updateSettings(settings.setRadiusLevel(1));
|
||||
}
|
||||
runCoreSearch(text, true, false);
|
||||
}
|
||||
|
||||
private void runCoreSearch(final String text, final boolean updateResult, final boolean searchMore) {
|
||||
showProgressBar();
|
||||
updateToolbarButton();
|
||||
interruptedSearch = false;
|
||||
searching = true;
|
||||
cancelPrev = true;
|
||||
runCoreSearchInternal(text, updateResult, searchMore);
|
||||
}
|
||||
|
||||
private void runCoreSearchInternal(String text, boolean updateResult, boolean searchMore) {
|
||||
SearchResultCollection c = searchUICore.search(text, new ResultMatcher<SearchResult>() {
|
||||
SearchResultCollection regionResultCollection = null;
|
||||
SearchCoreAPI regionResultApi = null;
|
||||
List<SearchResult> results = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public boolean publish(SearchResult object) {
|
||||
if (paused || cancelPrev) {
|
||||
if (results.size() > 0) {
|
||||
getResultCollection().addSearchResults(results, true, true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
switch (object.objectType) {
|
||||
case SEARCH_API_FINISHED:
|
||||
final SearchCoreAPI searchApi = (SearchCoreAPI) object.object;
|
||||
final List<SearchResult> apiResults;
|
||||
final SearchPhrase phrase = object.requiredSearchPhrase;
|
||||
final SearchCoreAPI regionApi = regionResultApi;
|
||||
final SearchResultCollection regionCollection = regionResultCollection;
|
||||
final boolean hasRegionCollection = (searchApi == regionApi && regionCollection != null);
|
||||
if (hasRegionCollection) {
|
||||
apiResults = regionCollection.getCurrentSearchResults();
|
||||
} else {
|
||||
apiResults = results;
|
||||
}
|
||||
regionResultApi = null;
|
||||
regionResultCollection = null;
|
||||
results = new ArrayList<>();
|
||||
showApiResults(apiResults, phrase, hasRegionCollection);
|
||||
break;
|
||||
case SEARCH_API_REGION_FINISHED:
|
||||
regionResultApi = (SearchCoreAPI) object.object;
|
||||
final SearchPhrase regionPhrase = object.requiredSearchPhrase;
|
||||
regionResultCollection =
|
||||
new SearchResultCollection(regionPhrase).addSearchResults(results, true, true);
|
||||
showRegionResults(regionResultCollection);
|
||||
break;
|
||||
case PARTIAL_LOCATION:
|
||||
showLocationToolbar();
|
||||
break;
|
||||
default:
|
||||
results.add(object);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return paused || cancelPrev;
|
||||
}
|
||||
});
|
||||
|
||||
if (!searchMore) {
|
||||
setResultCollection(null);
|
||||
if (!updateResult) {
|
||||
updateSearchResult(null, false);
|
||||
}
|
||||
}
|
||||
if (updateResult) {
|
||||
updateSearchResult(c, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void showLocationToolbar() {
|
||||
app.runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateToolbarButton();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showApiResults(final List<SearchResult> apiResults, final SearchPhrase phrase,
|
||||
final boolean hasRegionCollection) {
|
||||
app.runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!paused && !cancelPrev) {
|
||||
boolean append = getResultCollection() != null;
|
||||
if (append) {
|
||||
getResultCollection().addSearchResults(apiResults, true, true);
|
||||
} else {
|
||||
SearchResultCollection resCollection = new SearchResultCollection(phrase);
|
||||
resCollection.addSearchResults(apiResults, true, true);
|
||||
setResultCollection(resCollection);
|
||||
}
|
||||
if (!hasRegionCollection) {
|
||||
updateSearchResult(getResultCollection(), append);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showRegionResults(final SearchResultCollection regionResultCollection) {
|
||||
app.runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!paused && !cancelPrev) {
|
||||
if (getResultCollection() != null) {
|
||||
SearchResultCollection resCollection =
|
||||
getResultCollection().combineWithCollection(regionResultCollection, true, true);
|
||||
updateSearchResult(resCollection, true);
|
||||
} else {
|
||||
updateSearchResult(regionResultCollection, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void completeQueryWithObject(SearchResult sr) {
|
||||
searchUICore.selectSearchResult(sr);
|
||||
String txt = searchUICore.getPhrase().getText(true);
|
||||
searchQuery = txt;
|
||||
searchEditText.setText(txt);
|
||||
searchEditText.setSelection(txt.length());
|
||||
updateToolbarButton();
|
||||
SearchSettings settings = searchUICore.getPhrase().getSettings();
|
||||
if (settings.getRadiusLevel() != 1) {
|
||||
searchUICore.updateSettings(settings.setRadiusLevel(1));
|
||||
}
|
||||
runCoreSearch(txt, false, false);
|
||||
}
|
||||
|
||||
public void clearLastWord() {
|
||||
if (searchEditText.getText().length() > 0) {
|
||||
String newText = searchUICore.getPhrase().getTextWithoutLastWord();
|
||||
searchEditText.setText(newText);
|
||||
searchEditText.setSelection(newText.length());
|
||||
}
|
||||
}
|
||||
|
||||
private void addMoreButton() {
|
||||
QuickSearchMoreListItem moreListItem =
|
||||
new QuickSearchMoreListItem(app, app.getString("search_POI_level_btn").toUpperCase(), new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (!interruptedSearch) {
|
||||
SearchSettings settings = searchUICore.getPhrase().getSettings();
|
||||
searchUICore.updateSettings(settings.setRadiusLevel(settings.getRadiusLevel() + 1));
|
||||
}
|
||||
runCoreSearch(searchQuery, false, true);
|
||||
}
|
||||
});
|
||||
|
||||
if (!paused && !cancelPrev && mainSearchFragment != null) {
|
||||
mainSearchFragment.addListItem(moreListItem);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSearchResult(SearchResultCollection res, boolean append) {
|
||||
|
||||
if (!paused && mainSearchFragment != null) {
|
||||
List<QuickSearchListItem> rows = new ArrayList<>();
|
||||
if (res != null && res.getCurrentSearchResults().size() > 0) {
|
||||
for (final SearchResult sr : res.getCurrentSearchResults()) {
|
||||
rows.add(new QuickSearchListItem(app, sr));
|
||||
}
|
||||
}
|
||||
mainSearchFragment.updateListAdapter(rows, append);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean showInstance(@NonNull MainActivity mainActivity,
|
||||
@NonNull String searchQuery,
|
||||
@Nullable Object object,
|
||||
boolean showCategories,
|
||||
@Nullable LatLon latLon) {
|
||||
try {
|
||||
Bundle bundle = new Bundle();
|
||||
if (object != null) {
|
||||
bundle.putBoolean(QUICK_SEARCH_RUN_SEARCH_FIRST_TIME_KEY, true);
|
||||
String objectLocalizedName = searchQuery;
|
||||
|
||||
if (object instanceof PoiCategory) {
|
||||
PoiCategory c = (PoiCategory) object;
|
||||
objectLocalizedName = c.getTranslation();
|
||||
|
||||
SearchUICore searchUICore = mainActivity.getMyApplication().getSearchUICore().getCore();
|
||||
SearchPhrase phrase = searchUICore.resetPhrase(objectLocalizedName + " ");
|
||||
SearchResult sr = new SearchResult(phrase);
|
||||
sr.localeName = objectLocalizedName;
|
||||
sr.object = c;
|
||||
sr.priority = SEARCH_AMENITY_TYPE_PRIORITY;
|
||||
sr.priorityDistance = 0;
|
||||
sr.objectType = ObjectType.POI_TYPE;
|
||||
searchUICore.selectSearchResult(sr);
|
||||
|
||||
bundle.putBoolean(QUICK_SEARCH_PHRASE_DEFINED_KEY, true);
|
||||
}
|
||||
searchQuery = objectLocalizedName.trim() + " ";
|
||||
|
||||
} else if (!Algorithms.isEmpty(searchQuery)) {
|
||||
bundle.putBoolean(QUICK_SEARCH_RUN_SEARCH_FIRST_TIME_KEY, true);
|
||||
}
|
||||
|
||||
bundle.putString(QUICK_SEARCH_QUERY_KEY, searchQuery);
|
||||
bundle.putBoolean(QUICK_SEARCH_SHOW_CATEGORIES_KEY, showCategories);
|
||||
if (latLon != null) {
|
||||
bundle.putDouble(QUICK_SEARCH_LAT_KEY, latLon.getLatitude());
|
||||
bundle.putDouble(QUICK_SEARCH_LON_KEY, latLon.getLongitude());
|
||||
}
|
||||
QuickSearchDialogFragment fragment = new QuickSearchDialogFragment();
|
||||
fragment.setArguments(bundle);
|
||||
fragment.show(mainActivity.getSupportFragmentManager(), TAG);
|
||||
return true;
|
||||
|
||||
} catch (RuntimeException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private MainActivity getMainActivity() {
|
||||
return (MainActivity) getActivity();
|
||||
}
|
||||
|
||||
private SampleApplication getMyApplication() {
|
||||
return (SampleApplication) getActivity().getApplication();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCompassValue(final float value) {
|
||||
// 99 in next line used to one-time initialize arrows (with reference vs. fixed-north direction)
|
||||
// on non-compass devices
|
||||
float lastHeading = heading != null ? heading : 99;
|
||||
heading = value;
|
||||
if (Math.abs(MapUtils.degreesDiff(lastHeading, heading)) > 5) {
|
||||
final Location location = this.location;
|
||||
app.runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateLocationUI(location, value);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
heading = lastHeading;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLocation(final Location location) {
|
||||
final Float heading = this.heading;
|
||||
app.runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateLocationUI(location, heading);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateLocationUI(Location location, Float heading) {
|
||||
this.location = location;
|
||||
LatLon latLon = null;
|
||||
if (location != null) {
|
||||
latLon = new LatLon(location.getLatitude(), location.getLongitude());
|
||||
}
|
||||
updateLocationUI(latLon, heading);
|
||||
}
|
||||
|
||||
private void updateLocationUI(LatLon latLon, Float heading) {
|
||||
if (latLon != null && !paused && !cancelPrev) {
|
||||
if (mainSearchFragment != null && searchView.getVisibility() == View.VISIBLE) {
|
||||
mainSearchFragment.updateLocation(latLon, heading);
|
||||
} else if (categoriesSearchFragment != null) {
|
||||
categoriesSearchFragment.updateLocation(latLon, heading);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateUseMapCenterUI() {
|
||||
if (!paused && !cancelPrev) {
|
||||
if (mainSearchFragment != null) {
|
||||
mainSearchFragment.getListAdapter().setUseMapCenter(useMapCenter);
|
||||
}
|
||||
if (categoriesSearchFragment != null) {
|
||||
categoriesSearchFragment.getListAdapter().setUseMapCenter(useMapCenter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class QuickSearchCategoriesListFragment extends QuickSearchListFragment {
|
||||
|
||||
@Override
|
||||
public SearchListFragmentType getType() {
|
||||
return SearchListFragmentType.CATEGORIES;
|
||||
}
|
||||
}
|
||||
|
||||
public static class QuickSearchMainListFragment extends QuickSearchListFragment {
|
||||
|
||||
@Override
|
||||
public SearchListFragmentType getType() {
|
||||
return SearchListFragmentType.MAIN;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public static class QuickSearchToolbarController extends TopToolbarController {
|
||||
|
||||
public QuickSearchToolbarController() {
|
||||
super(TopToolbarControllerType.QUICK_SEARCH);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
package net.osmand.core.samples.android.sample1.search;
|
||||
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
import net.osmand.search.SearchUICore;
|
||||
import net.osmand.search.SearchUICore.SearchResultCollection;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class QuickSearchHelper {
|
||||
private SampleApplication app;
|
||||
private SearchUICore core;
|
||||
private SearchResultCollection resultCollection;
|
||||
|
||||
public QuickSearchHelper(SampleApplication app) {
|
||||
this.app = app;
|
||||
core = new SearchUICore(app.getPoiTypes(), SampleApplication.LANGUAGE, false);
|
||||
}
|
||||
|
||||
public SearchUICore getCore() {
|
||||
return core;
|
||||
}
|
||||
|
||||
public SearchResultCollection getResultCollection() {
|
||||
return resultCollection;
|
||||
}
|
||||
|
||||
public void setResultCollection(SearchResultCollection resultCollection) {
|
||||
this.resultCollection = resultCollection;
|
||||
}
|
||||
|
||||
public void initSearchUICore() {
|
||||
setRepositoriesForSearchUICore(app);
|
||||
core.setPoiTypes(app.getPoiTypes());
|
||||
core.init();
|
||||
}
|
||||
|
||||
public void setRepositoriesForSearchUICore(final SampleApplication app) {
|
||||
ArrayList<File> files = new ArrayList<File>();
|
||||
File appPath = app.getAppPath(null);
|
||||
collectFiles(appPath, IndexConstants.BINARY_MAP_INDEX_EXT, files);
|
||||
collectFiles(app.getAppPath(IndexConstants.WIKI_INDEX_DIR), IndexConstants.BINARY_MAP_INDEX_EXT, files);
|
||||
|
||||
List<BinaryMapIndexReader> readers = new ArrayList<>();
|
||||
for (File f : files) {
|
||||
try {
|
||||
RandomAccessFile mf = new RandomAccessFile(f.getPath(), "r");
|
||||
BinaryMapIndexReader reader = new BinaryMapIndexReader(mf, f);
|
||||
readers.add(reader);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
core.getSearchSettings().setOfflineIndexes(readers);
|
||||
}
|
||||
|
||||
private List<File> collectFiles(File dir, String ext, List<File> files) {
|
||||
if (dir.exists() && dir.canRead()) {
|
||||
File[] lf = dir.listFiles();
|
||||
if (lf == null || lf.length == 0) {
|
||||
return files;
|
||||
}
|
||||
for (File f : lf) {
|
||||
if (f.getName().endsWith(ext)) {
|
||||
files.add(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,331 @@
|
|||
package net.osmand.core.samples.android.sample1.search;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.Location;
|
||||
import net.osmand.core.samples.android.sample1.R;
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
import net.osmand.core.samples.android.sample1.SampleFormatter;
|
||||
import net.osmand.core.samples.android.sample1.view.DirectionDrawable;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.search.core.SearchPhrase;
|
||||
import net.osmand.util.Algorithms;
|
||||
import net.osmand.util.OpeningHoursParser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
public class QuickSearchListAdapter extends ArrayAdapter<QuickSearchListItem> {
|
||||
|
||||
private SampleApplication app;
|
||||
private Activity activity;
|
||||
|
||||
private LatLon location;
|
||||
private Float heading;
|
||||
private boolean useMapCenter;
|
||||
|
||||
private int searchMoreItemPosition;
|
||||
|
||||
private int screenOrientation;
|
||||
private int dp56;
|
||||
private int dp1;
|
||||
|
||||
private static final int ITEM_TYPE_REGULAR = 0;
|
||||
private static final int ITEM_TYPE_SEARCH_MORE = 1;
|
||||
|
||||
public interface OnSelectionListener {
|
||||
|
||||
void onUpdateSelectionMode(List<QuickSearchListItem> selectedItems);
|
||||
|
||||
void reloadData();
|
||||
}
|
||||
|
||||
public QuickSearchListAdapter(SampleApplication app, Activity activity) {
|
||||
super(app, R.layout.search_list_item);
|
||||
this.app = app;
|
||||
this.activity = activity;
|
||||
dp56 = AndroidUtils.dpToPx(app, 56f);
|
||||
dp1 = AndroidUtils.dpToPx(app, 1f);
|
||||
}
|
||||
|
||||
public int getScreenOrientation() {
|
||||
return screenOrientation;
|
||||
}
|
||||
|
||||
public void setScreenOrientation(int screenOrientation) {
|
||||
this.screenOrientation = screenOrientation;
|
||||
}
|
||||
|
||||
public LatLon getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(LatLon location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public Float getHeading() {
|
||||
return heading;
|
||||
}
|
||||
|
||||
public void setHeading(Float heading) {
|
||||
this.heading = heading;
|
||||
}
|
||||
|
||||
public boolean isUseMapCenter() {
|
||||
return useMapCenter;
|
||||
}
|
||||
|
||||
public void setUseMapCenter(boolean useMapCenter) {
|
||||
this.useMapCenter = useMapCenter;
|
||||
}
|
||||
|
||||
public void setListItems(List<QuickSearchListItem> items) {
|
||||
setNotifyOnChange(false);
|
||||
clear();
|
||||
for (QuickSearchListItem item : items) {
|
||||
add(item);
|
||||
}
|
||||
acquireAdditionalItemsPositions();
|
||||
setNotifyOnChange(true);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void addListItem(QuickSearchListItem item) {
|
||||
if (searchMoreItemPosition != -1 && item instanceof QuickSearchMoreListItem) {
|
||||
return;
|
||||
}
|
||||
setNotifyOnChange(false);
|
||||
add(item);
|
||||
acquireAdditionalItemsPositions();
|
||||
setNotifyOnChange(true);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void insertListItem(QuickSearchListItem item, int index) {
|
||||
setNotifyOnChange(false);
|
||||
insert(item, index);
|
||||
acquireAdditionalItemsPositions();
|
||||
setNotifyOnChange(true);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void acquireAdditionalItemsPositions() {
|
||||
searchMoreItemPosition = -1;
|
||||
if (getCount() > 0) {
|
||||
QuickSearchListItem first = getItem(0);
|
||||
QuickSearchListItem last = getItem(getCount() - 1);
|
||||
searchMoreItemPosition = last instanceof QuickSearchMoreListItem ? getCount() - 1 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public QuickSearchListItem getItem(int position) {
|
||||
return super.getItem(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (position == searchMoreItemPosition) {
|
||||
return ITEM_TYPE_SEARCH_MORE;
|
||||
} else {
|
||||
return ITEM_TYPE_REGULAR;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewTypeCount() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(final int position, View convertView, ViewGroup parent) {
|
||||
final QuickSearchListItem listItem = getItem(position);
|
||||
int viewType = getItemViewType(position);
|
||||
LinearLayout view;
|
||||
if (viewType == ITEM_TYPE_SEARCH_MORE) {
|
||||
if (convertView == null) {
|
||||
LayoutInflater inflater = activity.getLayoutInflater();
|
||||
view = (LinearLayout) inflater.inflate(R.layout.search_more_list_item, null);
|
||||
} else {
|
||||
view = (LinearLayout) convertView;
|
||||
}
|
||||
|
||||
((TextView) view.findViewById(R.id.title)).setText(listItem.getName());
|
||||
} else {
|
||||
if (convertView == null) {
|
||||
LayoutInflater inflater = activity.getLayoutInflater();
|
||||
view = (LinearLayout) inflater.inflate(R.layout.search_list_item, null);
|
||||
} else {
|
||||
view = (LinearLayout) convertView;
|
||||
}
|
||||
|
||||
ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
|
||||
TextView title = (TextView) view.findViewById(R.id.title);
|
||||
TextView subtitle = (TextView) view.findViewById(R.id.subtitle);
|
||||
|
||||
imageView.setImageDrawable(listItem.getIcon());
|
||||
String name = listItem.getName();
|
||||
title.setText(name);
|
||||
|
||||
String desc = listItem.getTypeName();
|
||||
boolean hasDesc = false;
|
||||
if (!Algorithms.isEmpty(desc) && !desc.equals(name)) {
|
||||
subtitle.setText(desc);
|
||||
subtitle.setVisibility(View.VISIBLE);
|
||||
hasDesc = true;
|
||||
} else {
|
||||
subtitle.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
view.findViewById(R.id.type_name_icon).setVisibility(View.GONE);
|
||||
|
||||
TextView timeText = (TextView) view.findViewById(R.id.time);
|
||||
ImageView timeIcon = (ImageView) view.findViewById(R.id.time_icon);
|
||||
if (listItem.getSearchResult().object instanceof Amenity
|
||||
&& ((Amenity) listItem.getSearchResult().object).getOpeningHours() != null) {
|
||||
Amenity amenity = (Amenity) listItem.getSearchResult().object;
|
||||
OpeningHoursParser.OpeningHours rs = OpeningHoursParser.parseOpenedHours(amenity.getOpeningHours());
|
||||
if (rs != null) {
|
||||
Calendar inst = Calendar.getInstance();
|
||||
inst.setTimeInMillis(System.currentTimeMillis());
|
||||
boolean worksNow = rs.isOpenedForTime(inst);
|
||||
inst.setTimeInMillis(System.currentTimeMillis() + 30 * 60 * 1000); // 30 minutes later
|
||||
boolean worksLater = rs.isOpenedForTime(inst);
|
||||
int colorId = worksNow ? worksLater ? R.color.color_ok : R.color.color_intermediate : R.color.color_warning;
|
||||
|
||||
timeIcon.setVisibility(View.VISIBLE);
|
||||
timeText.setVisibility(View.VISIBLE);
|
||||
timeIcon.setImageDrawable(app.getIconsCache().getIcon("ic_small_time", colorId));
|
||||
timeText.setTextColor(app.getResources().getColor(colorId));
|
||||
String rt = rs.getCurrentRuleTime(inst);
|
||||
timeText.setText(rt == null ? "" : rt);
|
||||
} else {
|
||||
timeIcon.setVisibility(View.GONE);
|
||||
timeText.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
timeIcon.setVisibility(View.GONE);
|
||||
timeText.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
updateCompassVisibility(view, listItem);
|
||||
}
|
||||
view.setBackgroundColor(app.getResources().getColor(R.color.bg_color_light));
|
||||
View divider = view.findViewById(R.id.divider);
|
||||
if (divider != null) {
|
||||
if (position == getCount() - 1) {
|
||||
divider.setVisibility(View.GONE);
|
||||
} else {
|
||||
divider.setVisibility(View.VISIBLE);
|
||||
if (position + 1 == searchMoreItemPosition) {
|
||||
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp1);
|
||||
p.setMargins(0, 0, 0 ,0);
|
||||
divider.setLayoutParams(p);
|
||||
} else {
|
||||
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp1);
|
||||
p.setMargins(dp56, 0, 0 ,0);
|
||||
divider.setLayoutParams(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
private void updateCompassVisibility(View view, QuickSearchListItem listItem) {
|
||||
View compassView = view.findViewById(R.id.compass_layout);
|
||||
Location ll = app.getLocationProvider().getLastKnownLocation();
|
||||
boolean showCompass = location != null && listItem.getSearchResult().location != null;
|
||||
boolean gpsFixed = ll != null && System.currentTimeMillis() - ll.getTime() < 1000 * 60 * 60 * 20;
|
||||
if ((gpsFixed || useMapCenter) && showCompass) {
|
||||
updateDistanceDirection(view, listItem);
|
||||
compassView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
if (!showCompass) {
|
||||
compassView.setVisibility(View.GONE);
|
||||
} else {
|
||||
compassView.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDistanceDirection(View view, QuickSearchListItem listItem) {
|
||||
TextView distanceText = (TextView) view.findViewById(R.id.distance);
|
||||
ImageView direction = (ImageView) view.findViewById(R.id.direction);
|
||||
SearchPhrase phrase = listItem.getSearchResult().requiredSearchPhrase;
|
||||
LatLon loc = location;
|
||||
if(phrase != null && useMapCenter) {
|
||||
LatLon ol = phrase.getSettings().getOriginalLocation();
|
||||
if(ol != null) {
|
||||
loc = ol;
|
||||
}
|
||||
}
|
||||
updateLocationView(useMapCenter, loc,
|
||||
heading, direction, distanceText,
|
||||
listItem.getSearchResult().location.getLatitude(),
|
||||
listItem.getSearchResult().location.getLongitude(),
|
||||
screenOrientation, app, activity);
|
||||
}
|
||||
|
||||
public static void updateLocationView(boolean useCenter, LatLon fromLoc, Float h,
|
||||
ImageView arrow, TextView txt, double toLat, double toLon,
|
||||
int screenOrientation, SampleApplication app, Context ctx) {
|
||||
updateLocationView(useCenter, fromLoc, h, arrow, 0, txt, new LatLon(toLat, toLon), screenOrientation, app, ctx, true);
|
||||
}
|
||||
|
||||
public static void updateLocationView(boolean useCenter, LatLon fromLoc, Float h,
|
||||
ImageView arrow, int arrowResId, TextView txt, LatLon toLoc,
|
||||
int screenOrientation, SampleApplication app, Context ctx, boolean paint) {
|
||||
float[] mes = new float[2];
|
||||
if (fromLoc != null && toLoc != null) {
|
||||
Location.distanceBetween(toLoc.getLatitude(), toLoc.getLongitude(), fromLoc.getLatitude(), fromLoc.getLongitude(), mes);
|
||||
}
|
||||
if (arrow != null) {
|
||||
boolean newImage = false;
|
||||
if (arrowResId == 0) {
|
||||
arrowResId = R.drawable.ic_direction_arrow;
|
||||
}
|
||||
DirectionDrawable dd;
|
||||
if(!(arrow.getDrawable() instanceof DirectionDrawable)) {
|
||||
newImage = true;
|
||||
dd = new DirectionDrawable(ctx, arrow.getWidth(), arrow.getHeight());
|
||||
} else {
|
||||
dd = (DirectionDrawable) arrow.getDrawable();
|
||||
}
|
||||
dd.setImage(arrowResId, useCenter ? R.color.color_distance : R.color.color_myloc_distance);
|
||||
if (fromLoc == null || h == null || toLoc == null) {
|
||||
dd.setAngle(0);
|
||||
} else {
|
||||
dd.setAngle(mes[1] - h + 180 + screenOrientation);
|
||||
}
|
||||
if (newImage) {
|
||||
arrow.setImageDrawable(dd);
|
||||
}
|
||||
arrow.invalidate();
|
||||
}
|
||||
if (txt != null) {
|
||||
if (fromLoc != null && toLoc != null) {
|
||||
if (paint) {
|
||||
txt.setTextColor(app.getResources().getColor(
|
||||
useCenter ? R.color.color_distance : R.color.color_myloc_distance));
|
||||
}
|
||||
txt.setText(SampleFormatter.getFormattedDistance(mes[0], app));
|
||||
} else {
|
||||
txt.setText("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,237 @@
|
|||
package net.osmand.core.samples.android.sample1.search;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.ListFragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.MainActivity;
|
||||
import net.osmand.core.samples.android.sample1.R;
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
import net.osmand.core.samples.android.sample1.SampleFormatter;
|
||||
import net.osmand.core.samples.android.sample1.SampleUtils;
|
||||
import net.osmand.core.samples.android.sample1.data.PointDescription;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.City;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.Street;
|
||||
import net.osmand.search.core.ObjectType;
|
||||
import net.osmand.search.core.SearchResult;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class QuickSearchListFragment extends ListFragment {
|
||||
|
||||
private QuickSearchDialogFragment dialogFragment;
|
||||
private QuickSearchListAdapter listAdapter;
|
||||
private boolean touching;
|
||||
private boolean scrolling;
|
||||
|
||||
enum SearchListFragmentType {
|
||||
CATEGORIES,
|
||||
MAIN
|
||||
}
|
||||
|
||||
public abstract SearchListFragmentType getType();
|
||||
|
||||
public SampleApplication getMyApplication() {
|
||||
return (SampleApplication) getActivity().getApplication();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.search_dialog_list_layout, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
ListView listView = getListView();
|
||||
if (listView != null) {
|
||||
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
|
||||
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
|
||||
}
|
||||
|
||||
public void onScrollStateChanged(AbsListView view, int scrollState) {
|
||||
scrolling = (scrollState != AbsListView.OnScrollListener.SCROLL_STATE_IDLE);
|
||||
if (scrolling) {
|
||||
dialogFragment.hideKeyboard();
|
||||
}
|
||||
}
|
||||
});
|
||||
View header = getLayoutInflater(savedInstanceState).inflate(R.layout.list_shadow_header, null);
|
||||
View footer = getLayoutInflater(savedInstanceState).inflate(R.layout.list_shadow_footer, null);
|
||||
listView.addHeaderView(header, null, false);
|
||||
listView.addFooterView(footer, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListItemClick(ListView l, View view, int position, long id) {
|
||||
int index = position - l.getHeaderViewsCount();
|
||||
if (index < listAdapter.getCount()) {
|
||||
QuickSearchListItem item = listAdapter.getItem(index);
|
||||
if (item != null) {
|
||||
if (item instanceof QuickSearchMoreListItem) {
|
||||
((QuickSearchMoreListItem) item).getOnClickListener().onClick(view);
|
||||
} else {
|
||||
SearchResult sr = item.getSearchResult();
|
||||
|
||||
if (sr.objectType == ObjectType.POI
|
||||
|| sr.objectType == ObjectType.LOCATION
|
||||
|| sr.objectType == ObjectType.HOUSE
|
||||
|| sr.objectType == ObjectType.FAVORITE
|
||||
|| sr.objectType == ObjectType.RECENT_OBJ
|
||||
|| sr.objectType == ObjectType.WPT
|
||||
|| sr.objectType == ObjectType.STREET_INTERSECTION) {
|
||||
|
||||
showOnMap(sr);
|
||||
} else {
|
||||
dialogFragment.completeQueryWithObject(item.getSearchResult());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
dialogFragment = (QuickSearchDialogFragment) getParentFragment();
|
||||
listAdapter = new QuickSearchListAdapter(getMyApplication(), getActivity());
|
||||
listAdapter.setUseMapCenter(dialogFragment.isUseMapCenter());
|
||||
setListAdapter(listAdapter);
|
||||
ListView listView = getListView();
|
||||
listView.setBackgroundColor(getResources().getColor(R.color.ctx_menu_info_view_bg_light));
|
||||
listView.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
touching = true;
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
touching = false;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public QuickSearchListAdapter getListAdapter() {
|
||||
return listAdapter;
|
||||
}
|
||||
|
||||
public ArrayAdapter<?> getAdapter() {
|
||||
return listAdapter;
|
||||
}
|
||||
|
||||
public QuickSearchDialogFragment getDialogFragment() {
|
||||
return dialogFragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
int screenOrientation = SampleUtils.getScreenOrientation(getActivity());
|
||||
listAdapter.setScreenOrientation(screenOrientation);
|
||||
dialogFragment.onSearchListFragmentResume(this);
|
||||
}
|
||||
|
||||
private void showOnMap(SearchResult searchResult) {
|
||||
if (searchResult.location != null) {
|
||||
SampleApplication app = getMyApplication();
|
||||
String lang = searchResult.requiredSearchPhrase.getSettings().getLang();
|
||||
boolean transliterate = searchResult.requiredSearchPhrase.getSettings().isTransliterate();
|
||||
PointDescription pointDescription = null;
|
||||
Object object = searchResult.object;
|
||||
switch (searchResult.objectType) {
|
||||
case POI:
|
||||
Amenity a = (Amenity) object;
|
||||
String poiSimpleFormat = SampleFormatter.getPoiStringWithoutType(a, lang, transliterate);
|
||||
pointDescription = new PointDescription(PointDescription.POINT_TYPE_POI, poiSimpleFormat);
|
||||
pointDescription.setIconName(QuickSearchListItem.getAmenityIconName(a));
|
||||
break;
|
||||
case HOUSE:
|
||||
String typeNameHouse = null;
|
||||
String name = searchResult.localeName;
|
||||
if (searchResult.relatedObject instanceof City) {
|
||||
name = ((City) searchResult.relatedObject).getName(searchResult.requiredSearchPhrase.getSettings().getLang(), true) + " " + name;
|
||||
} else if (searchResult.relatedObject instanceof Street) {
|
||||
String s = ((Street) searchResult.relatedObject).getName(searchResult.requiredSearchPhrase.getSettings().getLang(), true);
|
||||
typeNameHouse = ((Street) searchResult.relatedObject).getCity().getName(searchResult.requiredSearchPhrase.getSettings().getLang(), true);
|
||||
name = s + " " + name;
|
||||
} else if (searchResult.localeRelatedObjectName != null) {
|
||||
name = searchResult.localeRelatedObjectName + " " + name;
|
||||
}
|
||||
pointDescription = new PointDescription(PointDescription.POINT_TYPE_ADDRESS, typeNameHouse, name);
|
||||
pointDescription.setIconName("ic_action_building");
|
||||
break;
|
||||
case LOCATION:
|
||||
LatLon latLon = (LatLon) object;
|
||||
pointDescription = new PointDescription(latLon.getLatitude(), latLon.getLongitude());
|
||||
pointDescription.setIconName("ic_action_world_globe");
|
||||
break;
|
||||
case STREET_INTERSECTION:
|
||||
String typeNameIntersection = QuickSearchListItem.getTypeName(app, searchResult);
|
||||
if (Algorithms.isEmpty(typeNameIntersection)) {
|
||||
typeNameIntersection = null;
|
||||
}
|
||||
pointDescription = new PointDescription(PointDescription.POINT_TYPE_ADDRESS,
|
||||
typeNameIntersection, QuickSearchListItem.getName(app, searchResult));
|
||||
pointDescription.setIconName("ic_action_intersection");
|
||||
break;
|
||||
}
|
||||
|
||||
dialogFragment.hideToolbar();
|
||||
dialogFragment.hide();
|
||||
|
||||
getMainActivity().showOnMap(searchResult.location, searchResult.preferredZoom);
|
||||
/* todo
|
||||
getMyApplication().getSettings().setMapLocationToShow(
|
||||
searchResult.location.getLatitude(), searchResult.location.getLongitude(),
|
||||
searchResult.preferredZoom, pointDescription, true, object);
|
||||
|
||||
MapActivity.launchMapActivityMoveToTop(getActivity());
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
public MainActivity getMainActivity() {
|
||||
return (MainActivity) getActivity();
|
||||
}
|
||||
|
||||
public void updateLocation(LatLon latLon, Float heading) {
|
||||
if (listAdapter != null && !touching && !scrolling) {
|
||||
listAdapter.setLocation(latLon);
|
||||
listAdapter.setHeading(heading);
|
||||
listAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void updateListAdapter(List<QuickSearchListItem> listItems, boolean append) {
|
||||
if (listAdapter != null) {
|
||||
listAdapter.setListItems(listItems);
|
||||
if (!append) {
|
||||
getListView().setSelection(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addListItem(QuickSearchListItem listItem) {
|
||||
if (listItem != null) {
|
||||
listAdapter.addListItem(listItem);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,291 @@
|
|||
package net.osmand.core.samples.android.sample1.search;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.core.samples.android.sample1.OsmandResources;
|
||||
import net.osmand.core.samples.android.sample1.R;
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
import net.osmand.core.samples.android.sample1.SampleFormatter;
|
||||
import net.osmand.core.samples.android.sample1.data.PointDescription;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.City;
|
||||
import net.osmand.data.City.CityType;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.Street;
|
||||
import net.osmand.osm.AbstractPoiType;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.osm.PoiFilter;
|
||||
import net.osmand.osm.PoiType;
|
||||
import net.osmand.search.core.CustomSearchPoiFilter;
|
||||
import net.osmand.search.core.SearchResult;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
public class QuickSearchListItem {
|
||||
|
||||
protected SampleApplication app;
|
||||
private SearchResult searchResult;
|
||||
|
||||
public QuickSearchListItem(SampleApplication app, SearchResult searchResult) {
|
||||
this.app = app;
|
||||
this.searchResult = searchResult;
|
||||
}
|
||||
|
||||
public SearchResult getSearchResult() {
|
||||
return searchResult;
|
||||
}
|
||||
|
||||
public static String getCityTypeStr(SampleApplication ctx, CityType type) {
|
||||
switch (type) {
|
||||
case CITY:
|
||||
return ctx.getString("city_type_city");
|
||||
case TOWN:
|
||||
return ctx.getString("city_type_town");
|
||||
case VILLAGE:
|
||||
return ctx.getString("city_type_village");
|
||||
case HAMLET:
|
||||
return ctx.getString("city_type_hamlet");
|
||||
case SUBURB:
|
||||
return ctx.getString("city_type_suburb");
|
||||
case DISTRICT:
|
||||
return ctx.getString("city_type_district");
|
||||
case NEIGHBOURHOOD:
|
||||
return ctx.getString("city_type_neighbourhood");
|
||||
default:
|
||||
return ctx.getString("city_type_city");
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return getName(app, searchResult);
|
||||
}
|
||||
|
||||
public static String getName(SampleApplication app, SearchResult searchResult) {
|
||||
switch (searchResult.objectType) {
|
||||
case STREET:
|
||||
if (searchResult.localeName.endsWith(")")) {
|
||||
int i = searchResult.localeName.indexOf('(');
|
||||
if (i > 0) {
|
||||
return searchResult.localeName.substring(0, i).trim();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STREET_INTERSECTION:
|
||||
if (!Algorithms.isEmpty(searchResult.localeRelatedObjectName)) {
|
||||
return searchResult.localeName + " - " + searchResult.localeRelatedObjectName;
|
||||
}
|
||||
break;
|
||||
case LOCATION:
|
||||
LatLon latLon = (LatLon) searchResult.object;
|
||||
return PointDescription.getLocationNamePlain(app, latLon.getLatitude(), latLon.getLongitude());
|
||||
}
|
||||
return searchResult.localeName;
|
||||
}
|
||||
|
||||
public String getTypeName() {
|
||||
return getTypeName(app, searchResult);
|
||||
}
|
||||
|
||||
public static String getTypeName(SampleApplication app, SearchResult searchResult) {
|
||||
switch (searchResult.objectType) {
|
||||
case CITY:
|
||||
City city = (City) searchResult.object;
|
||||
return getCityTypeStr(app, city.getType());
|
||||
case POSTCODE:
|
||||
return app.getString("postcode");
|
||||
case VILLAGE:
|
||||
city = (City) searchResult.object;
|
||||
if (!Algorithms.isEmpty(searchResult.localeRelatedObjectName)) {
|
||||
if (searchResult.distRelatedObjectName > 0) {
|
||||
return getCityTypeStr(app, city.getType())
|
||||
+ " • "
|
||||
+ SampleFormatter.getFormattedDistance((float) searchResult.distRelatedObjectName, app)
|
||||
+ " " + app.getString("shared_string_from") + " "
|
||||
+ searchResult.localeRelatedObjectName;
|
||||
} else {
|
||||
return getCityTypeStr(app, city.getType())
|
||||
+ ", "
|
||||
+ searchResult.localeRelatedObjectName;
|
||||
}
|
||||
} else {
|
||||
return getCityTypeStr(app, city.getType());
|
||||
}
|
||||
case STREET:
|
||||
StringBuilder streetBuilder = new StringBuilder();
|
||||
if (searchResult.localeName.endsWith(")")) {
|
||||
int i = searchResult.localeName.indexOf('(');
|
||||
if (i > 0) {
|
||||
streetBuilder.append(searchResult.localeName.substring(i + 1, searchResult.localeName.length() - 1));
|
||||
}
|
||||
}
|
||||
if (!Algorithms.isEmpty(searchResult.localeRelatedObjectName)) {
|
||||
if (streetBuilder.length() > 0) {
|
||||
streetBuilder.append(", ");
|
||||
}
|
||||
streetBuilder.append(searchResult.localeRelatedObjectName);
|
||||
}
|
||||
return streetBuilder.toString();
|
||||
case HOUSE:
|
||||
if (searchResult.relatedObject != null) {
|
||||
Street relatedStreet = (Street) searchResult.relatedObject;
|
||||
if (relatedStreet.getCity() != null) {
|
||||
return searchResult.localeRelatedObjectName + ", "
|
||||
+ relatedStreet.getCity().getName(searchResult.requiredSearchPhrase.getSettings().getLang(), true);
|
||||
} else {
|
||||
return searchResult.localeRelatedObjectName;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
case STREET_INTERSECTION:
|
||||
Street street = (Street) searchResult.object;
|
||||
if (street.getCity() != null) {
|
||||
return street.getCity().getName(searchResult.requiredSearchPhrase.getSettings().getLang(), true);
|
||||
}
|
||||
return "";
|
||||
case POI_TYPE:
|
||||
String res = "";
|
||||
if (searchResult.object instanceof AbstractPoiType) {
|
||||
AbstractPoiType abstractPoiType = (AbstractPoiType) searchResult.object;
|
||||
if (abstractPoiType instanceof PoiCategory) {
|
||||
res = "";
|
||||
} else if (abstractPoiType instanceof PoiFilter) {
|
||||
PoiFilter poiFilter = (PoiFilter) abstractPoiType;
|
||||
res = poiFilter.getPoiCategory() != null ? poiFilter.getPoiCategory().getTranslation() : "";
|
||||
|
||||
} else if (abstractPoiType instanceof PoiType) {
|
||||
PoiType poiType = (PoiType) abstractPoiType;
|
||||
res = poiType.getParentType() != null ? poiType.getParentType().getTranslation() : null;
|
||||
if (res == null) {
|
||||
res = poiType.getCategory() != null ? poiType.getCategory().getTranslation() : null;
|
||||
}
|
||||
if (res == null) {
|
||||
res = "";
|
||||
}
|
||||
} else {
|
||||
res = "";
|
||||
}
|
||||
} else if (searchResult.object instanceof CustomSearchPoiFilter) {
|
||||
res = ((CustomSearchPoiFilter) searchResult.object).getName();
|
||||
}
|
||||
return res;
|
||||
case POI:
|
||||
Amenity amenity = (Amenity) searchResult.object;
|
||||
PoiCategory pc = amenity.getType();
|
||||
PoiType pt = pc.getPoiTypeByKeyName(amenity.getSubType());
|
||||
String typeStr = amenity.getSubType();
|
||||
if (pt != null) {
|
||||
typeStr = pt.getTranslation();
|
||||
} else if (typeStr != null) {
|
||||
typeStr = Algorithms.capitalizeFirstLetterAndLowercase(typeStr.replace('_', ' '));
|
||||
}
|
||||
return typeStr;
|
||||
case LOCATION:
|
||||
LatLon latLon = (LatLon) searchResult.object;
|
||||
if (searchResult.localeRelatedObjectName == null) {
|
||||
// todo
|
||||
//String locationCountry = app.getRegions().getCountryName(latLon);
|
||||
//searchResult.localeRelatedObjectName = locationCountry == null ? "" : locationCountry;
|
||||
}
|
||||
return searchResult.localeRelatedObjectName;
|
||||
case REGION:
|
||||
BinaryMapIndexReader binaryMapIndexReader = (BinaryMapIndexReader) searchResult.object;
|
||||
System.out.println(binaryMapIndexReader.getFile().getAbsolutePath() + " " + binaryMapIndexReader.getCountryName());
|
||||
break;
|
||||
case UNKNOWN_NAME_FILTER:
|
||||
break;
|
||||
}
|
||||
return searchResult.objectType.name();
|
||||
}
|
||||
|
||||
public Drawable getIcon() {
|
||||
return getIcon(app, searchResult);
|
||||
}
|
||||
|
||||
public static int getPoiTypeIconId(SampleApplication app, AbstractPoiType abstractPoiType) {
|
||||
int res = OsmandResources.getDrawableId("mx_" + abstractPoiType.getIconKeyName());
|
||||
if (res != 0) {
|
||||
return res;
|
||||
} else if (abstractPoiType instanceof PoiType) {
|
||||
res = OsmandResources.getDrawableId("mx_" + ((PoiType) abstractPoiType).getOsmTag()
|
||||
+ "_" + ((PoiType) abstractPoiType).getOsmValue());
|
||||
if (res != 0) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
if (abstractPoiType instanceof PoiType && ((PoiType) abstractPoiType).getParentType() != null) {
|
||||
return getPoiTypeIconId(app, ((PoiType) abstractPoiType).getParentType());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int getAmenityIconId(Amenity amenity) {
|
||||
int res = 0;
|
||||
PoiType st = amenity.getType().getPoiTypeByKeyName(amenity.getSubType());
|
||||
if (st != null) {
|
||||
res = OsmandResources.getDrawableId("mx_" + st.getIconKeyName());
|
||||
if (res == 0) {
|
||||
res = OsmandResources.getDrawableId("mx_" + st.getOsmTag() + "_" + st.getOsmValue());
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static String getAmenityIconName(Amenity amenity) {
|
||||
PoiType st = amenity.getType().getPoiTypeByKeyName(amenity.getSubType());
|
||||
if (st != null) {
|
||||
String id = st.getIconKeyName();
|
||||
if (OsmandResources.getDrawableId("mx_" + id) == 0) {
|
||||
id = st.getOsmTag() + "_" + st.getOsmValue();
|
||||
if (OsmandResources.getDrawableId("mx_" + id) != 0) {
|
||||
return id;
|
||||
}
|
||||
} else {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Drawable getIcon(SampleApplication app, SearchResult searchResult) {
|
||||
if (searchResult == null || searchResult.objectType == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int iconId;
|
||||
switch (searchResult.objectType) {
|
||||
case CITY:
|
||||
return app.getIconsCache().getIcon("ic_action_building_number", R.color.osmand_orange);
|
||||
case VILLAGE:
|
||||
return app.getIconsCache().getIcon("ic_action_home_dark", R.color.osmand_orange);
|
||||
case POSTCODE:
|
||||
case STREET:
|
||||
return app.getIconsCache().getIcon("ic_action_street_name", R.color.osmand_orange);
|
||||
case HOUSE:
|
||||
return app.getIconsCache().getIcon("ic_action_building", R.color.osmand_orange);
|
||||
case STREET_INTERSECTION:
|
||||
return app.getIconsCache().getIcon("ic_action_intersection", R.color.osmand_orange);
|
||||
case POI_TYPE:
|
||||
iconId = getPoiTypeIconId(app, (AbstractPoiType) searchResult.object);
|
||||
if (iconId != 0) {
|
||||
return app.getIconsCache().getOsmandIcon(iconId, R.color.osmand_orange);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
case POI:
|
||||
Amenity amenity = (Amenity) searchResult.object;
|
||||
iconId = getAmenityIconId(amenity);
|
||||
if (iconId != 0) {
|
||||
return app.getIconsCache().getOsmandIcon(iconId, R.color.osmand_orange);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
case LOCATION:
|
||||
return app.getIconsCache().getIcon("ic_action_world_globe", R.color.osmand_orange);
|
||||
case REGION:
|
||||
return app.getIconsCache().getIcon("ic_world_globe_dark", R.color.osmand_orange);
|
||||
case UNKNOWN_NAME_FILTER:
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package net.osmand.core.samples.android.sample1.search;
|
||||
|
||||
import android.view.View.OnClickListener;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
|
||||
public class QuickSearchMoreListItem extends QuickSearchListItem {
|
||||
|
||||
private String name;
|
||||
private OnClickListener onClickListener;
|
||||
|
||||
public QuickSearchMoreListItem(SampleApplication app, String name, OnClickListener onClickListener) {
|
||||
super(app, null);
|
||||
this.name = name;
|
||||
this.onClickListener = onClickListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public OnClickListener getOnClickListener() {
|
||||
return onClickListener;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
package net.osmand.core.samples.android.sample1.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.IconsCache;
|
||||
import net.osmand.core.samples.android.sample1.R;
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
|
||||
public class DirectionDrawable extends Drawable {
|
||||
Paint paintRouteDirection;
|
||||
float width;
|
||||
float height;
|
||||
Context ctx;
|
||||
private float angle;
|
||||
int resourceId = -1;
|
||||
Drawable arrowImage ;
|
||||
|
||||
public DirectionDrawable(Context ctx, float width, float height, int resourceId, int clrId) {
|
||||
this(ctx, width, height);
|
||||
IconsCache iconsCache = ((SampleApplication) ctx.getApplicationContext()).getIconsCache();
|
||||
arrowImage = iconsCache.getIcon(resourceId, clrId);
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
public DirectionDrawable(Context ctx, float width, float height) {
|
||||
this.ctx = ctx;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
paintRouteDirection = new Paint();
|
||||
paintRouteDirection.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||
paintRouteDirection.setColor(ctx.getResources().getColor(R.color.color_unknown));
|
||||
paintRouteDirection.setAntiAlias(true);
|
||||
}
|
||||
|
||||
public void setImage(int resourceId, int clrId) {
|
||||
IconsCache iconsCache = ((SampleApplication) ctx.getApplicationContext()).getIconsCache();
|
||||
arrowImage = iconsCache.getIcon(resourceId, clrId);
|
||||
this.resourceId = resourceId;
|
||||
onBoundsChange(getBounds());
|
||||
}
|
||||
|
||||
public void setImage(int resourceId) {
|
||||
IconsCache iconsCache = ((SampleApplication) ctx.getApplicationContext()).getIconsCache();
|
||||
arrowImage = iconsCache.getIcon(resourceId, 0);
|
||||
this.resourceId = resourceId;
|
||||
onBoundsChange(getBounds());
|
||||
}
|
||||
|
||||
|
||||
public void setColorId(int clrId) {
|
||||
// R.color.color_ok, R.color.color_unknown, R.color.color_warning
|
||||
if(arrowImage != null) {
|
||||
IconsCache iconsCache = ((SampleApplication) ctx.getApplicationContext()).getIconsCache();
|
||||
arrowImage = iconsCache.getIcon(resourceId, clrId);
|
||||
} else {
|
||||
paintRouteDirection.setColor(ctx.getResources().getColor(clrId));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setAngle(float angle) {
|
||||
this.angle = angle;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getIntrinsicWidth() {
|
||||
if (arrowImage != null) {
|
||||
return arrowImage.getIntrinsicWidth();
|
||||
}
|
||||
return super.getIntrinsicWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicHeight() {
|
||||
if (arrowImage != null) {
|
||||
return arrowImage.getIntrinsicHeight();
|
||||
}
|
||||
return super.getIntrinsicHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBoundsChange(Rect bounds) {
|
||||
super.onBoundsChange(bounds);
|
||||
if (arrowImage != null) {
|
||||
Rect r = bounds;
|
||||
int w = arrowImage.getIntrinsicWidth();
|
||||
int h = arrowImage.getIntrinsicHeight();
|
||||
int dx = Math.max(0, r.width() - w);
|
||||
int dy = Math.max(0, r.height() - h);
|
||||
if(r.width() == 0 && r.height() == 0) {
|
||||
arrowImage.setBounds(0, 0, w, h);
|
||||
} else {
|
||||
arrowImage.setBounds(r.left + dx / 2, r.top + dy / 2, r.right - dx / 2, r.bottom - dy / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
canvas.save();
|
||||
if (arrowImage != null) {
|
||||
Rect r = getBounds();
|
||||
canvas.rotate(angle, r.centerX(), r.centerY());
|
||||
arrowImage.draw(canvas);
|
||||
} else {
|
||||
canvas.rotate(angle, canvas.getWidth() / 2, canvas.getHeight() / 2);
|
||||
Path directionPath = createDirectionPath();
|
||||
canvas.drawPath(directionPath, paintRouteDirection);
|
||||
}
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
paintRouteDirection.setAlpha(alpha);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter cf) {
|
||||
paintRouteDirection.setColorFilter(cf);
|
||||
}
|
||||
|
||||
private Path createDirectionPath() {
|
||||
int h = 15;
|
||||
int w = 4;
|
||||
float sarrowL = 8; // side of arrow
|
||||
float harrowL = (float) Math.sqrt(2) * sarrowL; // hypotenuse of arrow
|
||||
float hpartArrowL = (harrowL - w) / 2;
|
||||
Path path = new Path();
|
||||
path.moveTo(width / 2, height - (height - h) / 3);
|
||||
path.rMoveTo(w / 2, 0);
|
||||
path.rLineTo(0, -h);
|
||||
path.rLineTo(hpartArrowL, 0);
|
||||
path.rLineTo(-harrowL / 2, -harrowL / 2); // center
|
||||
path.rLineTo(-harrowL / 2, harrowL / 2);
|
||||
path.rLineTo(hpartArrowL, 0);
|
||||
path.rLineTo(0, h);
|
||||
|
||||
DisplayMetrics dm = new DisplayMetrics();
|
||||
Matrix pathTransform = new Matrix();
|
||||
WindowManager mgr = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE);
|
||||
mgr.getDefaultDisplay().getMetrics(dm);
|
||||
pathTransform.postScale(dm.density, dm.density);
|
||||
path.transform(pathTransform);
|
||||
width *= dm.density;
|
||||
height *= dm.density;
|
||||
return path;
|
||||
}
|
||||
|
||||
}
|