Merge branch 'master' of ssh://github.com/osmandapp/Osmand into TelegramAidlUpdate

# Conflicts:
#	OsmAnd/src/net/osmand/aidl/IOsmAndAidlInterface.aidl
#	OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java
#	OsmAnd/src/net/osmand/aidl/OsmandAidlService.java
This commit is contained in:
Chumva 2018-08-30 18:30:07 +03:00
commit c0befa533f
13 changed files with 742 additions and 357 deletions

View file

@ -0,0 +1,3 @@
package net.osmand.aidl.navigation;
parcelable NavigateSearchParams;

View file

@ -0,0 +1,88 @@
package net.osmand.aidl.navigation;
import android.os.Parcel;
import android.os.Parcelable;
public class NavigateSearchParams implements Parcelable {
private String startName;
private double startLat;
private double startLon;
private String searchQuery;
private String profile;
private boolean force;
public NavigateSearchParams(String startName, double startLat, double startLon, String searchQuery, String profile, boolean force) {
this.startName = startName;
this.startLat = startLat;
this.startLon = startLon;
this.searchQuery = searchQuery;
this.profile = profile;
this.force = force;
}
public NavigateSearchParams(Parcel in) {
readFromParcel(in);
}
public static final Creator<NavigateSearchParams> CREATOR = new Creator<NavigateSearchParams>() {
@Override
public NavigateSearchParams createFromParcel(Parcel in) {
return new NavigateSearchParams(in);
}
@Override
public NavigateSearchParams[] newArray(int size) {
return new NavigateSearchParams[size];
}
};
public String getStartName() {
return startName;
}
public double getStartLat() {
return startLat;
}
public double getStartLon() {
return startLon;
}
public String getSearchQuery() {
return searchQuery;
}
public String getProfile() {
return profile;
}
public boolean isForce() {
return force;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(startName);
out.writeDouble(startLat);
out.writeDouble(startLon);
out.writeString(searchQuery);
out.writeString(profile);
out.writeByte((byte) (force ? 1 : 0));
}
private void readFromParcel(Parcel in) {
startName = in.readString();
startLat = in.readDouble();
startLon = in.readDouble();
searchQuery = in.readString();
profile = in.readString();
force = in.readByte() != 0;
}
@Override
public int describeContents() {
return 0;
}
}

View file

@ -333,7 +333,7 @@
<string name="avoid_unpaved">Saihestu asfaltatu gabeko bideak</string> <string name="avoid_unpaved">Saihestu asfaltatu gabeko bideak</string>
<string name="avoid_ferries">Saihestu ferryak</string> <string name="avoid_ferries">Saihestu ferryak</string>
<string name="avoid_in_routing_title">Saihestu…</string> <string name="avoid_in_routing_title">Saihestu…</string>
<string name="avoid_in_routing_descr">Saihestu bidesariak, asfaltatu gabekoak, ferryak.</string> <string name="avoid_in_routing_descr">Saihestu adibidez bidesariak, asfaltatu gabekoak, ferryak.</string>
<string name="map_widget_fluorescent">Ibilbide fluoreszenteak</string> <string name="map_widget_fluorescent">Ibilbide fluoreszenteak</string>
<string name="map_widget_show_ruler">Erregela</string> <string name="map_widget_show_ruler">Erregela</string>

View file

@ -368,11 +368,11 @@
<string name="local_index_transport_data">اطلاعات حمل‌ونقل عمومی</string> <string name="local_index_transport_data">اطلاعات حمل‌ونقل عمومی</string>
<string name="local_index_map_data">اطلاعات نقشه</string> <string name="local_index_map_data">اطلاعات نقشه</string>
<string name="local_indexes_cat_backup">غیرفعال</string> <string name="local_indexes_cat_backup">غیرفعال</string>
<string name="local_indexes_cat_tts">پیام‌های صوتی (ماشینی، TTS)</string> <string name="local_indexes_cat_tts">پیام‌های گفتاری (ماشینی، TTS)</string>
<string name="local_indexes_cat_voice">پیام‌های صوتی (ضبطی)</string> <string name="local_indexes_cat_voice">پیام‌های گفتاری (ضبطی)</string>
<string name="local_indexes_cat_poi">اطلاعات POI</string> <string name="local_indexes_cat_poi">اطلاعات POI</string>
<string name="ttsvoice">صدای TTS</string> <string name="ttsvoice">گفتار TTS</string>
<string name="search_offline_clear_search">جست‌وجوی جدید</string> <string name="search_offline_clear_search">جست‌وجوی جدید</string>
<string name="map_text_size_descr">اندازهٔ نوشته را برای نام‌های روی نقشه انتخاب کنید.</string> <string name="map_text_size_descr">اندازهٔ نوشته را برای نام‌های روی نقشه انتخاب کنید.</string>
<string name="map_text_size">اندازهٔ فونت نقشه</string> <string name="map_text_size">اندازهٔ فونت نقشه</string>
@ -453,8 +453,8 @@
<string name="index_name_asia">آسیا</string> <string name="index_name_asia">آسیا</string>
<string name="index_name_oceania">استرالیا و اقیانوسیه</string> <string name="index_name_oceania">استرالیا و اقیانوسیه</string>
<string name="index_name_other">نقشه‌های جهانی و بالادستی</string> <string name="index_name_other">نقشه‌های جهانی و بالادستی</string>
<string name="index_name_voice">پیام‌های صوتی (ضبطی، قابلیت محدود)</string> <string name="index_name_voice">پیام‌های گفتاری (ضبطی، قابلیت محدود)</string>
<string name="index_name_tts_voice">پیام‌های صوتی (ماشینی، TTS - بهتر)</string> <string name="index_name_tts_voice">پیام‌های گفتاری (ماشینی، TTS - بهتر)</string>
<string name="amenity_type_osmwiki">ویکی‌پدیا (آفلاین)</string> <string name="amenity_type_osmwiki">ویکی‌پدیا (آفلاین)</string>
<string name="routing_settings">راهبری</string> <string name="routing_settings">راهبری</string>
<string name="routing_settings_descr">گزینه‌های راهبری را تعریف کنید.</string> <string name="routing_settings_descr">گزینه‌های راهبری را تعریف کنید.</string>
@ -720,7 +720,7 @@
<string name="online_map_settings_descr">منبع نقشه‌های آنلاین یا کاشی‌های ذخیره‌شده را تنظیم کنید.</string> <string name="online_map_settings_descr">منبع نقشه‌های آنلاین یا کاشی‌های ذخیره‌شده را تنظیم کنید.</string>
<string name="vector_maps_may_display_faster_on_some_devices">نقشه‌های بُرداری معمولاً زودتر نمایش داده می‌شوند. شاید روی برخی دستگاه‌ها خوب کار نکند.</string> <string name="vector_maps_may_display_faster_on_some_devices">نقشه‌های بُرداری معمولاً زودتر نمایش داده می‌شوند. شاید روی برخی دستگاه‌ها خوب کار نکند.</string>
<string name="test_voice_prompts">امتحان‌کردن پیام‌های صوتی</string> <string name="test_voice_prompts">امتحان‌کردن پیام‌های گفتاری</string>
<string name="switch_to_raster_map_to_see">برای این مکان هیچ نقشهٔ بُرداری آفلاینی وجود ندارد. نقشهٔ موردنظرتان را از قسمت تنظیمات (مدیریت فایل‌های نقشه) دانلود کنید یا اینکه افزونهٔ «نقشه‌های آنلاین» را انتخاب کنید.</string> <string name="switch_to_raster_map_to_see">برای این مکان هیچ نقشهٔ بُرداری آفلاینی وجود ندارد. نقشهٔ موردنظرتان را از قسمت تنظیمات (مدیریت فایل‌های نقشه) دانلود کنید یا اینکه افزونهٔ «نقشه‌های آنلاین» را انتخاب کنید.</string>
<string name="no_info">بدون اطلاعات</string> <string name="no_info">بدون اطلاعات</string>
<string name="direction_style_clockwise">ساعت‌سو (۱۲سویه)</string> <string name="direction_style_clockwise">ساعت‌سو (۱۲سویه)</string>
@ -738,7 +738,7 @@
<string name="fav_export_confirmation">قبلاً از نقاط برگزیده یک خروجی تهیه کرده‌اید و فایلش وجود دارد. خروجی جدید را جایگزین آن می‌کنید؟</string> <string name="fav_export_confirmation">قبلاً از نقاط برگزیده یک خروجی تهیه کرده‌اید و فایلش وجود دارد. خروجی جدید را جایگزین آن می‌کنید؟</string>
<string name="osmand_development_plugin_description">به‌وسیلهٔ این افزونه می‌توانید تنظیمات توسعه‌ای و امکانات عیب‌یابی را مشاهده کنید؛ مانند شبیه‌سازی مسیریابی، آزمایش عملکرد رندر یا امتحان‌کردن پیام‌های صوتی. <string name="osmand_development_plugin_description">به‌وسیلهٔ این افزونه می‌توانید تنظیمات توسعه‌ای و امکانات عیب‌یابی را مشاهده کنید؛ مانند شبیه‌سازی مسیریابی، آزمایش عملکرد رندر یا امتحان‌کردن پیام‌های گفتاری.
\nاین تنظیمات برای توسعه‌دهندگان فراهم شده است و به‌کار کاربران عادی نمی‌آید.</string> \nاین تنظیمات برای توسعه‌دهندگان فراهم شده است و به‌کار کاربران عادی نمی‌آید.</string>
<string name="animate_route_off">پایان شبیه‌سازی</string> <string name="animate_route_off">پایان شبیه‌سازی</string>
<string name="animate_route">شروع شبیه‌سازی</string> <string name="animate_route">شروع شبیه‌سازی</string>
@ -816,7 +816,7 @@
\n \n
\n\tفعالسازی: \n\tفعالسازی:
\n\t«منو» ← «پیکربندی نقشه» ← «منبع نقشه…» ← «نقشه‌های بُرداری آفلاین».</string> \n\t«منو» ← «پیکربندی نقشه» ← «منبع نقشه…» ← «نقشه‌های بُرداری آفلاین».</string>
<string name="choose_audio_stream">خروجی راهنمای صوتی</string> <string name="choose_audio_stream">خروجی راهنمای گفتاری</string>
<string name="layer_underlay">نقشهٔ زیری…</string> <string name="layer_underlay">نقشهٔ زیری…</string>
<string name="map_underlay">نقشهٔ زیری</string> <string name="map_underlay">نقشهٔ زیری</string>
<string name="map_underlay_descr">نقشهٔ زیری را انتخاب کنید.</string> <string name="map_underlay_descr">نقشهٔ زیری را انتخاب کنید.</string>
@ -946,14 +946,14 @@
<string name="search_poi_location">در انتظار سیگنال…</string> <string name="search_poi_location">در انتظار سیگنال…</string>
<string name="search_near_map">جست‌وجو در اطراف مرکز نقشه</string> <string name="search_near_map">جست‌وجو در اطراف مرکز نقشه</string>
<string name="search_nearby">جست‌وجوی اطراف</string> <string name="search_nearby">جست‌وجوی اطراف</string>
<string name="voice_provider">راهنمای صوتی</string> <string name="voice_provider">راهنمای گفتاری</string>
<string name="menu_mute_off">صدا روشن است</string> <string name="menu_mute_off">صدا روشن است</string>
<string name="menu_mute_on">صدا خاموش است</string> <string name="menu_mute_on">صدا خاموش است</string>
<string name="voice_provider_descr">راهنمای صوتی راهبری را انتخاب کنید.</string> <string name="voice_provider_descr">راهنمای گفتاری برای راهبری را انتخاب کنید.</string>
<string name="voice_data_initializing">در حال آماده‌سازی داده‌های صوتی…</string> <string name="voice_data_initializing">در حال آماده‌سازی داده‌های گفتاری…</string>
<string name="voice_data_not_supported">این نسخه از دادهٔ صوتی پشتیبانی نمی‌شود</string> <string name="voice_data_not_supported">این نسخه از دادهٔ گفتاری پشتیبانی نمی‌شود</string>
<string name="voice_data_corrupted">دادهٔ صوتی انتخاب‌شده خراب است</string> <string name="voice_data_corrupted">دادهٔ گفتاری انتخاب‌شده خراب است</string>
<string name="voice_data_unavailable">دادهٔ صوتی انتخاب‌شده موجود نیست</string> <string name="voice_data_unavailable">دادهٔ گفتاری انتخاب‌شده موجود نیست</string>
<string name="sd_mounted_ro">کارت حافظه در حالت فقط‌خواندنی است. <string name="sd_mounted_ro">کارت حافظه در حالت فقط‌خواندنی است.
\nبا این حساب تنها می‌توانید نقشه‌هایی را ببینید که قبلاً دریافت شده‌اند و نمی‌توانید مناطق جدیدی را دانلود کنید.</string> \nبا این حساب تنها می‌توانید نقشه‌هایی را ببینید که قبلاً دریافت شده‌اند و نمی‌توانید مناطق جدیدی را دانلود کنید.</string>
<string name="process_navigation_service">سرویس راهبری OsmAnd</string> <string name="process_navigation_service">سرویس راهبری OsmAnd</string>
@ -1000,8 +1000,8 @@
<string name="loading_builds">بارگیری ساخت‌های OsmAnd…</string> <string name="loading_builds">بارگیری ساخت‌های OsmAnd…</string>
<string name="select_build_to_install">یک ساخت OsmAnd را برای نصب انتخاب کنید</string> <string name="select_build_to_install">یک ساخت OsmAnd را برای نصب انتخاب کنید</string>
<string name="gps_status_app_not_found">این برنامهٔ وضعیت GPS نصب نیست. در بازار اندروید بگردیم؟</string> <string name="gps_status_app_not_found">این برنامهٔ وضعیت GPS نصب نیست. در بازار اندروید بگردیم؟</string>
<string name="voice_is_not_available_msg">راهنمای صوتی موجود نیست. لطفاً به «تنطیمات» ← «تنظیمات راهبری» ← «راهنمای صوتی» بروید و یکی از بسته‌های پیام صوتی را انتخاب یا دانلود کنید.</string> <string name="voice_is_not_available_msg">راهنمای گفتاری موجود نیست. لطفاً به «تنطیمات» ← «تنظیمات راهبری» ← «راهنمای گفتاری» بروید و یکی از بسته‌های پیام گفتاری را انتخاب یا دانلود کنید.</string>
<string name="voice_is_not_available_title">راهنمای صوتی انتخاب نشده</string> <string name="voice_is_not_available_title">راهنمای گفتاری انتخاب نشده</string>
<string name="download_files_question">آیا {0} فایل دانلود شود ({1} مگابایت)؟</string> <string name="download_files_question">آیا {0} فایل دانلود شود ({1} مگابایت)؟</string>
<string name="filter_existing_indexes">دانلود شد</string> <string name="filter_existing_indexes">دانلود شد</string>
<string name="tiles_to_download_estimated_size">در زوم {0} تعداد {1} کاشی دانلود می‌شود ({2} مگابایت)</string> <string name="tiles_to_download_estimated_size">در زوم {0} تعداد {1} کاشی دانلود می‌شود ({2} مگابایت)</string>
@ -1019,7 +1019,7 @@
<string name="transport_search_again">تنظیم مجدد جست‌وجوی حمل‌ونقل</string> <string name="transport_search_again">تنظیم مجدد جست‌وجوی حمل‌ونقل</string>
<string name="voice">صدای ضبط‌شده</string> <string name="voice">گفتار ضبط‌شده</string>
<string name="no_vector_map_loaded">نقشه‌های بُرداری بارگیری نشدند</string> <string name="no_vector_map_loaded">نقشه‌های بُرداری بارگیری نشدند</string>
<string name="gpx_files_not_found">هیچ فایل GPXای در پوشهٔ tracks پیدا نشد</string> <string name="gpx_files_not_found">هیچ فایل GPXای در پوشهٔ tracks پیدا نشد</string>
@ -1062,36 +1062,37 @@
<string name="osmand_long_description_1000_chars">برنامهٔ OsmAnd (مخفف OSM Automated Navigation Directions به‌معنی راهبری خودکار برای OSM) یک نرم‌افزار مسیریابی متن‌باز است که به گسترهٔ وسیعی از داده‌های OSM دسترسی دارد. <string name="osmand_long_description_1000_chars">برنامهٔ OsmAnd (مخفف OSM Automated Navigation Directions به‌معنی راهبری خودکار بر پایهٔ OSM) یک نرم‌افزار مسیریابی متن‌باز است که به گسترهٔ وسیعی از داده‌های جهانی OSM دسترسی دارد.
\n \n
\nتمام داده‌های نقشه (بُرداری یا کاشی) را می‌توانید برای استفادهٔ آفلاین روی کارت حافظه ذخیره کنید. \nتمام داده‌های نقشه (بُرداری یا کاشی) را می‌توانید برای استفادهٔ آفلاین روی کارت حافظه ذخیره کنید.
\nهمچنین OsmAnd می‌تواند به‌صورت آنلاین و آفلاین و با راهنمای صوتیِ گام‌به‌گام، برایتان مسیریابی کند. \nهمچنین OsmAnd می‌تواند به‌صورت آنلاین و آفلاین مسیریابی کند و با راهنمای گفتاری شما را گام‌به‌گام هدایت کند.
\n \n
\n* از ویژگی‌های مهم: \n* از ویژگی‌های مهم:
\n- کارایی کامل در حالت آفلاین (قابلیت ذخیره‌سازی نقشه‌های بُرداری یا کاشی در حافظهٔ دستگاه) \n- کارایی کامل در حالت آفلاین (قابلیت ذخیره‌سازی نقشه‌های بُرداری یا کاشی در حافظهٔ دستگاه)
\n- وجود نقشه‌های برداری و آفلاینِ سراسر جهان به‌صورت فشرده \n- وجود نقشه‌های برداری و آفلاینِ سراسر جهان به‌صورت فشرده
\n- امکان دانلود نقشهٔ یک کشور یا منطقه مستقیماً از طریق برنامه \n- امکان دانلود نقشهٔ یک کشور یا منطقه مستقیماً از طریق برنامه
\n- امکان قراردادن نقشه‌های مختلف بر روی هم در چند لایه؛ مانند ردهای GPX یا مسیریابی، مکان‌های محبوب یا POI، نقاط برگزیده، منحنی‌های تراز، ایستگاه‌های حمل‌ونقل عمومی، نقشه‌های دیگر با درصد شفافیت دلخواه \n- امکان قراردادن نقشه‌های مختلف بر روی هم در چند لایه؛ مانند ردهای GPX یا مسیرپیمایی، مکان‌های محبوب یا POI، نقاط برگزیده، منحنی‌های تراز، ایستگاه‌های حمل‌ونقل عمومی، نقشه‌های دیگر با درصد شفافیت دلخواه
\n- جست‌وجوی آفلاین مکان‌ها (POIها) و نشانی‌ها \n- جست‌وجوی آفلاین مکان‌ها (POIها) و نشانی‌ها
\n- مسیریابی آفلاین برای مسافت‌های متوسط \n- مسیریابی آفلاین برای مسافت‌های متوسط
\n- نمایه‌های خودرو، دوچرخه و پیاده با قابلیت‌های اختیاری: \n- نمایه‌های خودرو، دوچرخه و پیاده با قابلیت‌های اختیاری:
\n. نمای خودکار شب یا روز؛ \n. نمای خودکار شب یا روز؛
\n. زوم وابسته به سرعت؛ \n. زوم وابسته به سرعت؛
\n. میزان‌کردن نقشه در جهت قطب‌نما یا در جهت حرکت؛ \n. میزان‌کردن نقشه در جهت قطب‌نما یا در جهت حرکت؛
\n. راهنمای خط عبوری، نمایش محدودیت سرعت، راهنمای صوتی انسانی یا ماشینی. \n. راهنمای خط عبوری، نمایش محدودیت سرعت، راهنمای گفتاری انسانی یا ماشینی.
\n \n
\n* محدودیت‌های این نسخهٔ رایگان از OsmAnd: \n* محدودیت‌های این نسخهٔ رایگان از OsmAnd:
\n- تعداد نقشه‌های قابل‌دانلود محدود است. \n- تعداد نقشه‌های قابل‌دانلود محدود است.
\n- به نقاط ویکی‌پدیایی به‌صورت آفلاین دسترسی ندارید. \n- به نقاط ویکی‌پدیا به‌صورت آفلاین دسترسی ندارید.
\n \n
\n* ما فعالانه در حال توسعهٔ OsmAnd هستیم و این پروژه و پیشرفت پیوستهٔ آن نیازمند کمک‌های مالی شماست تا برای توسعه و افزودن قابلیت‌های تازه هزینه کنیم. \n* ما فعالانه در حال توسعهٔ OsmAnd هستیم و این پروژه و پیشرفت پیوستهٔ آن نیازمند کمک‌های مالی شماست تا برای توسعه و افزودن قابلیت‌های تازه هزینه کنیم.
\n \n
\n* لطفاً OsmAnd+ را بخرید یا برای ویژگی‌های تازه و خاص سرمایه‌گذاری کنید. همچنین می‌توانید از طریق سایت https://osmand.net مبلغی هدیه کنید.</string> \n* لطفاً OsmAnd+ را بخرید یا برای ویژگی‌های تازه و خاص سرمایه‌گذاری کنید. همچنین می‌توانید از طریق سایت https://osmand.net مبلغی هدیه کنید.</string>
<string name="osmand_plus_long_description_1000_chars">برنامهٔ OsmAnd+ (مخفف OSM Automated Navigation Directions به‌معنی راهبری خودکار برای OSM) یک نرم‌افزار مسیریابی متن‌باز است که به گسترهٔ وسیعی از داده‌های OSM دسترسی دارد. <string name="osmand_plus_long_description_1000_chars">برنامهٔ OsmAnd (مخفف OSM Automated Navigation Directions به‌معنی راهبری خودکار بر پایهٔ OSM) یک نرم‌افزار مسیریابی متن‌باز است که به گسترهٔ وسیعی از داده‌های جهانی OSM دسترسی دارد.
\n \n
\nتمام داده‌های نقشه (بُرداری یا کاشی) را می‌توانید برای استفادهٔ آفلاین روی کارت حافظه ذخیره کنید. \nتمام داده‌های نقشه (بُرداری یا کاشی) را می‌توانید برای استفادهٔ آفلاین روی کارت حافظه ذخیره کنید.
\nهمچنین OsmAnd می‌تواند به‌صورت آنلاین و آفلاین و با راهنمای صوتیِ گام‌به‌گام، برایتان مسیریابی کند. \nهمچنین OsmAnd می‌تواند به‌صورت آنلاین و آفلاین مسیریابی کند و با راهنمای گفتاری شما را گام‌به‌گام هدایت کند.
\n
\nOsmAnd+ نسخهٔ پولی این برنامه است. با خریدن آن از این پروژه حمایت می‌کنید، سرمایه‌ای برای توسعهٔ قابلیت‌های جدید فراهم می‌کنید و آخرین به‌روزرسانی‌ها در اختیارتان قرار می‌گیرد. \nOsmAnd+ نسخهٔ پولی این برنامه است. با خریدن آن از این پروژه حمایت می‌کنید، سرمایه‌ای برای توسعهٔ قابلیت‌های جدید فراهم می‌کنید و آخرین به‌روزرسانی‌ها در اختیارتان قرار می‌گیرد.
\n \n
\n* از ویژگی‌های مهم: \n* از ویژگی‌های مهم:
@ -1099,17 +1100,17 @@
\n- وجود نقشه‌های برداری و آفلاینِ سراسر جهان به‌صورت فشرده \n- وجود نقشه‌های برداری و آفلاینِ سراسر جهان به‌صورت فشرده
\n- امکان دانلود نامحدود نقشه‌های کشوری یا منطقه‌ای مستقیماً از طریق برنامه \n- امکان دانلود نامحدود نقشه‌های کشوری یا منطقه‌ای مستقیماً از طریق برنامه
\n- دسترسی به ویکی‌پدیا به‌صورت آفلاین (دانلود POIهای ویکی‌پدیا) که برای گردشگری بسیار مفید است \n- دسترسی به ویکی‌پدیا به‌صورت آفلاین (دانلود POIهای ویکی‌پدیا) که برای گردشگری بسیار مفید است
\n \n
\n- امکان قراردادن نقشه‌های مختلف بر روی هم در چند لایه؛ مانند ردهای GPX یا مسیریابی، مکان‌های محبوب یا POI، نقاط برگزیده، منحنی‌های تراز، ایستگاه‌های حمل‌ونقل عمومی، نقشه‌های دیگر با درصد شفافیت دلخواه \n- امکان قراردادن نقشه‌های مختلف بر روی هم در چند لایه؛ مانند ردهای GPX یا مسیرپیمایی، مکان‌های محبوب یا POI، نقاط برگزیده، منحنی‌های تراز، ایستگاه‌های حمل‌ونقل عمومی، نقشه‌های دیگر با درصد شفافیت دلخواه
\n \n
\n- جست‌وجوی آفلاین مکان‌ها (POIها) و نشانی‌ها \n- جست‌وجوی آفلاین مکان‌ها (POIها) و نشانی‌ها
\n- مسیریابی آفلاین برای مسافت‌های متوسط \n- مسیریابی آفلاین برای مسافت‌های متوسط
\n- نمایه‌های خودرو، دوچرخه و پیاده با قابلیت‌های اختیاری: \n- نمایه‌های خودرو، دوچرخه و پیاده با قابلیت‌های اختیاری:
\n- نمای خودکار شب یا روز؛ \n- نمای خودکار شب یا روز؛
\n \n
\n- زوم وابسته به سرعت؛ \n- زوم وابسته به سرعت؛
\n- میزان‌کردن نقشه در جهت قطب‌نما یا در جهت حرکت؛ \n- میزان‌کردن نقشه در جهت قطب‌نما یا در جهت حرکت؛
\n- راهنمای خط عبوری، نمایش محدودیت سرعت، راهنمای صوتی انسانی یا ماشینی</string> \n- راهنمای خط عبوری، نمایش محدودیت سرعت، راهنمای گفتاری انسانی یا ماشینی</string>
<string name="asap">دراسرع‌وقت</string> <string name="asap">دراسرع‌وقت</string>
@ -1130,7 +1131,7 @@
\nhttps://openstreetmap.org \nhttps://openstreetmap.org
\n \n
\nشما هم می‌توانید مستقیماً از طریق برنامهٔ OsmAnd در تکمیل نقشه مشارکت کنید. برای این منظور لازم است اطلاعات عضویت در سایت OSM را در برنامه وارد کنید.</string> \nشما هم می‌توانید مستقیماً از طریق برنامهٔ OsmAnd در تکمیل نقشه مشارکت کنید. برای این منظور لازم است اطلاعات عضویت در سایت OSM را در برنامه وارد کنید.</string>
<string name="play_commands_of_currently_selected_voice">صدایی را انتخاب کنید و با پخش پیام‌ها، آن را امتحان کنید.</string> <string name="play_commands_of_currently_selected_voice">گفتاری را انتخاب کنید و با پخش پیام‌ها، آن را امتحان کنید.</string>
<string name="native_rendering">رندر بومی</string> <string name="native_rendering">رندر بومی</string>
<string name="accessibility_mode">حالت دسترسی آسان</string> <string name="accessibility_mode">حالت دسترسی آسان</string>
@ -1173,7 +1174,7 @@
<string name="trace_rendering">اطلاعات عیب‌یابی رندرگیری</string> <string name="trace_rendering">اطلاعات عیب‌یابی رندرگیری</string>
<string name="trace_rendering_descr">عملکرد رندرگیری را نمایش می‌دهد.</string> <string name="trace_rendering_descr">عملکرد رندرگیری را نمایش می‌دهد.</string>
<string name="choose_audio_stream_descr">بلندگوی پخش راهنمای صوتی را انتخاب کنید.</string> <string name="choose_audio_stream_descr">بلندگوی پخش راهنمای گفتاری را انتخاب کنید.</string>
<string name="voice_stream_voice_call">منبع صدای تماس تلفنی (همچنین برای وقفه‌انداختن در دستگاه پخش خودرو)</string> <string name="voice_stream_voice_call">منبع صدای تماس تلفنی (همچنین برای وقفه‌انداختن در دستگاه پخش خودرو)</string>
<string name="voice_stream_notification">منبع صدای اعلان</string> <string name="voice_stream_notification">منبع صدای اعلان</string>
<string name="voice_stream_music">منبع پخش صدای موسیقی/رسانه</string> <string name="voice_stream_music">منبع پخش صدای موسیقی/رسانه</string>
@ -1395,11 +1396,11 @@
<string name="always_center_position_on_map">موقعیت همیشه در وسط صفحه باشد</string> <string name="always_center_position_on_map">موقعیت همیشه در وسط صفحه باشد</string>
<string name="voice_pref_title">صدا</string> <string name="voice_pref_title">گفتار</string>
<string name="misc_pref_title">متفرقه</string> <string name="misc_pref_title">متفرقه</string>
<string name="localization_pref_title">بومی‌سازی</string> <string name="localization_pref_title">بومی‌سازی</string>
<string name="interrupt_music_descr">هنگام اعلام پیام‌های صوتی، پخش موسیقی نگه داشته شود، نه اینکه فقط آهسته شود.</string> <string name="interrupt_music_descr">هنگام بیان پیام‌های گفتاری، پخش موسیقی نگه داشته شود، نه اینکه فقط آهسته شود.</string>
<string name="interrupt_music">مکث موسیقی</string> <string name="interrupt_music">مکث موسیقی</string>
<string name="share_route_as_gpx">اشتراک‌گذاری مسیر در قالب فایل GPX</string> <string name="share_route_as_gpx">اشتراک‌گذاری مسیر در قالب فایل GPX</string>
<string name="share_route_subject">مسیر از طریق OsmAnd به‌اشتراک گذاشته شد</string> <string name="share_route_subject">مسیر از طریق OsmAnd به‌اشتراک گذاشته شد</string>
@ -1641,7 +1642,7 @@
<string name="shared_string_currently_recording_track">مسیر در حال ضبط</string> <string name="shared_string_currently_recording_track">مسیر در حال ضبط</string>
<string name="back_to_map">برگشتن به نقشه</string> <string name="back_to_map">برگشتن به نقشه</string>
<string name="plugin_touringview_name">نمای گشتی نقشه</string> <string name="plugin_touringview_name">نمای گشتی نقشه</string>
<string name="shared_string_audio">صدا</string> <string name="shared_string_audio">شنیداری</string>
<string name="share_note">به‌اشتراک‌گذاری یادداشت</string> <string name="share_note">به‌اشتراک‌گذاری یادداشت</string>
@ -1770,9 +1771,9 @@
<string name="shared_string_enabled">فعال</string> <string name="shared_string_enabled">فعال</string>
<string name="shared_string_disabled">غیرفعال</string> <string name="shared_string_disabled">غیرفعال</string>
<string name="shared_string_export">صادرکردن</string> <string name="shared_string_export">صادرکردن</string>
<string name="voices">پیام‌های صوتی</string> <string name="voices">پیام‌های گفتاری</string>
<string name="local_index_description">هر موردی را لمس کنید تا توضیحات بیشتری ببینید، برای غیرفعال یا پاک‌کردن لمس کنید و نگه دارید. داده‌های فعلی روی دستگاه (%1$s آزاد):</string> <string name="local_index_description">هر موردی را لمس کنید تا توضیحات بیشتری ببینید، برای غیرفعال یا پاک‌کردن لمس کنید و نگه دارید. داده‌های فعلی روی دستگاه (%1$s آزاد):</string>
<string name="speed_limit_exceed_message">محدودهٔ حداکثر سرعت را انتخاب کنید؛ با گذشتن از این مقدار، هشدار صوتی خواهید شنید.</string> <string name="speed_limit_exceed_message">محدودهٔ حداکثر سرعت را انتخاب کنید؛ با گذشتن از این مقدار، آوای هشدار پخش می‌شود.</string>
<string name="fav_point_emoticons_message">نام نقطهٔ برگزیده به %1$s تغییر کرد تا ذخیره‌سازی آن به‌همراه شکلک‌ها در فایل تسهیل شود.</string> <string name="fav_point_emoticons_message">نام نقطهٔ برگزیده به %1$s تغییر کرد تا ذخیره‌سازی آن به‌همراه شکلک‌ها در فایل تسهیل شود.</string>
<string name="rendering_attr_hideHouseNumbers_name">پلاک خانه‌ها</string> <string name="rendering_attr_hideHouseNumbers_name">پلاک خانه‌ها</string>
<string name="application_dir_change_warning3">فایل‌های دادهٔ OsmAnd به مکان جدید کپی شود؟</string> <string name="application_dir_change_warning3">فایل‌های دادهٔ OsmAnd به مکان جدید کپی شود؟</string>
@ -2266,8 +2267,8 @@
<string name="rec_split_storage_size_desc">مقدار فضای قابل‌تصرف برای همهٔ کلیپ‌های ضبط‌شده را مشخص کنید.</string> <string name="rec_split_storage_size_desc">مقدار فضای قابل‌تصرف برای همهٔ کلیپ‌های ضبط‌شده را مشخص کنید.</string>
<string name="live_updates">به‌روزرسانی‌های پویا</string> <string name="live_updates">به‌روزرسانی‌های پویا</string>
<string name="available_maps">نقشه‌های موجود</string> <string name="available_maps">نقشه‌های موجود</string>
<string name="select_voice_provider">راهنمای صوتی را انتخاب کنید</string> <string name="select_voice_provider">راهنمای گفتاری را انتخاب کنید</string>
<string name="select_voice_provider_descr">راهنمای صوتی زبان خودتان را انتخاب یا دانلود کنید.</string> <string name="select_voice_provider_descr">راهنمای گفتاری برای زبان خود را انتخاب یا دانلود کنید.</string>
<string name="impassable_road_desc">جاده‌هایی که می‌خواهید در مسیریابی نباشند را انتخاب کنید.</string> <string name="impassable_road_desc">جاده‌هایی که می‌خواهید در مسیریابی نباشند را انتخاب کنید.</string>
<string name="no_location_permission">برنامه اجازهٔ دسترسی به موقعیت مکانی ندارد.</string> <string name="no_location_permission">برنامه اجازهٔ دسترسی به موقعیت مکانی ندارد.</string>
<string name="no_camera_permission">برنامه اجازهٔ دسترسی به دوربین ندارد.</string> <string name="no_camera_permission">برنامه اجازهٔ دسترسی به دوربین ندارد.</string>
@ -2496,9 +2497,9 @@
<string name="quick_action_take_video_note">یادداشت ویدئویی جدید</string> <string name="quick_action_take_video_note">یادداشت ویدئویی جدید</string>
<string name="quick_action_take_photo_note">یادداشت عکسی جدید</string> <string name="quick_action_take_photo_note">یادداشت عکسی جدید</string>
<string name="quick_action_add_osm_bug">افزودن توضیح ویرایشی</string> <string name="quick_action_add_osm_bug">افزودن توضیح ویرایشی</string>
<string name="quick_action_navigation_voice">صدا روشن/خاموش</string> <string name="quick_action_navigation_voice">گفتار روشن/خاموش</string>
<string name="quick_action_navigation_voice_off">صدا خاموش است</string> <string name="quick_action_navigation_voice_off">گفتار خاموش است</string>
<string name="quick_action_navigation_voice_on">صدا روشن است</string> <string name="quick_action_navigation_voice_on">گفتار روشن است</string>
<string name="quick_action_add_parking">افزودن جای پارک</string> <string name="quick_action_add_parking">افزودن جای پارک</string>
<string name="quick_action_new_action">افزودن عملیات</string> <string name="quick_action_new_action">افزودن عملیات</string>
<string name="quick_action_edit_action">اصلاح عملیات</string> <string name="quick_action_edit_action">اصلاح عملیات</string>
@ -2513,7 +2514,7 @@
<string name="quick_action_take_photo_note_descr">با لمس این دکمهٔ عملیاتی یک یادداشت تصویری در مرکز صفحه ایجاد می‌شود.</string> <string name="quick_action_take_photo_note_descr">با لمس این دکمهٔ عملیاتی یک یادداشت تصویری در مرکز صفحه ایجاد می‌شود.</string>
<string name="quick_action_add_osm_bug_descr">با لمس این دکمهٔ عملیاتی یک توضیح ویرایشی OSM در مرکز صفحه ایجاد می‌شود.</string> <string name="quick_action_add_osm_bug_descr">با لمس این دکمهٔ عملیاتی یک توضیح ویرایشی OSM در مرکز صفحه ایجاد می‌شود.</string>
<string name="quick_action_add_poi_descr">با لمس این دکمهٔ عملیاتی یک مکان POI در مرکز صفحه ایجاد می‌شود.</string> <string name="quick_action_add_poi_descr">با لمس این دکمهٔ عملیاتی یک مکان POI در مرکز صفحه ایجاد می‌شود.</string>
<string name="quick_action_navigation_voice_descr">با لمس این دکمهٔ عملیاتی، راهنمای صوتی در زمان راهبری فعال یا غیرفعال می‌شود.</string> <string name="quick_action_navigation_voice_descr">با لمس این دکمهٔ عملیاتی، راهنمای گفتاری در زمان راهبری فعال یا غیرفعال می‌شود.</string>
<string name="quick_action_add_parking_descr">با لمس این دکمهٔ عملیاتی یک جای پارک در مرکز صفحه علامت‌گذاری می‌شود.</string> <string name="quick_action_add_parking_descr">با لمس این دکمهٔ عملیاتی یک جای پارک در مرکز صفحه علامت‌گذاری می‌شود.</string>
<string name="favorite_autofill_toast_text">" اینجا ذخیره شد: "</string> <string name="favorite_autofill_toast_text">" اینجا ذخیره شد: "</string>
<string name="favorite_empty_place_name">مکان</string> <string name="favorite_empty_place_name">مکان</string>
@ -2754,12 +2755,12 @@
<string name="plugin_ski_descr">با این افزونه اطلاعات جهانی سراشیبی‌های اسکی، مسابقات اسکی صحرایی، مسیرهای اسکی آلپاین، تله‌کابین‌ها و نقاله‌های اسکی کاملاً در اختیارتان است. مسیرها و پیست‌ها بر اساس دشواری رنگ‌بندی شده‌اند که در یک سبک زمستانی ارائه می‌شوند تا نمایی همگون با محیط زمستانی را برایتان ایجاد کند. <string name="plugin_ski_descr">با این افزونه اطلاعات جهانی سراشیبی‌های اسکی، مسابقات اسکی صحرایی، مسیرهای اسکی آلپاین، تله‌کابین‌ها و نقاله‌های اسکی کاملاً در اختیارتان است. مسیرها و پیست‌ها بر اساس دشواری رنگ‌بندی شده‌اند که در یک سبک زمستانی ارائه می‌شوند تا نمایی همگون با محیط زمستانی را برایتان ایجاد کند.
\n \n
\nبا فعال‌کردن این نما، سبک نقشه به «زمستان و اسکی» تغییر می‌کند که همهٔ خصوصیات زمین را با ظاهر زمستانی نشان می‌دهد. برای غیرفعال‌کردن این نما افزونه را غیرفعال کنید یا اینکه از طریق منو ← پیکربندی نقشه ← سبک نقشه، سبک دلخواهتان را انتخاب کنید.</string> \nبا فعال‌کردن این نما، سبک نقشه به «زمستان و اسکی» تغییر می‌کند که همهٔ خصوصیات زمین را با ظاهر زمستانی نشان می‌دهد. برای غیرفعال‌کردن این نما افزونه را غیرفعال کنید یا اینکه از طریق منو ← پیکربندی نقشه ← سبک نقشه، سبک دلخواهتان را انتخاب کنید.</string>
<string name="osmand_extended_description_part1">برنامهٔ OsmAnd (مخفف OSM Automated Navigation Directions به‌معنی راهبری خودکار با نقشهٔ OSM) یک نرم‌افزار نقشه و راهبری است که به گسترهٔ وسیعی از داده‌های نقشهٔ باز شهری (OpenStreetMap یا به‌صورت خلاصه OSM) دسترسی دارد. این داده‌های رایگان و جهانی با بالاترین کیفیت ارائه می‌شوند. <string name="osmand_extended_description_part1">برنامهٔ OsmAnd (مخفف OSM Automated Navigation Directions به‌معنی راهبری خودکار بر پایهٔ OSM) یک نرم‌افزار نقشه و راهبری است که به گسترهٔ وسیعی از داده‌های نقشهٔ باز شهری (OpenStreetMap یا به‌صورت خلاصه OSM) دسترسی دارد. این داده‌های رایگان و جهانی با بالاترین کیفیت ارائه می‌شوند.
\n \n
\nراهبر دیداری و شنیداری، مشاهدهٔ مکان‌های محبوب (POIها یا Points of interest)، ایجاد و مدیریت ردهای GPX، استفاده از تصویرسازی منحنی‌های تراز و اطلاعات ارتفاع (با استفاده از افزونه)، انتخاب حالت‌های پیاده، دوچرخه، خودرو، امکان ویرایش مکان‌ها و... چیزهایی هستند که تجربهٔ مؤثر و لذت‌بخشی در کار با نقشه را برایتان به ارمغان می‌آورند.</string> \nراهبر دیداری و شنیداری، مشاهدهٔ مکان‌های محبوب (POIها یا Points of interest)، ایجاد و مدیریت ردهای GPX، استفاده از تصویرسازی منحنی‌های تراز و اطلاعات ارتفاع (با استفاده از افزونه)، انتخاب حالت‌های پیاده، دوچرخه، خودرو، امکان ویرایش مکان‌ها و... چیزهایی هستند که تجربهٔ مؤثر و لذت‌بخشی در کار با نقشه را برایتان به ارمغان می‌آورند.</string>
<string name="osmand_extended_description_part2">راهبری با GPS <string name="osmand_extended_description_part2">راهبری با GPS
\n • امکان انتخاب بین حالت آنلاین و آفلاین؛ در حالت آفلاین هزینهٔ دیگری بابت اینترنت نمی‌پردازید و در حالت آنلاین عملکرد سریع‌تری را تجربه می‌کنید \n • امکان انتخاب بین حالت آنلاین و آفلاین؛ در حالت آفلاین هزینهٔ دیگری بابت اینترنت نمی‌پردازید و در حالت آنلاین عملکرد سریع‌تری را تجربه می‌کنید
\n • راهنمای گام‌به‌گام صوتی که در پیمودن مسیر راهنمایی‌تان می‌کند (با پیام‌های صوتی انسانی و ماشینی) \n • راهنمای گام‌به‌گام گفتاری که در پیمودن مسیر راهنمایی‌تان می‌کند (با پیام‌های گفتاری انسانی و ماشینی)
\n • اگر از مسیر منحرف شوید، مسیر جدیدی برایتان پیدا می‌کند \n • اگر از مسیر منحرف شوید، مسیر جدیدی برایتان پیدا می‌کند
\n • راهنمای خطوط عبوری، نام خیابان‌ها و زمان تخمینی رسیدن را دریافت می‌کنید که در طول مسیر راهنمای شماست \n • راهنمای خطوط عبوری، نام خیابان‌ها و زمان تخمینی رسیدن را دریافت می‌کنید که در طول مسیر راهنمای شماست
\n • برای داشتن سفری ایمن‌تر، حالات شب/روز به‌صورت خودکار انتخاب می‌شود \n • برای داشتن سفری ایمن‌تر، حالات شب/روز به‌صورت خودکار انتخاب می‌شود
@ -2801,12 +2802,12 @@
<string name="av_locations_descr">فایل GPX از مکان‌های یادداشت‌دار.</string> <string name="av_locations_descr">فایل GPX از مکان‌های یادداشت‌دار.</string>
<string name="osmand_plus_extended_description_part1">برنامهٔ OsmAnd+ (مخفف OSM Automated Navigation Directions به‌معنی راهبری خودکار با نقشهٔ OSM) یک نرم‌افزار نقشه و راهبری است که به گسترهٔ وسیعی از داده‌های نقشهٔ باز شهری (OpenStreetMap یا به‌صورت خلاصه OSM) دسترسی دارد. این داده‌های رایگان و جهانی با بالاترین کیفیت ارائه می‌شوند. <string name="osmand_plus_extended_description_part1">برنامهٔ OsmAnd+ (مخفف OSM Automated Navigation Directions به‌معنی راهبری خودکار بر پایهٔ OSM) یک نرم‌افزار نقشه و راهبری است که به گسترهٔ وسیعی از داده‌های نقشهٔ باز شهری (OpenStreetMap یا به‌صورت خلاصه OSM) دسترسی دارد. این داده‌های رایگان و جهانی با بالاترین کیفیت ارائه می‌شوند.
\n \n
\nراهبر دیداری و شنیداری، مشاهدهٔ مکان‌های محبوب (POIها یا Points of interest)، ایجاد و مدیریت ردهای GPX، استفاده از تصویرسازی منحنی‌های تراز و اطلاعات ارتفاع، انتخاب حالت‌های پیاده، دوچرخه، خودرو، امکان ویرایش مکان‌ها و... چیزهایی هستند که تجربهٔ مؤثر و لذت‌بخشی را در کار با نقشه برایتان به ارمغان می‌آورد. \nراهبر دیداری و شنیداری، مشاهدهٔ مکان‌های محبوب (POIها یا Points of interest)، ایجاد و مدیریت ردهای GPX، استفاده از تصویرسازی منحنی‌های تراز و اطلاعات ارتفاع، انتخاب حالت‌های پیاده، دوچرخه، خودرو، امکان ویرایش مکان‌ها و... چیزهایی هستند که تجربهٔ مؤثر و لذت‌بخشی را در کار با نقشه برایتان به ارمغان می‌آورد.
\n \n
\nOsmAnd+ نسخهٔ پولی این برنامه است. با خریدن آن از این پروژه حمایت می‌کنید، سرمایه‌ای برای توسعهٔ قابلیت‌های جدید فراهم می‌کنید و آخرین به‌روزرسانی‌ها در اختیارتان قرار می‌گیرد. \nOsmAnd+ نسخهٔ پولی این برنامه است. با خریدن آن از این پروژه حمایت می‌کنید، سرمایه‌ای برای توسعهٔ قابلیت‌های جدید فراهم می‌کنید و آخرین به‌روزرسانی‌ها در اختیارتان قرار می‌گیرد.
\n \n
\nاز ویژگی‌های مهم برنامه:</string> \nاز ویژگی‌های مهم برنامه:</string>
<string name="plugin_touringview_descr">با فعال‌کردن این نما سبک نقشهٔ OsmAnd به نمای گردشگری (Touring view) تغییر می‌کند که سبکی با جزئیات فراوان و مناسب برای مسافران و رانندگان حرفه‌ای است. <string name="plugin_touringview_descr">با فعال‌کردن این نما سبک نقشهٔ OsmAnd به نمای گردشگری (Touring view) تغییر می‌کند که سبکی با جزئیات فراوان و مناسب برای مسافران و رانندگان حرفه‌ای است.
\n \n
@ -2855,12 +2856,12 @@
\n • جنوبگان: * \n • جنوبگان: *
\nبا این نرم‌افزار نقشهٔ بیشتر مناطق جهان را خواهید یافت! \nبا این نرم‌افزار نقشهٔ بیشتر مناطق جهان را خواهید یافت!
\nاز یک مسیریاب معتبر و قابل‌اعتماد استفاده کنید. هر کجا که هستید؛ در فرانسه، آلمان، انگلستان، مکزیک، آمریکا، هلند، ایران، روسیه، برزیل یا هر جای دیگر، فرقی نمی‌کند.</string> \nاز یک مسیریاب معتبر و قابل‌اعتماد استفاده کنید. هر کجا که هستید؛ در فرانسه، آلمان، انگلستان، مکزیک، آمریکا، هلند، ایران، روسیه، برزیل یا هر جای دیگر، فرقی نمی‌کند.</string>
<string name="osmand_plus_extended_description_part2">راهبری <string name="osmand_plus_extended_description_part2">راهبری
\n • امکان انتخاب بین حالت آنلاین (سریع) و آفلاین (بدون هزینهٔ اضافی بابت اینترنت) \n • امکان انتخاب بین حالت آنلاین (سریع) و آفلاین (بدون هزینهٔ اضافی بابت اینترنت)
\n • راهنمای گام‌به‌گام صوتی (پیام‌های صوتی انسانی و ماشینی) \n • راهنمای گام‌به‌گام گفتاری (پیام‌های گفتاری انسانی و ماشینی)
\n • راهنمای خطوط عبوری، نام خیابان‌ها و زمان تخمینی رسیدن \n • راهنمای خطوط عبوری، نام خیابان‌ها و زمان تخمینی رسیدن
\n • پشتیبانی از نقاط بین‌راهی مسیر \n • پشتیبانی از نقاط بین‌راهی مسیر
\n • اگر از مسیر منحرف شوید، مسیر جدیدی برایتان پیدا می‌کند \n • اگر از مسیر منحرف شوید، مسیر جدیدی برایتان پیدا می‌کند
\n • جست‌وجو با استفاده از نشانی، نوع مکان (مثلاً پارکینگ، رستوران، هتل، پمپ گاز، موزه) یا مختصات جغرافیایی</string> \n • جست‌وجو با استفاده از نشانی، نوع مکان (مثلاً پارکینگ، رستوران، هتل، پمپ گاز، موزه) یا مختصات جغرافیایی</string>
<string name="osmand_plus_extended_description_part8">پوشش و کیفیت تقریبی نقشه: <string name="osmand_plus_extended_description_part8">پوشش و کیفیت تقریبی نقشه:
\nاروپای غربی: **** \nاروپای غربی: ****
@ -3190,5 +3191,5 @@
\n • اصلاح مشکلاتی دیگر \n • اصلاح مشکلاتی دیگر
\n \n
\n"</string> \n"</string>
<string name="test_voice_desrc">روی یکی از دکمه‌ها بزنید و فرمان صوتی متناظر با آن را بشنوید تا فرمان‌های مشکل‌دار یا ناموجود را شناسایی کنید.</string> <string name="test_voice_desrc">روی یکی از دکمه‌ها بزنید و فرمان گفتاری متناظر با آن را بشنوید تا فرمان‌های مشکل‌دار یا ناموجود را شناسایی کنید.</string>
</resources> </resources>

View file

@ -1180,7 +1180,7 @@ Sólsetur: %2$s</string>
<string name="avoid_unpaved">Forðast vegi með óbundnu slitlagi</string> <string name="avoid_unpaved">Forðast vegi með óbundnu slitlagi</string>
<string name="avoid_ferries">Forðast ferjur</string> <string name="avoid_ferries">Forðast ferjur</string>
<string name="avoid_in_routing_title">Forðast…</string> <string name="avoid_in_routing_title">Forðast…</string>
<string name="avoid_in_routing_descr">Forðast gjaldskyldu, óbundið slitlag, ferjur.</string> <string name="avoid_in_routing_descr">Forðast t.d. gjaldskyldu, óbundið slitlag, ferjur.</string>
<string name="map_widget_transparent">Gegnsæir viðmótshlutar</string> <string name="map_widget_transparent">Gegnsæir viðmótshlutar</string>
<string name="bg_service_sleep_mode_off">Keyra <string name="bg_service_sleep_mode_off">Keyra
forrit í bakgrunni</string> forrit í bakgrunni</string>
@ -2938,19 +2938,21 @@ Stendur fyrir svæði: %1$s x %2$s</string>
<string name="coord_input_save_as_track_descr">Þú bættir við %1$s punktum. Settu inn heitið á skránni og vistaðu.</string> <string name="coord_input_save_as_track_descr">Þú bættir við %1$s punktum. Settu inn heitið á skránni og vistaðu.</string>
<string name="shared_string_world">Veröld</string> <string name="shared_string_world">Veröld</string>
<string name="point_deleted">Punkti %1$s eytt</string> <string name="point_deleted">Punkti %1$s eytt</string>
<string name="release_3_1">• Leiðsögn: Framvindustika lagfærð, hraðari víxl á upphafi og enda leiða <string name="release_3_1">"• Leiðsögn: Framvindustika lagfærð, hraðari víxl á upphafi og enda leiða
\n
\n • Kortamerki: lagfæring á að kveikja/slökkva á hópum, hægt að fela merki á korti
\n
\n • OSM-breytingar: Hægt að breyta merkjum á atriðum sem ekki eru punktar, lagfæring á þegar athugasemdir vantar á minnispunkta, öryggisafritun breytinga
\n
\n • Bæting á þáttun Wikipedia og Wikivoyage, uppfærðar skrár eru þegar tiltækar
\n
\n • Samhengisvalmynd: lagfæring á samgöngumerkingum í næturham, lagfæring á stærðum viðbótarvalmynda
\n
\n • Siglingaleiðsögn: stuðningur við merktar siglingaleiðir
\n \n
\n • Kortamerki: lagfæring á að kveikja/slökkva á hópum, hægt að fela merki á korti \n • Lagfæringar á öðrum göllum
\n \n
\n • OSM-breytingar: Hægt að breyta merkjum á atriðum sem ekki eru punktar, lagfæring á þegar athugasemdir vantar á minnispunkta, öryggisafritun breytinga \n"</string>
\n
\n • Bæting á þáttun Wikipedia og Wikivoyage, uppfærðar skrár eru þegar tiltækar
\n
\n • Samhengisvalmynd: lagfæring á samgöngumerkingum í næturham, lagfæring á stærðum viðbótarvalmynda
\n
\n • Lagfæringar á öðrum göllum
\n
\n</string>
<string name="increase_search_radius_to">Auka radíus leitar í %1$s</string> <string name="increase_search_radius_to">Auka radíus leitar í %1$s</string>
<string name="send_search_query_description">Við munum senda leitarfyrirspurn þína: <b>\"%1$s\"</b>, ásamt staðsetningu þinni.<br/><br/> Við söfnum ekki persónulegum upplýsingum, við þurfum einfaldlega þessi gögn til að bæta útreikninga leitarinnar.<br/></string> <string name="send_search_query_description">Við munum senda leitarfyrirspurn þína: <b>\"%1$s\"</b>, ásamt staðsetningu þinni.<br/><br/> Við söfnum ekki persónulegum upplýsingum, við þurfum einfaldlega þessi gögn til að bæta útreikninga leitarinnar.<br/></string>
<string name="search_no_results_description">Engar niðurstöður? <string name="search_no_results_description">Engar niðurstöður?
@ -2961,4 +2963,5 @@ Stendur fyrir svæði: %1$s x %2$s</string>
<string name="search_no_results_feedback">Engar leitarniðurstöður? <string name="search_no_results_feedback">Engar leitarniðurstöður?
\nLáttu okkur vita</string> \nLáttu okkur vita</string>
<string name="commiting_way">Sendi leið inn…</string> <string name="commiting_way">Sendi leið inn…</string>
</resources> <string name="test_voice_desrc">Bankaðu á hnapp og hlustaðu á samsvarandi raddskipun til að bera kennsl á fyrirmæli sem vantar eða sem eru skemmd.</string>
</resources>

View file

@ -3095,4 +3095,6 @@ voor Gebied: %1$s x %2$s</string>
<string name="show_guide_line_descr">"Toon rechte lijnen van je positie nasr de actieve Markeervlaggetjes. "</string> <string name="show_guide_line_descr">"Toon rechte lijnen van je positie nasr de actieve Markeervlaggetjes. "</string>
<string name="show_arrows_descr">Toon pijlen richting de actieve Markeervlaggetjes.</string> <string name="show_arrows_descr">Toon pijlen richting de actieve Markeervlaggetjes.</string>
<string name="waypoints_added_to_map_markers">"Routepunten: toegevoegd aan Markeervlaggetjes "</string> <string name="waypoints_added_to_map_markers">"Routepunten: toegevoegd aan Markeervlaggetjes "</string>
</resources> <string name="access_intermediate_arrival_time">Aankomsttijd Tussempunt</string>
<string name="map_widget_intermediate_time">Tijd tot Tussenpunt</string>
</resources>

View file

@ -65,6 +65,7 @@ import net.osmand.aidl.IOsmAndAidlCallback;
import net.osmand.aidl.search.SearchResult; import net.osmand.aidl.search.SearchResult;
import net.osmand.aidl.search.SearchParams; import net.osmand.aidl.search.SearchParams;
import net.osmand.aidl.navigation.NavigateSearchParams;
// NOTE: Add new methods at the end of file!!! // NOTE: Add new methods at the end of file!!!
@ -128,6 +129,7 @@ interface IOsmAndAidlInterface {
boolean unmuteNavigation(in UnmuteNavigationParams params); boolean unmuteNavigation(in UnmuteNavigationParams params);
boolean search(in SearchParams params, IOsmAndAidlCallback callback); boolean search(in SearchParams params, IOsmAndAidlCallback callback);
boolean navigateSearch(in NavigateSearchParams params);
boolean registerForUpdates(in long updateTimeMS, IOsmAndAidlCallback callback); boolean registerForUpdates(in long updateTimeMS, IOsmAndAidlCallback callback);
boolean unregisterFromUpdates(in IOsmAndAidlCallback callback); boolean unregisterFromUpdates(in IOsmAndAidlCallback callback);

View file

@ -19,6 +19,7 @@ import android.view.View;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import net.osmand.IndexConstants; import net.osmand.IndexConstants;
import net.osmand.Location;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.aidl.favorite.AFavorite; import net.osmand.aidl.favorite.AFavorite;
import net.osmand.aidl.favorite.group.AFavoriteGroup; import net.osmand.aidl.favorite.group.AFavoriteGroup;
@ -29,7 +30,6 @@ import net.osmand.aidl.maplayer.AMapLayer;
import net.osmand.aidl.maplayer.point.AMapPoint; import net.osmand.aidl.maplayer.point.AMapPoint;
import net.osmand.aidl.mapmarker.AMapMarker; import net.osmand.aidl.mapmarker.AMapMarker;
import net.osmand.aidl.mapwidget.AMapWidget; import net.osmand.aidl.mapwidget.AMapWidget;
import net.osmand.aidl.search.SearchParams;
import net.osmand.aidl.search.SearchResult; import net.osmand.aidl.search.SearchResult;
import net.osmand.data.FavouritePoint; import net.osmand.data.FavouritePoint;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
@ -48,14 +48,14 @@ import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.MapMarkersHelper.MapMarker; import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.audionotes.AudioVideoNotesPlugin; import net.osmand.plus.audionotes.AudioVideoNotesPlugin;
import net.osmand.plus.dialogs.ConfigureMapMenu; import net.osmand.plus.dialogs.ConfigureMapMenu;
import net.osmand.plus.helpers.ColorDialogs; import net.osmand.plus.helpers.ColorDialogs;
import net.osmand.plus.helpers.ExternalApiHelper;
import net.osmand.plus.monitoring.OsmandMonitoringPlugin; import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.search.listitems.QuickSearchListItem;
import net.osmand.plus.views.AidlMapLayer; import net.osmand.plus.views.AidlMapLayer;
import net.osmand.plus.views.MapInfoLayer; import net.osmand.plus.views.MapInfoLayer;
import net.osmand.plus.views.OsmandMapLayer; import net.osmand.plus.views.OsmandMapLayer;
@ -63,10 +63,6 @@ import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.plus.views.mapwidgets.MapWidgetRegistry.MapWidgetRegInfo; import net.osmand.plus.views.mapwidgets.MapWidgetRegistry.MapWidgetRegInfo;
import net.osmand.plus.views.mapwidgets.TextInfoWidget; import net.osmand.plus.views.mapwidgets.TextInfoWidget;
import net.osmand.search.SearchUICore;
import net.osmand.search.SearchUICore.SearchResultCollection;
import net.osmand.search.core.ObjectType;
import net.osmand.search.core.SearchSettings;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -82,6 +78,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@ -90,15 +87,6 @@ import java.util.Map;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import static net.osmand.search.core.ObjectType.CITY;
import static net.osmand.search.core.ObjectType.HOUSE;
import static net.osmand.search.core.ObjectType.POI;
import static net.osmand.search.core.ObjectType.POSTCODE;
import static net.osmand.search.core.ObjectType.STREET;
import static net.osmand.search.core.ObjectType.STREET_INTERSECTION;
import static net.osmand.search.core.ObjectType.VILLAGE;
import static net.osmand.search.core.SearchCoreFactory.MAX_DEFAULT_SEARCH_RADIUS;
public class OsmandAidlApi { public class OsmandAidlApi {
private static final Log LOG = PlatformUtil.getLog(OsmandAidlApi.class); private static final Log LOG = PlatformUtil.getLog(OsmandAidlApi.class);
@ -119,6 +107,7 @@ public class OsmandAidlApi {
private static final String AIDL_DATA = "aidl_data"; private static final String AIDL_DATA = "aidl_data";
private static final String AIDL_URI = "aidl_uri"; private static final String AIDL_URI = "aidl_uri";
private static final String AIDL_FORCE = "aidl_force"; private static final String AIDL_FORCE = "aidl_force";
private static final String AIDL_SEARCH_QUERY = "aidl_search_query";
private static final String AIDL_OBJECT_ID = "aidl_object_id"; private static final String AIDL_OBJECT_ID = "aidl_object_id";
@ -135,6 +124,7 @@ public class OsmandAidlApi {
private static final String AIDL_NAVIGATE = "aidl_navigate"; private static final String AIDL_NAVIGATE = "aidl_navigate";
private static final String AIDL_NAVIGATE_GPX = "aidl_navigate_gpx"; private static final String AIDL_NAVIGATE_GPX = "aidl_navigate_gpx";
private static final String AIDL_NAVIGATE_SEARCH = "aidl_navigate_search";
private static final String AIDL_PAUSE_NAVIGATION = "pause_navigation"; private static final String AIDL_PAUSE_NAVIGATION = "pause_navigation";
private static final String AIDL_RESUME_NAVIGATION = "resume_navigation"; private static final String AIDL_RESUME_NAVIGATION = "resume_navigation";
private static final String AIDL_STOP_NAVIGATION = "stop_navigation"; private static final String AIDL_STOP_NAVIGATION = "stop_navigation";
@ -166,7 +156,7 @@ public class OsmandAidlApi {
this.app = app; this.app = app;
} }
public void onCreateMapActivity(final MapActivity mapActivity) { public void onCreateMapActivity(MapActivity mapActivity) {
mapActivityActive = true; mapActivityActive = true;
registerRefreshMapReceiver(mapActivity); registerRefreshMapReceiver(mapActivity);
registerSetMapLocationReceiver(mapActivity); registerSetMapLocationReceiver(mapActivity);
@ -180,6 +170,7 @@ public class OsmandAidlApi {
registerStopRecordingReceiver(mapActivity); registerStopRecordingReceiver(mapActivity);
registerNavigateReceiver(mapActivity); registerNavigateReceiver(mapActivity);
registerNavigateGpxReceiver(mapActivity); registerNavigateGpxReceiver(mapActivity);
registerNavigateSearchReceiver(mapActivity);
registerPauseNavigationReceiver(mapActivity); registerPauseNavigationReceiver(mapActivity);
registerResumeNavigationReceiver(mapActivity); registerResumeNavigationReceiver(mapActivity);
registerStopNavigationReceiver(mapActivity); registerStopNavigationReceiver(mapActivity);
@ -187,7 +178,7 @@ public class OsmandAidlApi {
registerUnmuteNavigationReceiver(mapActivity); registerUnmuteNavigationReceiver(mapActivity);
} }
public void onDestroyMapActivity(final MapActivity mapActivity) { public void onDestroyMapActivity(MapActivity mapActivity) {
mapActivityActive = false; mapActivityActive = false;
for (BroadcastReceiver b : receivers.values()) { for (BroadcastReceiver b : receivers.values()) {
if(b == null) { if(b == null) {
@ -201,45 +192,53 @@ public class OsmandAidlApi {
} }
receivers = new TreeMap<>(); receivers = new TreeMap<>();
} }
public boolean isUpdateAllowed() { public boolean isUpdateAllowed() {
return mapActivityActive; return mapActivityActive;
} }
private void registerRefreshMapReceiver(final MapActivity mapActivity) { private void registerRefreshMapReceiver(MapActivity mapActivity) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
BroadcastReceiver refreshMapReceiver = new BroadcastReceiver() { BroadcastReceiver refreshMapReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
mapActivity.refreshMap(); MapActivity mapActivity = mapActivityRef.get();
if (mapActivity != null) {
mapActivity.refreshMap();
}
} }
}; };
registerReceiver(refreshMapReceiver, mapActivity, AIDL_REFRESH_MAP); registerReceiver(refreshMapReceiver, mapActivity, AIDL_REFRESH_MAP);
} }
private void registerSetMapLocationReceiver(final MapActivity mapActivity) { private void registerSetMapLocationReceiver(MapActivity mapActivity) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
BroadcastReceiver setMapLocationReceiver = new BroadcastReceiver() { BroadcastReceiver setMapLocationReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
double lat = intent.getDoubleExtra(AIDL_LATITUDE, Double.NaN); MapActivity mapActivity = mapActivityRef.get();
double lon = intent.getDoubleExtra(AIDL_LONGITUDE, Double.NaN); if (mapActivity != null) {
int zoom = intent.getIntExtra(AIDL_ZOOM, 0); double lat = intent.getDoubleExtra(AIDL_LATITUDE, Double.NaN);
boolean animated = intent.getBooleanExtra(AIDL_ANIMATED, false); double lon = intent.getDoubleExtra(AIDL_LONGITUDE, Double.NaN);
if (!Double.isNaN(lat) && !Double.isNaN(lon)) { int zoom = intent.getIntExtra(AIDL_ZOOM, 0);
OsmandMapTileView mapView = mapActivity.getMapView(); boolean animated = intent.getBooleanExtra(AIDL_ANIMATED, false);
if (zoom == 0) { if (!Double.isNaN(lat) && !Double.isNaN(lon)) {
zoom = mapView.getZoom(); OsmandMapTileView mapView = mapActivity.getMapView();
} else { if (zoom == 0) {
zoom = zoom > mapView.getMaxZoom() ? mapView.getMaxZoom() : zoom; zoom = mapView.getZoom();
zoom = zoom < mapView.getMinZoom() ? mapView.getMinZoom() : zoom; } else {
} zoom = zoom > mapView.getMaxZoom() ? mapView.getMaxZoom() : zoom;
if (animated) { zoom = zoom < mapView.getMinZoom() ? mapView.getMinZoom() : zoom;
mapView.getAnimatedDraggingThread().startMoving(lat, lon, zoom, true); }
} else { if (animated) {
mapView.setLatLon(lat, lon); mapView.getAnimatedDraggingThread().startMoving(lat, lon, zoom, true);
mapView.setIntZoom(zoom); } else {
mapView.setLatLon(lat, lon);
mapView.setIntZoom(zoom);
}
} }
mapActivity.refreshMap();
} }
mapActivity.refreshMap();
} }
}; };
registerReceiver(setMapLocationReceiver, mapActivity, AIDL_SET_MAP_LOCATION); registerReceiver(setMapLocationReceiver, mapActivity, AIDL_SET_MAP_LOCATION);
@ -253,12 +252,14 @@ public class OsmandAidlApi {
} }
} }
private void registerAddMapWidgetReceiver(final MapActivity mapActivity) { private void registerAddMapWidgetReceiver(MapActivity mapActivity) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
BroadcastReceiver addMapWidgetReceiver = new BroadcastReceiver() { BroadcastReceiver addMapWidgetReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
MapActivity mapActivity = mapActivityRef.get();
String widgetId = intent.getStringExtra(AIDL_OBJECT_ID); String widgetId = intent.getStringExtra(AIDL_OBJECT_ID);
if (widgetId != null) { if (mapActivity != null && widgetId != null) {
AMapWidget widget = widgets.get(widgetId); AMapWidget widget = widgets.get(widgetId);
if (widget != null) { if (widget != null) {
MapInfoLayer layer = mapActivity.getMapLayers().getMapInfoLayer(); MapInfoLayer layer = mapActivity.getMapLayers().getMapInfoLayer();
@ -287,12 +288,14 @@ public class OsmandAidlApi {
ma.registerReceiver(rec, new IntentFilter(filter)); ma.registerReceiver(rec, new IntentFilter(filter));
} }
private void registerRemoveMapWidgetReceiver(final MapActivity mapActivity) { private void registerRemoveMapWidgetReceiver(MapActivity mapActivity) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
BroadcastReceiver removeMapWidgetReceiver = new BroadcastReceiver() { BroadcastReceiver removeMapWidgetReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
MapActivity mapActivity = mapActivityRef.get();
String widgetId = intent.getStringExtra(AIDL_OBJECT_ID); String widgetId = intent.getStringExtra(AIDL_OBJECT_ID);
if (widgetId != null) { if (mapActivity != null && widgetId != null) {
MapInfoLayer layer = mapActivity.getMapLayers().getMapInfoLayer(); MapInfoLayer layer = mapActivity.getMapLayers().getMapInfoLayer();
TextInfoWidget widgetControl = widgetControls.get(widgetId); TextInfoWidget widgetControl = widgetControls.get(widgetId);
if (layer != null && widgetControl != null) { if (layer != null && widgetControl != null) {
@ -323,12 +326,14 @@ public class OsmandAidlApi {
} }
} }
private void registerAddMapLayerReceiver(final MapActivity mapActivity) { private void registerAddMapLayerReceiver(MapActivity mapActivity) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
BroadcastReceiver addMapLayerReceiver = new BroadcastReceiver() { BroadcastReceiver addMapLayerReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
MapActivity mapActivity = mapActivityRef.get();
String layerId = intent.getStringExtra(AIDL_OBJECT_ID); String layerId = intent.getStringExtra(AIDL_OBJECT_ID);
if (layerId != null) { if (mapActivity != null && layerId != null) {
AMapLayer layer = layers.get(layerId); AMapLayer layer = layers.get(layerId);
if (layer != null) { if (layer != null) {
OsmandMapLayer mapLayer = mapLayers.get(layerId); OsmandMapLayer mapLayer = mapLayers.get(layerId);
@ -345,12 +350,14 @@ public class OsmandAidlApi {
registerReceiver(addMapLayerReceiver, mapActivity, AIDL_ADD_MAP_LAYER); registerReceiver(addMapLayerReceiver, mapActivity, AIDL_ADD_MAP_LAYER);
} }
private void registerRemoveMapLayerReceiver(final MapActivity mapActivity) { private void registerRemoveMapLayerReceiver(MapActivity mapActivity) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
BroadcastReceiver removeMapLayerReceiver = new BroadcastReceiver() { BroadcastReceiver removeMapLayerReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
MapActivity mapActivity = mapActivityRef.get();
String layerId = intent.getStringExtra(AIDL_OBJECT_ID); String layerId = intent.getStringExtra(AIDL_OBJECT_ID);
if (layerId != null) { if (mapActivity != null && layerId != null) {
OsmandMapLayer mapLayer = mapLayers.remove(layerId); OsmandMapLayer mapLayer = mapLayers.remove(layerId);
if (mapLayer != null) { if (mapLayer != null) {
mapActivity.getMapView().removeLayer(mapLayer); mapActivity.getMapView().removeLayer(mapLayer);
@ -362,12 +369,14 @@ public class OsmandAidlApi {
registerReceiver(removeMapLayerReceiver, mapActivity, AIDL_REMOVE_MAP_LAYER); registerReceiver(removeMapLayerReceiver, mapActivity, AIDL_REMOVE_MAP_LAYER);
} }
private void registerTakePhotoNoteReceiver(final MapActivity mapActivity) { private void registerTakePhotoNoteReceiver(MapActivity mapActivity) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
BroadcastReceiver takePhotoNoteReceiver = new BroadcastReceiver() { BroadcastReceiver takePhotoNoteReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
MapActivity mapActivity = mapActivityRef.get();
final AudioVideoNotesPlugin plugin = OsmandPlugin.getEnabledPlugin(AudioVideoNotesPlugin.class); final AudioVideoNotesPlugin plugin = OsmandPlugin.getEnabledPlugin(AudioVideoNotesPlugin.class);
if (plugin != null) { if (mapActivity != null && plugin != null) {
double lat = intent.getDoubleExtra(AIDL_LATITUDE, Double.NaN); double lat = intent.getDoubleExtra(AIDL_LATITUDE, Double.NaN);
double lon = intent.getDoubleExtra(AIDL_LONGITUDE, Double.NaN); double lon = intent.getDoubleExtra(AIDL_LONGITUDE, Double.NaN);
plugin.takePhoto(lat, lon, mapActivity, false, true); plugin.takePhoto(lat, lon, mapActivity, false, true);
@ -377,12 +386,14 @@ public class OsmandAidlApi {
registerReceiver(takePhotoNoteReceiver, mapActivity, AIDL_TAKE_PHOTO_NOTE); registerReceiver(takePhotoNoteReceiver, mapActivity, AIDL_TAKE_PHOTO_NOTE);
} }
private void registerStartVideoRecordingReceiver(final MapActivity mapActivity) { private void registerStartVideoRecordingReceiver(MapActivity mapActivity) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
BroadcastReceiver startVideoRecordingReceiver = new BroadcastReceiver() { BroadcastReceiver startVideoRecordingReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
MapActivity mapActivity = mapActivityRef.get();
final AudioVideoNotesPlugin plugin = OsmandPlugin.getEnabledPlugin(AudioVideoNotesPlugin.class); final AudioVideoNotesPlugin plugin = OsmandPlugin.getEnabledPlugin(AudioVideoNotesPlugin.class);
if (plugin != null) { if (mapActivity != null && plugin != null) {
double lat = intent.getDoubleExtra(AIDL_LATITUDE, Double.NaN); double lat = intent.getDoubleExtra(AIDL_LATITUDE, Double.NaN);
double lon = intent.getDoubleExtra(AIDL_LONGITUDE, Double.NaN); double lon = intent.getDoubleExtra(AIDL_LONGITUDE, Double.NaN);
plugin.recordVideo(lat, lon, mapActivity, true); plugin.recordVideo(lat, lon, mapActivity, true);
@ -392,12 +403,14 @@ public class OsmandAidlApi {
registerReceiver(startVideoRecordingReceiver, mapActivity, AIDL_START_VIDEO_RECORDING); registerReceiver(startVideoRecordingReceiver, mapActivity, AIDL_START_VIDEO_RECORDING);
} }
private void registerStartAudioRecordingReceiver(final MapActivity mapActivity) { private void registerStartAudioRecordingReceiver(MapActivity mapActivity) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
BroadcastReceiver startAudioRecordingReceiver = new BroadcastReceiver() { BroadcastReceiver startAudioRecordingReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
MapActivity mapActivity = mapActivityRef.get();
final AudioVideoNotesPlugin plugin = OsmandPlugin.getEnabledPlugin(AudioVideoNotesPlugin.class); final AudioVideoNotesPlugin plugin = OsmandPlugin.getEnabledPlugin(AudioVideoNotesPlugin.class);
if (plugin != null) { if (mapActivity != null && plugin != null) {
double lat = intent.getDoubleExtra(AIDL_LATITUDE, Double.NaN); double lat = intent.getDoubleExtra(AIDL_LATITUDE, Double.NaN);
double lon = intent.getDoubleExtra(AIDL_LONGITUDE, Double.NaN); double lon = intent.getDoubleExtra(AIDL_LONGITUDE, Double.NaN);
plugin.recordAudio(lat, lon, mapActivity); plugin.recordAudio(lat, lon, mapActivity);
@ -407,12 +420,14 @@ public class OsmandAidlApi {
registerReceiver(startAudioRecordingReceiver, mapActivity, AIDL_START_AUDIO_RECORDING); registerReceiver(startAudioRecordingReceiver, mapActivity, AIDL_START_AUDIO_RECORDING);
} }
private void registerStopRecordingReceiver(final MapActivity mapActivity) { private void registerStopRecordingReceiver(MapActivity mapActivity) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
BroadcastReceiver stopRecordingReceiver = new BroadcastReceiver() { BroadcastReceiver stopRecordingReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
MapActivity mapActivity = mapActivityRef.get();
final AudioVideoNotesPlugin plugin = OsmandPlugin.getEnabledPlugin(AudioVideoNotesPlugin.class); final AudioVideoNotesPlugin plugin = OsmandPlugin.getEnabledPlugin(AudioVideoNotesPlugin.class);
if (plugin != null) { if (mapActivity != null && plugin != null) {
plugin.stopRecording(mapActivity, false); plugin.stopRecording(mapActivity, false);
} }
} }
@ -420,7 +435,8 @@ public class OsmandAidlApi {
registerReceiver(stopRecordingReceiver, mapActivity, AIDL_STOP_RECORDING); registerReceiver(stopRecordingReceiver, mapActivity, AIDL_STOP_RECORDING);
} }
private void registerNavigateReceiver(final MapActivity mapActivity) { private void registerNavigateReceiver(MapActivity mapActivity) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
BroadcastReceiver navigateReceiver = new BroadcastReceiver() { BroadcastReceiver navigateReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
@ -433,7 +449,8 @@ public class OsmandAidlApi {
break; break;
} }
} }
if (validProfile) { MapActivity mapActivity = mapActivityRef.get();
if (mapActivity != null && validProfile) {
String startName = intent.getStringExtra(AIDL_START_NAME); String startName = intent.getStringExtra(AIDL_START_NAME);
if (Algorithms.isEmpty(startName)) { if (Algorithms.isEmpty(startName)) {
startName = ""; startName = "";
@ -468,13 +485,14 @@ public class OsmandAidlApi {
@Override @Override
public void onDismiss(DialogInterface dialog) { public void onDismiss(DialogInterface dialog) {
if (!routingHelper.isFollowingMode()) { MapActivity mapActivity = mapActivityRef.get();
startNavigation(mapActivity, null, start, startDesc, dest, destDesc, profile); if (mapActivity != null && !routingHelper.isFollowingMode()) {
ExternalApiHelper.startNavigation(mapActivity, start, startDesc, dest, destDesc, profile);
} }
} }
}); });
} else { } else {
startNavigation(mapActivity, null, start, startDesc, dest, destDesc, profile); ExternalApiHelper.startNavigation(mapActivity, start, startDesc, dest, destDesc, profile);
} }
} }
} }
@ -482,51 +500,120 @@ public class OsmandAidlApi {
registerReceiver(navigateReceiver, mapActivity, AIDL_NAVIGATE); registerReceiver(navigateReceiver, mapActivity, AIDL_NAVIGATE);
} }
private void registerNavigateGpxReceiver(final MapActivity mapActivity) { private void registerNavigateSearchReceiver(MapActivity mapActivity) {
BroadcastReceiver navigateGpxReceiver = new BroadcastReceiver() { final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
BroadcastReceiver navigateSearchReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
boolean force = intent.getBooleanExtra(AIDL_FORCE, false); String profileStr = intent.getStringExtra(AIDL_PROFILE);
final ApplicationMode profile = ApplicationMode.valueOfStringKey(profileStr, DEFAULT_PROFILE);
GPXFile gpx = null; boolean validProfile = false;
if (intent.getStringExtra(AIDL_DATA) != null) { for (ApplicationMode mode : VALID_PROFILES) {
String gpxStr = intent.getStringExtra(AIDL_DATA); if (mode == profile) {
if (!Algorithms.isEmpty(gpxStr)) { validProfile = true;
gpx = GPXUtilities.loadGPXFile(mapActivity, new ByteArrayInputStream(gpxStr.getBytes())); break;
}
}
MapActivity mapActivity = mapActivityRef.get();
final String searchQuery = intent.getStringExtra(AIDL_SEARCH_QUERY);
if (mapActivity != null && validProfile && !Algorithms.isEmpty(searchQuery)) {
String startName = intent.getStringExtra(AIDL_START_NAME);
if (Algorithms.isEmpty(startName)) {
startName = "";
} }
} else if (intent.getParcelableExtra(AIDL_URI) != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
Uri gpxUri = intent.getParcelableExtra(AIDL_URI);
ParcelFileDescriptor gpxParcelDescriptor = null; final LatLon start;
try { final PointDescription startDesc;
gpxParcelDescriptor = mapActivity.getContentResolver().openFileDescriptor(gpxUri, "r"); double startLat = intent.getDoubleExtra(AIDL_START_LAT, 0);
} catch (FileNotFoundException e) { double startLon = intent.getDoubleExtra(AIDL_START_LON, 0);
e.printStackTrace(); if (startLat != 0 && startLon != 0) {
start = new LatLon(startLat, startLon);
startDesc = new PointDescription(PointDescription.POINT_TYPE_LOCATION, startName);
} else {
Location location = app.getLocationProvider().getLastKnownLocation();
if (location != null) {
start = new LatLon(location.getLatitude(), location.getLongitude());
startDesc = new PointDescription(PointDescription.POINT_TYPE_MY_LOCATION, mapActivity.getString(R.string.shared_string_my_location));
} else {
start = null;
startDesc = null;
} }
if (gpxParcelDescriptor != null) { }
FileDescriptor fileDescriptor = gpxParcelDescriptor.getFileDescriptor();
gpx = GPXUtilities.loadGPXFile(mapActivity, new FileInputStream(fileDescriptor)); if (start != null) {
final RoutingHelper routingHelper = app.getRoutingHelper();
boolean force = intent.getBooleanExtra(AIDL_FORCE, true);
if (routingHelper.isFollowingMode() && !force) {
AlertDialog dlg = mapActivity.getMapActions().stopNavigationActionConfirm();
dlg.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
MapActivity mapActivity = mapActivityRef.get();
if (mapActivity != null && !routingHelper.isFollowingMode()) {
ExternalApiHelper.searchAndNavigate(mapActivity, start, startDesc, profile, searchQuery);
}
}
});
} else {
ExternalApiHelper.searchAndNavigate(mapActivity, start, startDesc, profile, searchQuery);
} }
} }
} }
}
};
registerReceiver(navigateSearchReceiver, mapActivity, AIDL_NAVIGATE_SEARCH);
}
if (gpx != null) { private void registerNavigateGpxReceiver(MapActivity mapActivity) {
final RoutingHelper routingHelper = app.getRoutingHelper(); final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
if (routingHelper.isFollowingMode() && !force) { BroadcastReceiver navigateGpxReceiver = new BroadcastReceiver() {
final GPXFile gpxFile = gpx; @Override
AlertDialog dlg = mapActivity.getMapActions().stopNavigationActionConfirm(); public void onReceive(Context context, Intent intent) {
dlg.setOnDismissListener(new DialogInterface.OnDismissListener() { MapActivity mapActivity = mapActivityRef.get();
if (mapActivity != null) {
boolean force = intent.getBooleanExtra(AIDL_FORCE, false);
GPXFile gpx = null;
if (intent.getStringExtra(AIDL_DATA) != null) {
String gpxStr = intent.getStringExtra(AIDL_DATA);
if (!Algorithms.isEmpty(gpxStr)) {
gpx = GPXUtilities.loadGPXFile(mapActivity, new ByteArrayInputStream(gpxStr.getBytes()));
}
} else if (intent.getParcelableExtra(AIDL_URI) != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
Uri gpxUri = intent.getParcelableExtra(AIDL_URI);
@Override ParcelFileDescriptor gpxParcelDescriptor = null;
public void onDismiss(DialogInterface dialog) { try {
if (!routingHelper.isFollowingMode()) { gpxParcelDescriptor = mapActivity.getContentResolver().openFileDescriptor(gpxUri, "r");
startNavigation(mapActivity, gpxFile, null, null, null, null, null); } catch (FileNotFoundException e) {
} e.printStackTrace();
} }
}); if (gpxParcelDescriptor != null) {
} else { FileDescriptor fileDescriptor = gpxParcelDescriptor.getFileDescriptor();
startNavigation(mapActivity, gpx, null, null, null, null, null); gpx = GPXUtilities.loadGPXFile(mapActivity, new FileInputStream(fileDescriptor));
}
}
}
if (gpx != null) {
final RoutingHelper routingHelper = app.getRoutingHelper();
if (routingHelper.isFollowingMode() && !force) {
final GPXFile gpxFile = gpx;
AlertDialog dlg = mapActivity.getMapActions().stopNavigationActionConfirm();
dlg.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
MapActivity mapActivity = mapActivityRef.get();
if (mapActivity != null && !routingHelper.isFollowingMode()) {
ExternalApiHelper.startNavigation(mapActivity, gpxFile);
}
}
});
} else {
ExternalApiHelper.startNavigation(mapActivity, gpx);
}
} }
} }
} }
@ -534,95 +621,85 @@ public class OsmandAidlApi {
registerReceiver(navigateGpxReceiver, mapActivity, AIDL_NAVIGATE_GPX); registerReceiver(navigateGpxReceiver, mapActivity, AIDL_NAVIGATE_GPX);
} }
private void startNavigation(MapActivity mapActivity, private void registerPauseNavigationReceiver(MapActivity mapActivity) {
GPXFile gpx, final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
LatLon from, PointDescription fromDesc,
LatLon to, PointDescription toDesc,
ApplicationMode mode) {
OsmandApplication app = mapActivity.getMyApplication();
RoutingHelper routingHelper = app.getRoutingHelper();
if (gpx == null) {
app.getSettings().APPLICATION_MODE.set(mode);
final TargetPointsHelper targets = mapActivity.getMyApplication().getTargetPointsHelper();
targets.removeAllWayPoints(false, true);
targets.navigateToPoint(to, true, -1, toDesc);
}
mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(gpx, from, fromDesc, true, false);
if (!app.getTargetPointsHelper().checkPointToNavigateShort()) {
mapActivity.getMapLayers().getMapControlsLayer().getMapRouteInfoMenu().show();
} else {
if (app.getSettings().APPLICATION_MODE.get() != routingHelper.getAppMode()) {
app.getSettings().APPLICATION_MODE.set(routingHelper.getAppMode());
}
mapActivity.getMapViewTrackingUtilities().backToLocationImpl();
app.getSettings().FOLLOW_THE_ROUTE.set(true);
routingHelper.setFollowingMode(true);
routingHelper.setRoutePlanningMode(false);
mapActivity.getMapViewTrackingUtilities().switchToRoutePlanningMode();
app.getRoutingHelper().notifyIfRouteIsCalculated();
routingHelper.setCurrentLocation(app.getLocationProvider().getLastKnownLocation(), false);
}
}
private void registerPauseNavigationReceiver(final MapActivity mapActivity) {
BroadcastReceiver pauseNavigationReceiver = new BroadcastReceiver() { BroadcastReceiver pauseNavigationReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
RoutingHelper routingHelper = mapActivity.getRoutingHelper(); MapActivity mapActivity = mapActivityRef.get();
if (routingHelper.isRouteCalculated() && !routingHelper.isRoutePlanningMode()) { if (mapActivity != null) {
routingHelper.setRoutePlanningMode(true); RoutingHelper routingHelper = mapActivity.getRoutingHelper();
routingHelper.setFollowingMode(false); if (routingHelper.isRouteCalculated() && !routingHelper.isRoutePlanningMode()) {
routingHelper.setPauseNavigation(true); routingHelper.setRoutePlanningMode(true);
routingHelper.setFollowingMode(false);
routingHelper.setPauseNavigation(true);
}
} }
} }
}; };
registerReceiver(pauseNavigationReceiver, mapActivity, AIDL_PAUSE_NAVIGATION); registerReceiver(pauseNavigationReceiver, mapActivity, AIDL_PAUSE_NAVIGATION);
} }
private void registerResumeNavigationReceiver(final MapActivity mapActivity) { private void registerResumeNavigationReceiver(MapActivity mapActivity) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
BroadcastReceiver resumeNavigationReceiver = new BroadcastReceiver() { BroadcastReceiver resumeNavigationReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
RoutingHelper routingHelper = mapActivity.getRoutingHelper(); MapActivity mapActivity = mapActivityRef.get();
if (routingHelper.isRouteCalculated() && routingHelper.isRoutePlanningMode()) { if (mapActivity != null) {
routingHelper.setRoutePlanningMode(false); RoutingHelper routingHelper = mapActivity.getRoutingHelper();
routingHelper.setFollowingMode(true); if (routingHelper.isRouteCalculated() && routingHelper.isRoutePlanningMode()) {
routingHelper.setRoutePlanningMode(false);
routingHelper.setFollowingMode(true);
}
} }
} }
}; };
registerReceiver(resumeNavigationReceiver, mapActivity, AIDL_RESUME_NAVIGATION); registerReceiver(resumeNavigationReceiver, mapActivity, AIDL_RESUME_NAVIGATION);
} }
private void registerStopNavigationReceiver(final MapActivity mapActivity) { private void registerStopNavigationReceiver(MapActivity mapActivity) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
BroadcastReceiver stopNavigationReceiver = new BroadcastReceiver() { BroadcastReceiver stopNavigationReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
RoutingHelper routingHelper = mapActivity.getRoutingHelper(); MapActivity mapActivity = mapActivityRef.get();
if (routingHelper.isPauseNavigation() || routingHelper.isFollowingMode()) { if (mapActivity != null) {
mapActivity.getMapLayers().getMapControlsLayer().stopNavigationWithoutConfirm(); RoutingHelper routingHelper = mapActivity.getRoutingHelper();
if (routingHelper.isPauseNavigation() || routingHelper.isFollowingMode()) {
mapActivity.getMapLayers().getMapControlsLayer().stopNavigationWithoutConfirm();
}
} }
} }
}; };
registerReceiver(stopNavigationReceiver, mapActivity, AIDL_STOP_NAVIGATION); registerReceiver(stopNavigationReceiver, mapActivity, AIDL_STOP_NAVIGATION);
} }
private void registerMuteNavigationReceiver(final MapActivity mapActivity) { private void registerMuteNavigationReceiver(MapActivity mapActivity) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
BroadcastReceiver muteNavigationReceiver = new BroadcastReceiver() { BroadcastReceiver muteNavigationReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
mapActivity.getMyApplication().getSettings().VOICE_MUTE.set(true); MapActivity mapActivity = mapActivityRef.get();
mapActivity.getRoutingHelper().getVoiceRouter().setMute(true); if (mapActivity != null) {
mapActivity.getMyApplication().getSettings().VOICE_MUTE.set(true);
mapActivity.getRoutingHelper().getVoiceRouter().setMute(true);
}
} }
}; };
registerReceiver(muteNavigationReceiver, mapActivity, AIDL_MUTE_NAVIGATION); registerReceiver(muteNavigationReceiver, mapActivity, AIDL_MUTE_NAVIGATION);
} }
private void registerUnmuteNavigationReceiver(final MapActivity mapActivity) { private void registerUnmuteNavigationReceiver(MapActivity mapActivity) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
BroadcastReceiver unmuteNavigationReceiver = new BroadcastReceiver() { BroadcastReceiver unmuteNavigationReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
mapActivity.getMyApplication().getSettings().VOICE_MUTE.set(false); MapActivity mapActivity = mapActivityRef.get();
mapActivity.getRoutingHelper().getVoiceRouter().setMute(false); if (mapActivity != null) {
mapActivity.getMyApplication().getSettings().VOICE_MUTE.set(false);
mapActivity.getRoutingHelper().getVoiceRouter().setMute(false);
}
} }
}; };
registerReceiver(unmuteNavigationReceiver, mapActivity, AIDL_UNMUTE_NAVIGATION); registerReceiver(unmuteNavigationReceiver, mapActivity, AIDL_UNMUTE_NAVIGATION);
@ -646,7 +723,7 @@ public class OsmandAidlApi {
app.sendBroadcast(intent); app.sendBroadcast(intent);
} }
private TextInfoWidget createWidgetControl(final MapActivity mapActivity, final String widgetId) { private TextInfoWidget createWidgetControl(MapActivity mapActivity, final String widgetId) {
final TextInfoWidget control = new TextInfoWidget(mapActivity) { final TextInfoWidget control = new TextInfoWidget(mapActivity) {
@Override @Override
@ -1292,6 +1369,19 @@ public class OsmandAidlApi {
return true; return true;
} }
boolean navigateSearch(String startName, double startLat, double startLon, String searchQuery, String profile, boolean force) {
Intent intent = new Intent();
intent.setAction(AIDL_NAVIGATE_SEARCH);
intent.putExtra(AIDL_START_NAME, startName);
intent.putExtra(AIDL_START_LAT, startLat);
intent.putExtra(AIDL_START_LON, startLon);
intent.putExtra(AIDL_SEARCH_QUERY, searchQuery);
intent.putExtra(AIDL_PROFILE, profile);
intent.putExtra(AIDL_FORCE, force);
app.sendBroadcast(intent);
return true;
}
boolean pauseNavigation() { boolean pauseNavigation() {
Intent intent = new Intent(); Intent intent = new Intent();
intent.setAction(AIDL_PAUSE_NAVIGATION); intent.setAction(AIDL_PAUSE_NAVIGATION);
@ -1350,73 +1440,15 @@ public class OsmandAidlApi {
@Override @Override
public void onFinish(AppInitializer init) { public void onFinish(AppInitializer init) {
runSearch(searchQuery, searchType, latitude, longitude, radiusLevel, totalLimit, callback); ExternalApiHelper.runSearch(app, searchQuery, searchType, latitude, longitude, radiusLevel, totalLimit, callback);
} }
}); });
} else { } else {
runSearch(searchQuery, searchType, latitude, longitude, radiusLevel, totalLimit, callback); ExternalApiHelper.runSearch(app, searchQuery, searchType, latitude, longitude, radiusLevel, totalLimit, callback);
} }
return true; return true;
} }
private void runSearch(String searchQuery, int searchType, double latitude, double longitude, int radiusLevel,
int totalLimit, final SearchCompleteCallback callback) {
if (radiusLevel < 1) {
radiusLevel = 1;
} else if (radiusLevel > MAX_DEFAULT_SEARCH_RADIUS) {
radiusLevel = MAX_DEFAULT_SEARCH_RADIUS;
}
if (totalLimit <= 0) {
totalLimit = -1;
}
final int limit = totalLimit;
final SearchUICore core = app.getSearchUICore().getCore();
core.setOnResultsComplete(new Runnable() {
@Override
public void run() {
List<SearchResult> resultSet = new ArrayList<>();
SearchResultCollection resultCollection = core.getCurrentSearchResult();
int count = 0;
for (net.osmand.search.core.SearchResult r : resultCollection.getCurrentSearchResults()) {
String name = QuickSearchListItem.getName(app, r);
String typeName = QuickSearchListItem.getTypeName(app, r);
SearchResult result = new SearchResult(r.location.getLatitude(), r.location.getLongitude(),
name, typeName, r.alternateName, new ArrayList<>(r.otherNames));
resultSet.add(result);
count++;
if (limit != -1 && count >= limit) {
break;
}
}
callback.onSearchComplete(resultSet);
}
});
SearchSettings searchSettings = new SearchSettings(core.getSearchSettings())
.setRadiusLevel(radiusLevel)
.setEmptyQueryAllowed(false)
.setSortByName(false)
.setOriginalLocation(new LatLon(latitude, longitude))
.setTotalLimit(totalLimit);
List<ObjectType> searchTypes = new ArrayList<>();
if ((searchType & SearchParams.SEARCH_TYPE_POI) != 0) {
searchTypes.add(POI);
}
if ((searchType & SearchParams.SEARCH_TYPE_ADDRESS) != 0) {
searchTypes.add(CITY);
searchTypes.add(VILLAGE);
searchTypes.add(POSTCODE);
searchTypes.add(STREET);
searchTypes.add(HOUSE);
searchTypes.add(STREET_INTERSECTION);
}
searchSettings = searchSettings.setSearchTypes(searchTypes.toArray(new ObjectType[searchTypes.size()]));
core.search(searchQuery, false, null, searchSettings);
}
boolean setNavDrawerItems(String appPackage, List<net.osmand.aidl.navdrawer.NavDrawerItem> items) { boolean setNavDrawerItems(String appPackage, List<net.osmand.aidl.navdrawer.NavDrawerItem> items) {
if (!TextUtils.isEmpty(appPackage) && items != null) { if (!TextUtils.isEmpty(appPackage) && items != null) {
if (items.isEmpty()) { if (items.isEmpty()) {

View file

@ -8,6 +8,7 @@ import android.os.HandlerThread;
import android.os.IBinder; import android.os.IBinder;
import android.os.Looper; import android.os.Looper;
import android.os.Message; import android.os.Message;
import android.os.Parcelable;
import android.os.RemoteException; import android.os.RemoteException;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
@ -44,6 +45,7 @@ import net.osmand.aidl.navdrawer.SetNavDrawerItemsParams;
import net.osmand.aidl.navigation.MuteNavigationParams; import net.osmand.aidl.navigation.MuteNavigationParams;
import net.osmand.aidl.navigation.NavigateGpxParams; import net.osmand.aidl.navigation.NavigateGpxParams;
import net.osmand.aidl.navigation.NavigateParams; import net.osmand.aidl.navigation.NavigateParams;
import net.osmand.aidl.navigation.NavigateSearchParams;
import net.osmand.aidl.navigation.PauseNavigationParams; import net.osmand.aidl.navigation.PauseNavigationParams;
import net.osmand.aidl.navigation.ResumeNavigationParams; import net.osmand.aidl.navigation.ResumeNavigationParams;
import net.osmand.aidl.navigation.StopNavigationParams; import net.osmand.aidl.navigation.StopNavigationParams;
@ -70,17 +72,15 @@ public class OsmandAidlService extends Service {
private static final Log LOG = PlatformUtil.getLog(OsmandAidlService.class); private static final Log LOG = PlatformUtil.getLog(OsmandAidlService.class);
private static final int MIN_UPDATE_TIME_MS = 1000; private static final int MIN_UPDATE_TIME_MS = 1000;
private static final int MSG_RUN_SEARCH = 53;
private static final String DATA_KEY_RESULT_SET = "resultSet"; private static final String DATA_KEY_RESULT_SET = "resultSet";
private ArrayList<IOsmAndAidlCallback> mRemoteCallbacks;
private Map<Long, IOsmAndAidlCallback> callbacks; private Map<Long, IOsmAndAidlCallback> callbacks;
private ServiceHandler mHandler = null; private ServiceHandler mHandler = null;
HandlerThread mHandlerThread = new HandlerThread("OsmAndAidlServiceThread"); HandlerThread mHandlerThread = new HandlerThread("OsmAndAidlServiceThread");
private long updateCallbackId = 0; private long updateCallbackId = 0;
OsmandApplication getApp() { OsmandApplication getApp() {
return (OsmandApplication) getApplication(); return (OsmandApplication) getApplication();
} }
@ -104,7 +104,6 @@ public class OsmandAidlService extends Service {
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
mRemoteCallbacks = new ArrayList<>();
callbacks = new HashMap<>(); callbacks = new HashMap<>();
} }
@ -482,7 +481,10 @@ public class OsmandAidlService extends Service {
@Override @Override
public boolean navigate(NavigateParams params) throws RemoteException { public boolean navigate(NavigateParams params) throws RemoteException {
try { try {
return params != null && getApi("navigate").navigate(params.getStartName(), params.getStartLat(), params.getStartLon(), params.getDestName(), params.getDestLat(), params.getDestLon(), params.getProfile(), params.isForce()); return params != null && getApi("navigate").navigate(
params.getStartName(), params.getStartLat(), params.getStartLon(),
params.getDestName(), params.getDestLat(), params.getDestLon(),
params.getProfile(), params.isForce());
} catch (Exception e) { } catch (Exception e) {
handleException(e); handleException(e);
return false; return false;
@ -563,14 +565,18 @@ public class OsmandAidlService extends Service {
public boolean search(SearchParams params, final IOsmAndAidlCallback callback) throws RemoteException { public boolean search(SearchParams params, final IOsmAndAidlCallback callback) throws RemoteException {
try { try {
return params != null && getApi("search").search(params.getSearchQuery(), params.getSearchType(), return params != null && getApi("search").search(params.getSearchQuery(), params.getSearchType(),
params.getLatutude(), params.getLongitude(), params.getRadiusLevel(), params.getTotalLimit(), new SearchCompleteCallback() { params.getLatitude(), params.getLongitude(), params.getRadiusLevel(), params.getTotalLimit(), new SearchCompleteCallback() {
@Override @Override
public void onSearchComplete(List<SearchResult> resultSet) { public void onSearchComplete(List<SearchResult> resultSet) {
Bundle data = new Bundle(); Bundle data = new Bundle();
if (resultSet.size() > 0) { if (resultSet.size() > 0) {
data.putParcelableArrayList(DATA_KEY_RESULT_SET, new ArrayList<>(resultSet)); data.putParcelableArrayList(DATA_KEY_RESULT_SET, new ArrayList<>(resultSet));
} }
sendMsgToHandler(callback, MSG_RUN_SEARCH, data); try {
callback.onSearchComplete(resultSet);
} catch (RemoteException e) {
handleException(e);
}
} }
}); });
} catch (Exception e) { } catch (Exception e) {
@ -617,56 +623,16 @@ public class OsmandAidlService extends Service {
} }
}), updateTimeMS); }), updateTimeMS);
} }
/**
* Create handler message to be sent
*/
void sendMsgToHandler(IOsmAndAidlCallback callback, int flag, Bundle data) {
mRemoteCallbacks.add(callback);
Message message = mHandler.obtainMessage();
message.arg1 = mRemoteCallbacks.size() - 1;
message.setData(data);
message.what = flag;
mHandler.sendMessage(message);
}
/**
* Handler class sending result in callback to respective
* application
*/
private class ServiceHandler extends Handler {
int callbackIndex = 0;
ServiceHandler(Looper looper) {
super(looper);
}
@Override @Override
public void handleMessage(Message msg) { public boolean navigateSearch(NavigateSearchParams params) throws RemoteException {
callbackIndex = msg.arg1; try {
return params != null && getApi("navigateSearch").navigateSearch(
switch (msg.what) { params.getStartName(), params.getStartLat(), params.getStartLon(),
params.getSearchQuery(), params.getProfile(), params.isForce());
case MSG_RUN_SEARCH: } catch (Exception e) {
handleException(e);
Bundle data = msg.getData(); return false;
List<SearchResult> resultSet;
if (data.containsKey(DATA_KEY_RESULT_SET)) {
resultSet = data.getParcelableArrayList(DATA_KEY_RESULT_SET);
} else {
resultSet = Collections.emptyList();
}
try {
mRemoteCallbacks.get(callbackIndex).onSearchComplete(resultSet);
} catch (RemoteException e) {
LOG.error("AIDL e.getMessage()", e);
}
break;
} }
} }
} };
} }

View file

@ -0,0 +1,3 @@
package net.osmand.aidl.navigation;
parcelable NavigateSearchParams;

View file

@ -0,0 +1,88 @@
package net.osmand.aidl.navigation;
import android.os.Parcel;
import android.os.Parcelable;
public class NavigateSearchParams implements Parcelable {
private String startName;
private double startLat;
private double startLon;
private String searchQuery;
private String profile;
private boolean force;
public NavigateSearchParams(String startName, double startLat, double startLon, String searchQuery, String profile, boolean force) {
this.startName = startName;
this.startLat = startLat;
this.startLon = startLon;
this.searchQuery = searchQuery;
this.profile = profile;
this.force = force;
}
public NavigateSearchParams(Parcel in) {
readFromParcel(in);
}
public static final Creator<NavigateSearchParams> CREATOR = new Creator<NavigateSearchParams>() {
@Override
public NavigateSearchParams createFromParcel(Parcel in) {
return new NavigateSearchParams(in);
}
@Override
public NavigateSearchParams[] newArray(int size) {
return new NavigateSearchParams[size];
}
};
public String getStartName() {
return startName;
}
public double getStartLat() {
return startLat;
}
public double getStartLon() {
return startLon;
}
public String getSearchQuery() {
return searchQuery;
}
public String getProfile() {
return profile;
}
public boolean isForce() {
return force;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(startName);
out.writeDouble(startLat);
out.writeDouble(startLon);
out.writeString(searchQuery);
out.writeString(profile);
out.writeByte((byte) (force ? 1 : 0));
}
private void readFromParcel(Parcel in) {
startName = in.readString();
startLat = in.readDouble();
startLon = in.readDouble();
searchQuery = in.readString();
profile = in.readString();
force = in.readByte() != 0;
}
@Override
public int describeContents() {
return 0;
}
}

View file

@ -11,15 +11,15 @@ public class SearchParams implements Parcelable {
private String searchQuery; private String searchQuery;
private int searchType; private int searchType;
private double latutude; private double latitude;
private double longitude; private double longitude;
private int radiusLevel = 1; private int radiusLevel = 1;
private int totalLimit = -1; private int totalLimit = -1;
public SearchParams(String searchQuery, int searchType, double latutude, double longitude, int radiusLevel, int totalLimit) { public SearchParams(String searchQuery, int searchType, double latitude, double longitude, int radiusLevel, int totalLimit) {
this.searchQuery = searchQuery; this.searchQuery = searchQuery;
this.searchType = searchType; this.searchType = searchType;
this.latutude = latutude; this.latitude = latitude;
this.longitude = longitude; this.longitude = longitude;
this.radiusLevel = radiusLevel; this.radiusLevel = radiusLevel;
this.totalLimit = totalLimit; this.totalLimit = totalLimit;
@ -49,8 +49,8 @@ public class SearchParams implements Parcelable {
return searchType; return searchType;
} }
public double getLatutude() { public double getLatitude() {
return latutude; return latitude;
} }
public double getLongitude() { public double getLongitude() {
@ -69,7 +69,7 @@ public class SearchParams implements Parcelable {
public void writeToParcel(Parcel out, int flags) { public void writeToParcel(Parcel out, int flags) {
out.writeString(searchQuery); out.writeString(searchQuery);
out.writeInt(searchType); out.writeInt(searchType);
out.writeDouble(latutude); out.writeDouble(latitude);
out.writeDouble(longitude); out.writeDouble(longitude);
out.writeInt(radiusLevel); out.writeInt(radiusLevel);
out.writeInt(totalLimit); out.writeInt(totalLimit);
@ -78,7 +78,7 @@ public class SearchParams implements Parcelable {
private void readFromParcel(Parcel in) { private void readFromParcel(Parcel in) {
searchQuery = in.readString(); searchQuery = in.readString();
searchType = in.readInt(); searchType = in.readInt();
latutude = in.readDouble(); latitude = in.readDouble();
longitude = in.readDouble(); longitude = in.readDouble();
radiusLevel = in.readInt(); radiusLevel = in.readInt();
totalLimit = in.readInt(); totalLimit = in.readInt();

View file

@ -1,17 +1,23 @@
package net.osmand.plus.helpers; package net.osmand.plus.helpers;
import android.app.Activity; import android.app.Activity;
import android.app.ProgressDialog;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.IndexConstants; import net.osmand.IndexConstants;
import net.osmand.Location; import net.osmand.Location;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.aidl.OsmandAidlApi;
import net.osmand.aidl.search.SearchParams;
import net.osmand.aidl.search.SearchResult;
import net.osmand.data.FavouritePoint; import net.osmand.data.FavouritePoint;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.PointDescription; import net.osmand.data.PointDescription;
@ -23,6 +29,7 @@ import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.MapMarkersHelper.MapMarker; import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.TargetPointsHelper;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.audionotes.AudioVideoNotesPlugin; import net.osmand.plus.audionotes.AudioVideoNotesPlugin;
@ -31,14 +38,30 @@ import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo; import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo;
import net.osmand.plus.routing.RouteDirectionInfo; import net.osmand.plus.routing.RouteDirectionInfo;
import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.search.listitems.QuickSearchListItem;
import net.osmand.router.TurnType; import net.osmand.router.TurnType;
import net.osmand.search.SearchUICore;
import net.osmand.search.core.ObjectType;
import net.osmand.search.core.SearchSettings;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import static net.osmand.search.core.ObjectType.CITY;
import static net.osmand.search.core.ObjectType.HOUSE;
import static net.osmand.search.core.ObjectType.POI;
import static net.osmand.search.core.ObjectType.POSTCODE;
import static net.osmand.search.core.ObjectType.STREET;
import static net.osmand.search.core.ObjectType.STREET_INTERSECTION;
import static net.osmand.search.core.ObjectType.VILLAGE;
import static net.osmand.search.core.SearchCoreFactory.MAX_DEFAULT_SEARCH_RADIUS;
public class ExternalApiHelper { public class ExternalApiHelper {
private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(ExternalApiHelper.class); private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(ExternalApiHelper.class);
@ -47,6 +70,8 @@ public class ExternalApiHelper {
public static final String API_CMD_NAVIGATE_GPX = "navigate_gpx"; public static final String API_CMD_NAVIGATE_GPX = "navigate_gpx";
public static final String API_CMD_NAVIGATE = "navigate"; public static final String API_CMD_NAVIGATE = "navigate";
public static final String API_CMD_NAVIGATE_SEARCH = "navigate_search";
public static final String API_CMD_PAUSE_NAVIGATION = "pause_navigation"; public static final String API_CMD_PAUSE_NAVIGATION = "pause_navigation";
public static final String API_CMD_RESUME_NAVIGATION = "resume_navigation"; public static final String API_CMD_RESUME_NAVIGATION = "resume_navigation";
public static final String API_CMD_STOP_NAVIGATION = "stop_navigation"; public static final String API_CMD_STOP_NAVIGATION = "stop_navigation";
@ -124,6 +149,8 @@ public class ExternalApiHelper {
public static final int RESULT_CODE_ERROR_PLUGIN_INACTIVE = 1003; public static final int RESULT_CODE_ERROR_PLUGIN_INACTIVE = 1003;
public static final int RESULT_CODE_ERROR_GPX_NOT_FOUND = 1004; public static final int RESULT_CODE_ERROR_GPX_NOT_FOUND = 1004;
public static final int RESULT_CODE_ERROR_INVALID_PROFILE = 1005; public static final int RESULT_CODE_ERROR_INVALID_PROFILE = 1005;
public static final int RESULT_CODE_ERROR_EMPTY_SEARCH_QUERY = 1006;
public static final int RESULT_CODE_ERROR_START_LOCATION_UNDEFINED = 1007;
private MapActivity mapActivity; private MapActivity mapActivity;
private int resultCode; private int resultCode;
@ -199,12 +226,12 @@ public class ExternalApiHelper {
@Override @Override
public void onDismiss(DialogInterface dialog) { public void onDismiss(DialogInterface dialog) {
if (!routingHelper.isFollowingMode()) { if (!routingHelper.isFollowingMode()) {
startNavigation(gpxFile, null, null, null, null, null); startNavigation(mapActivity, gpxFile);
} }
} }
}); });
} else { } else {
startNavigation(gpx, null, null, null, null, null); startNavigation(mapActivity, gpx);
} }
} else { } else {
app.getSelectedGpxHelper().setGpxFileToDisplay(gpx); app.getSelectedGpxHelper().setGpxFileToDisplay(gpx);
@ -237,7 +264,6 @@ public class ExternalApiHelper {
destName = ""; destName = "";
} }
final LatLon start; final LatLon start;
final PointDescription startDesc; final PointDescription startDesc;
String startLatStr = uri.getQueryParameter(PARAM_START_LAT); String startLatStr = uri.getQueryParameter(PARAM_START_LAT);
@ -252,7 +278,6 @@ public class ExternalApiHelper {
startDesc = null; startDesc = null;
} }
String destSearchQuery = uri.getQueryParameter(PARAM_DEST_SEARCH_QUERY);
String destLatStr = uri.getQueryParameter(PARAM_DEST_LAT); String destLatStr = uri.getQueryParameter(PARAM_DEST_LAT);
String destLonStr = uri.getQueryParameter(PARAM_DEST_LON); String destLonStr = uri.getQueryParameter(PARAM_DEST_LON);
final LatLon dest; final LatLon dest;
@ -262,9 +287,6 @@ public class ExternalApiHelper {
dest = new LatLon(destLat, destLon); dest = new LatLon(destLat, destLon);
} else { } else {
dest = null; dest = null;
}
if (!Algorithms.isEmpty(destSearchQuery)) {
} }
final PointDescription destDesc = new PointDescription(PointDescription.POINT_TYPE_LOCATION, destName); final PointDescription destDesc = new PointDescription(PointDescription.POINT_TYPE_LOCATION, destName);
@ -278,12 +300,76 @@ public class ExternalApiHelper {
@Override @Override
public void onDismiss(DialogInterface dialog) { public void onDismiss(DialogInterface dialog) {
if (!routingHelper.isFollowingMode()) { if (!routingHelper.isFollowingMode()) {
startNavigation(null, start, startDesc, dest, destDesc, profile); startNavigation(mapActivity, start, startDesc, dest, destDesc, profile);
} }
} }
}); });
} else { } else {
startNavigation(null, start, startDesc, dest, destDesc, profile); startNavigation(mapActivity, start, startDesc, dest, destDesc, profile);
}
}
} else if (API_CMD_NAVIGATE_SEARCH.equals(cmd)) {
String profileStr = uri.getQueryParameter(PARAM_PROFILE);
final ApplicationMode profile = ApplicationMode.valueOfStringKey(profileStr, DEFAULT_PROFILE);
boolean validProfile = false;
for (ApplicationMode mode : VALID_PROFILES) {
if (mode == profile) {
validProfile = true;
break;
}
}
final String searchQuery = uri.getQueryParameter(PARAM_DEST_SEARCH_QUERY);
if (Algorithms.isEmpty(searchQuery)) {
resultCode = RESULT_CODE_ERROR_EMPTY_SEARCH_QUERY;
} else if (!validProfile) {
resultCode = RESULT_CODE_ERROR_INVALID_PROFILE;
} else {
String startName = uri.getQueryParameter(PARAM_START_NAME);
if (Algorithms.isEmpty(startName)) {
startName = "";
}
final LatLon start;
final PointDescription startDesc;
String startLatStr = uri.getQueryParameter(PARAM_START_LAT);
String startLonStr = uri.getQueryParameter(PARAM_START_LON);
if (!Algorithms.isEmpty(startLatStr) && !Algorithms.isEmpty(startLonStr)) {
double lat = Double.parseDouble(uri.getQueryParameter(PARAM_START_LAT));
double lon = Double.parseDouble(uri.getQueryParameter(PARAM_START_LON));
start = new LatLon(lat, lon);
startDesc = new PointDescription(PointDescription.POINT_TYPE_LOCATION, startName);
} else {
Location location = app.getLocationProvider().getLastKnownLocation();
if (location != null) {
start = new LatLon(location.getLatitude(), location.getLongitude());
startDesc = new PointDescription(PointDescription.POINT_TYPE_MY_LOCATION, mapActivity.getString(R.string.shared_string_my_location));
} else {
start = null;
startDesc = null;
}
}
if (start == null) {
resultCode = RESULT_CODE_ERROR_START_LOCATION_UNDEFINED;
} else {
boolean force = uri.getBooleanQueryParameter(PARAM_FORCE, false);
final RoutingHelper routingHelper = app.getRoutingHelper();
if (routingHelper.isFollowingMode() && !force) {
AlertDialog dlg = mapActivity.getMapActions().stopNavigationActionConfirm();
dlg.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
if (!routingHelper.isFollowingMode()) {
searchAndNavigate(mapActivity, start, startDesc, profile, searchQuery);
}
}
});
} else {
searchAndNavigate(mapActivity, start, startDesc, profile, searchQuery);
}
resultCode = Activity.RESULT_OK;
} }
} }
@ -498,10 +584,23 @@ public class ExternalApiHelper {
mapContextMenu.show(new LatLon(lat, lon), pointDescription, object); mapContextMenu.show(new LatLon(lat, lon), pointDescription, object);
} }
private void startNavigation(GPXFile gpx, static public void startNavigation(MapActivity mapActivity,
LatLon from, PointDescription fromDesc, @NonNull GPXFile gpx) {
LatLon to, PointDescription toDesc, startNavigation(mapActivity, gpx, null, null, null, null, null);
ApplicationMode mode) { }
static public void startNavigation(MapActivity mapActivity,
@Nullable LatLon from, @Nullable PointDescription fromDesc,
@Nullable LatLon to, @Nullable PointDescription toDesc,
@NonNull ApplicationMode mode) {
startNavigation(mapActivity, null, from, fromDesc, to, toDesc, mode);
}
static private void startNavigation(MapActivity mapActivity,
GPXFile gpx,
LatLon from, PointDescription fromDesc,
LatLon to, PointDescription toDesc,
ApplicationMode mode) {
OsmandApplication app = mapActivity.getMyApplication(); OsmandApplication app = mapActivity.getMyApplication();
RoutingHelper routingHelper = app.getRoutingHelper(); RoutingHelper routingHelper = app.getRoutingHelper();
if (gpx == null) { if (gpx == null) {
@ -527,6 +626,104 @@ public class ExternalApiHelper {
} }
} }
static public void searchAndNavigate(@NonNull MapActivity mapActivity,
@NonNull final LatLon from, @Nullable final PointDescription fromDesc,
@NonNull final ApplicationMode mode, @NonNull final String searchQuery) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
OsmandApplication app = mapActivity.getMyApplication();
ProgressDialog dlg = new ProgressDialog(mapActivity);
dlg.setTitle("");
dlg.setMessage(mapActivity.getString(R.string.searching_address));
dlg.show();
final WeakReference<ProgressDialog> dlgRef = new WeakReference<>(dlg);
runSearch(app, searchQuery, SearchParams.SEARCH_TYPE_ALL,
from.getLatitude(), from.getLongitude(), 1, 1, new OsmandAidlApi.SearchCompleteCallback() {
@Override
public void onSearchComplete(final List<SearchResult> resultSet) {
final MapActivity mapActivity = mapActivityRef.get();
if (mapActivity != null) {
mapActivity.getMyApplication().runInUIThread(new Runnable() {
@Override
public void run() {
ProgressDialog dlg = dlgRef.get();
if (dlg != null) {
dlg.dismiss();
}
if (resultSet.size() > 0) {
final SearchResult res = resultSet.get(0);
LatLon to = new LatLon(res.getLatitude(), res.getLongitude());
PointDescription toDesc = new PointDescription(PointDescription.POINT_TYPE_TARGET, res.getLocalName() + ", " + res.getLocalTypeName());
startNavigation(mapActivity, from, fromDesc, to, toDesc, mode);
} else {
mapActivity.getMyApplication().showToastMessage(mapActivity.getString(R.string.search_nothing_found));
}
}
});
}
}
});
}
static public void runSearch(final OsmandApplication app, String searchQuery, int searchType,
double latitude, double longitude, int radiusLevel,
int totalLimit, final OsmandAidlApi.SearchCompleteCallback callback) {
if (radiusLevel < 1) {
radiusLevel = 1;
} else if (radiusLevel > MAX_DEFAULT_SEARCH_RADIUS) {
radiusLevel = MAX_DEFAULT_SEARCH_RADIUS;
}
if (totalLimit <= 0) {
totalLimit = -1;
}
final int limit = totalLimit;
final SearchUICore core = app.getSearchUICore().getCore();
core.setOnResultsComplete(new Runnable() {
@Override
public void run() {
List<SearchResult> resultSet = new ArrayList<>();
SearchUICore.SearchResultCollection resultCollection = core.getCurrentSearchResult();
int count = 0;
for (net.osmand.search.core.SearchResult r : resultCollection.getCurrentSearchResults()) {
String name = QuickSearchListItem.getName(app, r);
String typeName = QuickSearchListItem.getTypeName(app, r);
SearchResult result = new SearchResult(r.location.getLatitude(), r.location.getLongitude(),
name, typeName, r.alternateName, new ArrayList<>(r.otherNames));
resultSet.add(result);
count++;
if (limit != -1 && count >= limit) {
break;
}
}
callback.onSearchComplete(resultSet);
}
});
SearchSettings searchSettings = new SearchSettings(core.getSearchSettings())
.setRadiusLevel(radiusLevel)
.setEmptyQueryAllowed(false)
.setSortByName(false)
.setOriginalLocation(new LatLon(latitude, longitude))
.setTotalLimit(totalLimit);
List<ObjectType> searchTypes = new ArrayList<>();
if ((searchType & SearchParams.SEARCH_TYPE_POI) != 0) {
searchTypes.add(POI);
}
if ((searchType & SearchParams.SEARCH_TYPE_ADDRESS) != 0) {
searchTypes.add(CITY);
searchTypes.add(VILLAGE);
searchTypes.add(POSTCODE);
searchTypes.add(STREET);
searchTypes.add(HOUSE);
searchTypes.add(STREET_INTERSECTION);
}
searchSettings = searchSettings.setSearchTypes(searchTypes.toArray(new ObjectType[searchTypes.size()]));
core.search(searchQuery, false, null, searchSettings);
}
public void testApi(OsmandApplication app, String command) { public void testApi(OsmandApplication app, String command) {
Uri uri = null; Uri uri = null;
Intent intent = null; Intent intent = null;