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_ferries">Saihestu ferryak</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_show_ruler">Erregela</string>

View file

@ -368,11 +368,11 @@
<string name="local_index_transport_data">اطلاعات حمل‌ونقل عمومی</string>
<string name="local_index_map_data">اطلاعات نقشه</string>
<string name="local_indexes_cat_backup">غیرفعال</string>
<string name="local_indexes_cat_tts">پیام‌های صوتی (ماشینی، TTS)</string>
<string name="local_indexes_cat_voice">پیام‌های صوتی (ضبطی)</string>
<string name="local_indexes_cat_tts">پیام‌های گفتاری (ماشینی، TTS)</string>
<string name="local_indexes_cat_voice">پیام‌های گفتاری (ضبطی)</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="map_text_size_descr">اندازهٔ نوشته را برای نام‌های روی نقشه انتخاب کنید.</string>
<string name="map_text_size">اندازهٔ فونت نقشه</string>
@ -453,8 +453,8 @@
<string name="index_name_asia">آسیا</string>
<string name="index_name_oceania">استرالیا و اقیانوسیه</string>
<string name="index_name_other">نقشه‌های جهانی و بالادستی</string>
<string name="index_name_voice">پیام‌های صوتی (ضبطی، قابلیت محدود)</string>
<string name="index_name_tts_voice">پیام‌های صوتی (ماشینی، TTS - بهتر)</string>
<string name="index_name_voice">پیام‌های گفتاری (ضبطی، قابلیت محدود)</string>
<string name="index_name_tts_voice">پیام‌های گفتاری (ماشینی، TTS - بهتر)</string>
<string name="amenity_type_osmwiki">ویکی‌پدیا (آفلاین)</string>
<string name="routing_settings">راهبری</string>
<string name="routing_settings_descr">گزینه‌های راهبری را تعریف کنید.</string>
@ -720,7 +720,7 @@
<string name="online_map_settings_descr">منبع نقشه‌های آنلاین یا کاشی‌های ذخیره‌شده را تنظیم کنید.</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="no_info">بدون اطلاعات</string>
<string name="direction_style_clockwise">ساعت‌سو (۱۲سویه)</string>
@ -738,7 +738,7 @@
<string name="fav_export_confirmation">قبلاً از نقاط برگزیده یک خروجی تهیه کرده‌اید و فایلش وجود دارد. خروجی جدید را جایگزین آن می‌کنید؟</string>
<string name="osmand_development_plugin_description">به‌وسیلهٔ این افزونه می‌توانید تنظیمات توسعه‌ای و امکانات عیب‌یابی را مشاهده کنید؛ مانند شبیه‌سازی مسیریابی، آزمایش عملکرد رندر یا امتحان‌کردن پیام‌های صوتی.
<string name="osmand_development_plugin_description">به‌وسیلهٔ این افزونه می‌توانید تنظیمات توسعه‌ای و امکانات عیب‌یابی را مشاهده کنید؛ مانند شبیه‌سازی مسیریابی، آزمایش عملکرد رندر یا امتحان‌کردن پیام‌های گفتاری.
\nاین تنظیمات برای توسعه‌دهندگان فراهم شده است و به‌کار کاربران عادی نمی‌آید.</string>
<string name="animate_route_off">پایان شبیه‌سازی</string>
<string name="animate_route">شروع شبیه‌سازی</string>
@ -816,7 +816,7 @@
\n
\n\tفعالسازی:
\n\t«منو» ← «پیکربندی نقشه» ← «منبع نقشه…» ← «نقشه‌های بُرداری آفلاین».</string>
<string name="choose_audio_stream">خروجی راهنمای صوتی</string>
<string name="choose_audio_stream">خروجی راهنمای گفتاری</string>
<string name="layer_underlay">نقشهٔ زیری…</string>
<string name="map_underlay">نقشهٔ زیری</string>
<string name="map_underlay_descr">نقشهٔ زیری را انتخاب کنید.</string>
@ -946,14 +946,14 @@
<string name="search_poi_location">در انتظار سیگنال…</string>
<string name="search_near_map">جست‌وجو در اطراف مرکز نقشه</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_on">صدا خاموش است</string>
<string name="voice_provider_descr">راهنمای صوتی راهبری را انتخاب کنید.</string>
<string name="voice_data_initializing">در حال آماده‌سازی داده‌های صوتی…</string>
<string name="voice_data_not_supported">این نسخه از دادهٔ صوتی پشتیبانی نمی‌شود</string>
<string name="voice_data_corrupted">دادهٔ صوتی انتخاب‌شده خراب است</string>
<string name="voice_data_unavailable">دادهٔ صوتی انتخاب‌شده موجود نیست</string>
<string name="voice_provider_descr">راهنمای گفتاری برای راهبری را انتخاب کنید.</string>
<string name="voice_data_initializing">در حال آماده‌سازی داده‌های گفتاری…</string>
<string name="voice_data_not_supported">این نسخه از دادهٔ گفتاری پشتیبانی نمی‌شود</string>
<string name="voice_data_corrupted">دادهٔ گفتاری انتخاب‌شده خراب است</string>
<string name="voice_data_unavailable">دادهٔ گفتاری انتخاب‌شده موجود نیست</string>
<string name="sd_mounted_ro">کارت حافظه در حالت فقط‌خواندنی است.
\nبا این حساب تنها می‌توانید نقشه‌هایی را ببینید که قبلاً دریافت شده‌اند و نمی‌توانید مناطق جدیدی را دانلود کنید.</string>
<string name="process_navigation_service">سرویس راهبری OsmAnd</string>
@ -1000,8 +1000,8 @@
<string name="loading_builds">بارگیری ساخت‌های OsmAnd…</string>
<string name="select_build_to_install">یک ساخت OsmAnd را برای نصب انتخاب کنید</string>
<string name="gps_status_app_not_found">این برنامهٔ وضعیت GPS نصب نیست. در بازار اندروید بگردیم؟</string>
<string name="voice_is_not_available_msg">راهنمای صوتی موجود نیست. لطفاً به «تنطیمات» ← «تنظیمات راهبری» ← «راهنمای صوتی» بروید و یکی از بسته‌های پیام صوتی را انتخاب یا دانلود کنید.</string>
<string name="voice_is_not_available_title">راهنمای صوتی انتخاب نشده</string>
<string name="voice_is_not_available_msg">راهنمای گفتاری موجود نیست. لطفاً به «تنطیمات» ← «تنظیمات راهبری» ← «راهنمای گفتاری» بروید و یکی از بسته‌های پیام گفتاری را انتخاب یا دانلود کنید.</string>
<string name="voice_is_not_available_title">راهنمای گفتاری انتخاب نشده</string>
<string name="download_files_question">آیا {0} فایل دانلود شود ({1} مگابایت)؟</string>
<string name="filter_existing_indexes">دانلود شد</string>
<string name="tiles_to_download_estimated_size">در زوم {0} تعداد {1} کاشی دانلود می‌شود ({2} مگابایت)</string>
@ -1019,7 +1019,7 @@
<string name="transport_search_again">تنظیم مجدد جست‌وجوی حمل‌ونقل</string>
<string name="voice">صدای ضبط‌شده</string>
<string name="voice">گفتار ضبط‌شده</string>
<string name="no_vector_map_loaded">نقشه‌های بُرداری بارگیری نشدند</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همچنین OsmAnd می‌تواند به‌صورت آنلاین و آفلاین و با راهنمای صوتیِ گام‌به‌گام، برایتان مسیریابی کند.
\nهمچنین OsmAnd می‌تواند به‌صورت آنلاین و آفلاین مسیریابی کند و با راهنمای گفتاری شما را گام‌به‌گام هدایت کند.
\n
\n* از ویژگی‌های مهم:
\n- کارایی کامل در حالت آفلاین (قابلیت ذخیره‌سازی نقشه‌های بُرداری یا کاشی در حافظهٔ دستگاه)
\n- وجود نقشه‌های برداری و آفلاینِ سراسر جهان به‌صورت فشرده
\n- امکان دانلود نقشهٔ یک کشور یا منطقه مستقیماً از طریق برنامه
\n- امکان قراردادن نقشه‌های مختلف بر روی هم در چند لایه؛ مانند ردهای GPX یا مسیریابی، مکان‌های محبوب یا POI، نقاط برگزیده، منحنی‌های تراز، ایستگاه‌های حمل‌ونقل عمومی، نقشه‌های دیگر با درصد شفافیت دلخواه
\n- امکان قراردادن نقشه‌های مختلف بر روی هم در چند لایه؛ مانند ردهای GPX یا مسیرپیمایی، مکان‌های محبوب یا POI، نقاط برگزیده، منحنی‌های تراز، ایستگاه‌های حمل‌ونقل عمومی، نقشه‌های دیگر با درصد شفافیت دلخواه
\n- جست‌وجوی آفلاین مکان‌ها (POIها) و نشانی‌ها
\n- مسیریابی آفلاین برای مسافت‌های متوسط
\n- نمایه‌های خودرو، دوچرخه و پیاده با قابلیت‌های اختیاری:
\n. نمای خودکار شب یا روز؛
\n. زوم وابسته به سرعت؛
\n. میزان‌کردن نقشه در جهت قطب‌نما یا در جهت حرکت؛
\n. راهنمای خط عبوری، نمایش محدودیت سرعت، راهنمای صوتی انسانی یا ماشینی.
\n. راهنمای خط عبوری، نمایش محدودیت سرعت، راهنمای گفتاری انسانی یا ماشینی.
\n
\n* محدودیت‌های این نسخهٔ رایگان از OsmAnd:
\n- تعداد نقشه‌های قابل‌دانلود محدود است.
\n- به نقاط ویکی‌پدیایی به‌صورت آفلاین دسترسی ندارید.
\n- به نقاط ویکی‌پدیا به‌صورت آفلاین دسترسی ندارید.
\n
\n* ما فعالانه در حال توسعهٔ OsmAnd هستیم و این پروژه و پیشرفت پیوستهٔ آن نیازمند کمک‌های مالی شماست تا برای توسعه و افزودن قابلیت‌های تازه هزینه کنیم.
\n
\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همچنین OsmAnd می‌تواند به‌صورت آنلاین و آفلاین و با راهنمای صوتیِ گام‌به‌گام، برایتان مسیریابی کند.
\nهمچنین OsmAnd می‌تواند به‌صورت آنلاین و آفلاین مسیریابی کند و با راهنمای گفتاری شما را گام‌به‌گام هدایت کند.
\n
\nOsmAnd+ نسخهٔ پولی این برنامه است. با خریدن آن از این پروژه حمایت می‌کنید، سرمایه‌ای برای توسعهٔ قابلیت‌های جدید فراهم می‌کنید و آخرین به‌روزرسانی‌ها در اختیارتان قرار می‌گیرد.
\n
\n* از ویژگی‌های مهم:
@ -1100,7 +1101,7 @@
\n- امکان دانلود نامحدود نقشه‌های کشوری یا منطقه‌ای مستقیماً از طریق برنامه
\n- دسترسی به ویکی‌پدیا به‌صورت آفلاین (دانلود POIهای ویکی‌پدیا) که برای گردشگری بسیار مفید است
\n
\n- امکان قراردادن نقشه‌های مختلف بر روی هم در چند لایه؛ مانند ردهای GPX یا مسیریابی، مکان‌های محبوب یا POI، نقاط برگزیده، منحنی‌های تراز، ایستگاه‌های حمل‌ونقل عمومی، نقشه‌های دیگر با درصد شفافیت دلخواه
\n- امکان قراردادن نقشه‌های مختلف بر روی هم در چند لایه؛ مانند ردهای GPX یا مسیرپیمایی، مکان‌های محبوب یا POI، نقاط برگزیده، منحنی‌های تراز، ایستگاه‌های حمل‌ونقل عمومی، نقشه‌های دیگر با درصد شفافیت دلخواه
\n
\n- جست‌وجوی آفلاین مکان‌ها (POIها) و نشانی‌ها
\n- مسیریابی آفلاین برای مسافت‌های متوسط
@ -1109,7 +1110,7 @@
\n
\n- زوم وابسته به سرعت؛
\n- میزان‌کردن نقشه در جهت قطب‌نما یا در جهت حرکت؛
\n- راهنمای خط عبوری، نمایش محدودیت سرعت، راهنمای صوتی انسانی یا ماشینی</string>
\n- راهنمای خط عبوری، نمایش محدودیت سرعت، راهنمای گفتاری انسانی یا ماشینی</string>
<string name="asap">دراسرع‌وقت</string>
@ -1130,7 +1131,7 @@
\nhttps://openstreetmap.org
\n
\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="accessibility_mode">حالت دسترسی آسان</string>
@ -1173,7 +1174,7 @@
<string name="trace_rendering">اطلاعات عیب‌یابی رندرگیری</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_notification">منبع صدای اعلان</string>
<string name="voice_stream_music">منبع پخش صدای موسیقی/رسانه</string>
@ -1395,11 +1396,11 @@
<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="localization_pref_title">بومی‌سازی</string>
<string name="interrupt_music_descr">هنگام اعلام پیام‌های صوتی، پخش موسیقی نگه داشته شود، نه اینکه فقط آهسته شود.</string>
<string name="interrupt_music_descr">هنگام بیان پیام‌های گفتاری، پخش موسیقی نگه داشته شود، نه اینکه فقط آهسته شود.</string>
<string name="interrupt_music">مکث موسیقی</string>
<string name="share_route_as_gpx">اشتراک‌گذاری مسیر در قالب فایل GPX</string>
<string name="share_route_subject">مسیر از طریق OsmAnd به‌اشتراک گذاشته شد</string>
@ -1641,7 +1642,7 @@
<string name="shared_string_currently_recording_track">مسیر در حال ضبط</string>
<string name="back_to_map">برگشتن به نقشه</string>
<string name="plugin_touringview_name">نمای گشتی نقشه</string>
<string name="shared_string_audio">صدا</string>
<string name="shared_string_audio">شنیداری</string>
<string name="share_note">به‌اشتراک‌گذاری یادداشت</string>
@ -1770,9 +1771,9 @@
<string name="shared_string_enabled">فعال</string>
<string name="shared_string_disabled">غیرفعال</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="speed_limit_exceed_message">محدودهٔ حداکثر سرعت را انتخاب کنید؛ با گذشتن از این مقدار، هشدار صوتی خواهید شنید.</string>
<string name="speed_limit_exceed_message">محدودهٔ حداکثر سرعت را انتخاب کنید؛ با گذشتن از این مقدار، آوای هشدار پخش می‌شود.</string>
<string name="fav_point_emoticons_message">نام نقطهٔ برگزیده به %1$s تغییر کرد تا ذخیره‌سازی آن به‌همراه شکلک‌ها در فایل تسهیل شود.</string>
<string name="rendering_attr_hideHouseNumbers_name">پلاک خانه‌ها</string>
<string name="application_dir_change_warning3">فایل‌های دادهٔ OsmAnd به مکان جدید کپی شود؟</string>
@ -2266,8 +2267,8 @@
<string name="rec_split_storage_size_desc">مقدار فضای قابل‌تصرف برای همهٔ کلیپ‌های ضبط‌شده را مشخص کنید.</string>
<string name="live_updates">به‌روزرسانی‌های پویا</string>
<string name="available_maps">نقشه‌های موجود</string>
<string name="select_voice_provider">راهنمای صوتی را انتخاب کنید</string>
<string name="select_voice_provider_descr">راهنمای صوتی زبان خودتان را انتخاب یا دانلود کنید.</string>
<string name="select_voice_provider">راهنمای گفتاری را انتخاب کنید</string>
<string name="select_voice_provider_descr">راهنمای گفتاری برای زبان خود را انتخاب یا دانلود کنید.</string>
<string name="impassable_road_desc">جاده‌هایی که می‌خواهید در مسیریابی نباشند را انتخاب کنید.</string>
<string name="no_location_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_photo_note">یادداشت عکسی جدید</string>
<string name="quick_action_add_osm_bug">افزودن توضیح ویرایشی</string>
<string name="quick_action_navigation_voice">صدا روشن/خاموش</string>
<string name="quick_action_navigation_voice_off">صدا خاموش است</string>
<string name="quick_action_navigation_voice_on">صدا روشن است</string>
<string name="quick_action_navigation_voice">گفتار روشن/خاموش</string>
<string name="quick_action_navigation_voice_off">گفتار خاموش است</string>
<string name="quick_action_navigation_voice_on">گفتار روشن است</string>
<string name="quick_action_add_parking">افزودن جای پارک</string>
<string name="quick_action_new_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_add_osm_bug_descr">با لمس این دکمهٔ عملیاتی یک توضیح ویرایشی OSM در مرکز صفحه ایجاد می‌شود.</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="favorite_autofill_toast_text">" اینجا ذخیره شد: "</string>
<string name="favorite_empty_place_name">مکان</string>
@ -2754,12 +2755,12 @@
<string name="plugin_ski_descr">با این افزونه اطلاعات جهانی سراشیبی‌های اسکی، مسابقات اسکی صحرایی، مسیرهای اسکی آلپاین، تله‌کابین‌ها و نقاله‌های اسکی کاملاً در اختیارتان است. مسیرها و پیست‌ها بر اساس دشواری رنگ‌بندی شده‌اند که در یک سبک زمستانی ارائه می‌شوند تا نمایی همگون با محیط زمستانی را برایتان ایجاد کند.
\n
\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راهبر دیداری و شنیداری، مشاهدهٔ مکان‌های محبوب (POIها یا Points of interest)، ایجاد و مدیریت ردهای GPX، استفاده از تصویرسازی منحنی‌های تراز و اطلاعات ارتفاع (با استفاده از افزونه)، انتخاب حالت‌های پیاده، دوچرخه، خودرو، امکان ویرایش مکان‌ها و... چیزهایی هستند که تجربهٔ مؤثر و لذت‌بخشی در کار با نقشه را برایتان به ارمغان می‌آورند.</string>
<string name="osmand_extended_description_part2">راهبری با GPS
\n • امکان انتخاب بین حالت آنلاین و آفلاین؛ در حالت آفلاین هزینهٔ دیگری بابت اینترنت نمی‌پردازید و در حالت آنلاین عملکرد سریع‌تری را تجربه می‌کنید
\n • راهنمای گام‌به‌گام صوتی که در پیمودن مسیر راهنمایی‌تان می‌کند (با پیام‌های صوتی انسانی و ماشینی)
\n • راهنمای گام‌به‌گام گفتاری که در پیمودن مسیر راهنمایی‌تان می‌کند (با پیام‌های گفتاری انسانی و ماشینی)
\n • اگر از مسیر منحرف شوید، مسیر جدیدی برایتان پیدا می‌کند
\n • راهنمای خطوط عبوری، نام خیابان‌ها و زمان تخمینی رسیدن را دریافت می‌کنید که در طول مسیر راهنمای شماست
\n • برای داشتن سفری ایمن‌تر، حالات شب/روز به‌صورت خودکار انتخاب می‌شود
@ -2801,7 +2802,7 @@
<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راهبر دیداری و شنیداری، مشاهدهٔ مکان‌های محبوب (POIها یا Points of interest)، ایجاد و مدیریت ردهای GPX، استفاده از تصویرسازی منحنی‌های تراز و اطلاعات ارتفاع، انتخاب حالت‌های پیاده، دوچرخه، خودرو، امکان ویرایش مکان‌ها و... چیزهایی هستند که تجربهٔ مؤثر و لذت‌بخشی را در کار با نقشه برایتان به ارمغان می‌آورد.
\n
@ -2857,7 +2858,7 @@
\nاز یک مسیریاب معتبر و قابل‌اعتماد استفاده کنید. هر کجا که هستید؛ در فرانسه، آلمان، انگلستان، مکزیک، آمریکا، هلند، ایران، روسیه، برزیل یا هر جای دیگر، فرقی نمی‌کند.</string>
<string name="osmand_plus_extended_description_part2">راهبری
\n • امکان انتخاب بین حالت آنلاین (سریع) و آفلاین (بدون هزینهٔ اضافی بابت اینترنت)
\n • راهنمای گام‌به‌گام صوتی (پیام‌های صوتی انسانی و ماشینی)
\n • راهنمای گام‌به‌گام گفتاری (پیام‌های گفتاری انسانی و ماشینی)
\n • راهنمای خطوط عبوری، نام خیابان‌ها و زمان تخمینی رسیدن
\n • پشتیبانی از نقاط بین‌راهی مسیر
\n • اگر از مسیر منحرف شوید، مسیر جدیدی برایتان پیدا می‌کند
@ -3190,5 +3191,5 @@
\n • اصلاح مشکلاتی دیگر
\n
\n"</string>
<string name="test_voice_desrc">روی یکی از دکمه‌ها بزنید و فرمان صوتی متناظر با آن را بشنوید تا فرمان‌های مشکل‌دار یا ناموجود را شناسایی کنید.</string>
<string name="test_voice_desrc">روی یکی از دکمه‌ها بزنید و فرمان گفتاری متناظر با آن را بشنوید تا فرمان‌های مشکل‌دار یا ناموجود را شناسایی کنید.</string>
</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_ferries">Forðast ferjur</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="bg_service_sleep_mode_off">Keyra
forrit í bakgrunni</string>
@ -2938,7 +2938,7 @@ 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="shared_string_world">Veröld</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
@ -2948,9 +2948,11 @@ Stendur fyrir svæði: %1$s x %2$s</string>
\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 • Lagfæringar á öðrum göllum
\n
\n</string>
\n"</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="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?
\nLáttu okkur vita</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_arrows_descr">Toon pijlen richting de actieve 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.SearchParams;
import net.osmand.aidl.navigation.NavigateSearchParams;
// NOTE: Add new methods at the end of file!!!
@ -128,6 +129,7 @@ interface IOsmAndAidlInterface {
boolean unmuteNavigation(in UnmuteNavigationParams params);
boolean search(in SearchParams params, IOsmAndAidlCallback callback);
boolean navigateSearch(in NavigateSearchParams params);
boolean registerForUpdates(in long updateTimeMS, IOsmAndAidlCallback callback);
boolean unregisterFromUpdates(in IOsmAndAidlCallback callback);

View file

@ -19,6 +19,7 @@ import android.view.View;
import android.widget.ArrayAdapter;
import net.osmand.IndexConstants;
import net.osmand.Location;
import net.osmand.PlatformUtil;
import net.osmand.aidl.favorite.AFavorite;
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.mapmarker.AMapMarker;
import net.osmand.aidl.mapwidget.AMapWidget;
import net.osmand.aidl.search.SearchParams;
import net.osmand.aidl.search.SearchResult;
import net.osmand.data.FavouritePoint;
import net.osmand.data.LatLon;
@ -48,14 +48,14 @@ import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.OsmandApplication;
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.audionotes.AudioVideoNotesPlugin;
import net.osmand.plus.dialogs.ConfigureMapMenu;
import net.osmand.plus.helpers.ColorDialogs;
import net.osmand.plus.helpers.ExternalApiHelper;
import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.search.listitems.QuickSearchListItem;
import net.osmand.plus.views.AidlMapLayer;
import net.osmand.plus.views.MapInfoLayer;
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.mapwidgets.MapWidgetRegistry.MapWidgetRegInfo;
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 org.apache.commons.logging.Log;
@ -82,6 +78,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
@ -90,15 +87,6 @@ import java.util.Map;
import java.util.TreeMap;
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 {
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_URI = "aidl_uri";
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";
@ -135,6 +124,7 @@ public class OsmandAidlApi {
private static final String AIDL_NAVIGATE = "aidl_navigate";
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_RESUME_NAVIGATION = "resume_navigation";
private static final String AIDL_STOP_NAVIGATION = "stop_navigation";
@ -166,7 +156,7 @@ public class OsmandAidlApi {
this.app = app;
}
public void onCreateMapActivity(final MapActivity mapActivity) {
public void onCreateMapActivity(MapActivity mapActivity) {
mapActivityActive = true;
registerRefreshMapReceiver(mapActivity);
registerSetMapLocationReceiver(mapActivity);
@ -180,6 +170,7 @@ public class OsmandAidlApi {
registerStopRecordingReceiver(mapActivity);
registerNavigateReceiver(mapActivity);
registerNavigateGpxReceiver(mapActivity);
registerNavigateSearchReceiver(mapActivity);
registerPauseNavigationReceiver(mapActivity);
registerResumeNavigationReceiver(mapActivity);
registerStopNavigationReceiver(mapActivity);
@ -187,7 +178,7 @@ public class OsmandAidlApi {
registerUnmuteNavigationReceiver(mapActivity);
}
public void onDestroyMapActivity(final MapActivity mapActivity) {
public void onDestroyMapActivity(MapActivity mapActivity) {
mapActivityActive = false;
for (BroadcastReceiver b : receivers.values()) {
if(b == null) {
@ -206,40 +197,48 @@ public class OsmandAidlApi {
return mapActivityActive;
}
private void registerRefreshMapReceiver(final MapActivity mapActivity) {
private void registerRefreshMapReceiver(MapActivity mapActivity) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
BroadcastReceiver refreshMapReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
mapActivity.refreshMap();
MapActivity mapActivity = mapActivityRef.get();
if (mapActivity != null) {
mapActivity.refreshMap();
}
}
};
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() {
@Override
public void onReceive(Context context, Intent intent) {
double lat = intent.getDoubleExtra(AIDL_LATITUDE, Double.NaN);
double lon = intent.getDoubleExtra(AIDL_LONGITUDE, Double.NaN);
int zoom = intent.getIntExtra(AIDL_ZOOM, 0);
boolean animated = intent.getBooleanExtra(AIDL_ANIMATED, false);
if (!Double.isNaN(lat) && !Double.isNaN(lon)) {
OsmandMapTileView mapView = mapActivity.getMapView();
if (zoom == 0) {
zoom = mapView.getZoom();
} else {
zoom = zoom > mapView.getMaxZoom() ? mapView.getMaxZoom() : zoom;
zoom = zoom < mapView.getMinZoom() ? mapView.getMinZoom() : zoom;
}
if (animated) {
mapView.getAnimatedDraggingThread().startMoving(lat, lon, zoom, true);
} else {
mapView.setLatLon(lat, lon);
mapView.setIntZoom(zoom);
MapActivity mapActivity = mapActivityRef.get();
if (mapActivity != null) {
double lat = intent.getDoubleExtra(AIDL_LATITUDE, Double.NaN);
double lon = intent.getDoubleExtra(AIDL_LONGITUDE, Double.NaN);
int zoom = intent.getIntExtra(AIDL_ZOOM, 0);
boolean animated = intent.getBooleanExtra(AIDL_ANIMATED, false);
if (!Double.isNaN(lat) && !Double.isNaN(lon)) {
OsmandMapTileView mapView = mapActivity.getMapView();
if (zoom == 0) {
zoom = mapView.getZoom();
} else {
zoom = zoom > mapView.getMaxZoom() ? mapView.getMaxZoom() : zoom;
zoom = zoom < mapView.getMinZoom() ? mapView.getMinZoom() : zoom;
}
if (animated) {
mapView.getAnimatedDraggingThread().startMoving(lat, lon, zoom, true);
} else {
mapView.setLatLon(lat, lon);
mapView.setIntZoom(zoom);
}
}
mapActivity.refreshMap();
}
mapActivity.refreshMap();
}
};
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() {
@Override
public void onReceive(Context context, Intent intent) {
MapActivity mapActivity = mapActivityRef.get();
String widgetId = intent.getStringExtra(AIDL_OBJECT_ID);
if (widgetId != null) {
if (mapActivity != null && widgetId != null) {
AMapWidget widget = widgets.get(widgetId);
if (widget != null) {
MapInfoLayer layer = mapActivity.getMapLayers().getMapInfoLayer();
@ -287,12 +288,14 @@ public class OsmandAidlApi {
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() {
@Override
public void onReceive(Context context, Intent intent) {
MapActivity mapActivity = mapActivityRef.get();
String widgetId = intent.getStringExtra(AIDL_OBJECT_ID);
if (widgetId != null) {
if (mapActivity != null && widgetId != null) {
MapInfoLayer layer = mapActivity.getMapLayers().getMapInfoLayer();
TextInfoWidget widgetControl = widgetControls.get(widgetId);
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() {
@Override
public void onReceive(Context context, Intent intent) {
MapActivity mapActivity = mapActivityRef.get();
String layerId = intent.getStringExtra(AIDL_OBJECT_ID);
if (layerId != null) {
if (mapActivity != null && layerId != null) {
AMapLayer layer = layers.get(layerId);
if (layer != null) {
OsmandMapLayer mapLayer = mapLayers.get(layerId);
@ -345,12 +350,14 @@ public class OsmandAidlApi {
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() {
@Override
public void onReceive(Context context, Intent intent) {
MapActivity mapActivity = mapActivityRef.get();
String layerId = intent.getStringExtra(AIDL_OBJECT_ID);
if (layerId != null) {
if (mapActivity != null && layerId != null) {
OsmandMapLayer mapLayer = mapLayers.remove(layerId);
if (mapLayer != null) {
mapActivity.getMapView().removeLayer(mapLayer);
@ -362,12 +369,14 @@ public class OsmandAidlApi {
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() {
@Override
public void onReceive(Context context, Intent intent) {
MapActivity mapActivity = mapActivityRef.get();
final AudioVideoNotesPlugin plugin = OsmandPlugin.getEnabledPlugin(AudioVideoNotesPlugin.class);
if (plugin != null) {
if (mapActivity != null && plugin != null) {
double lat = intent.getDoubleExtra(AIDL_LATITUDE, Double.NaN);
double lon = intent.getDoubleExtra(AIDL_LONGITUDE, Double.NaN);
plugin.takePhoto(lat, lon, mapActivity, false, true);
@ -377,12 +386,14 @@ public class OsmandAidlApi {
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() {
@Override
public void onReceive(Context context, Intent intent) {
MapActivity mapActivity = mapActivityRef.get();
final AudioVideoNotesPlugin plugin = OsmandPlugin.getEnabledPlugin(AudioVideoNotesPlugin.class);
if (plugin != null) {
if (mapActivity != null && plugin != null) {
double lat = intent.getDoubleExtra(AIDL_LATITUDE, Double.NaN);
double lon = intent.getDoubleExtra(AIDL_LONGITUDE, Double.NaN);
plugin.recordVideo(lat, lon, mapActivity, true);
@ -392,12 +403,14 @@ public class OsmandAidlApi {
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() {
@Override
public void onReceive(Context context, Intent intent) {
MapActivity mapActivity = mapActivityRef.get();
final AudioVideoNotesPlugin plugin = OsmandPlugin.getEnabledPlugin(AudioVideoNotesPlugin.class);
if (plugin != null) {
if (mapActivity != null && plugin != null) {
double lat = intent.getDoubleExtra(AIDL_LATITUDE, Double.NaN);
double lon = intent.getDoubleExtra(AIDL_LONGITUDE, Double.NaN);
plugin.recordAudio(lat, lon, mapActivity);
@ -407,12 +420,14 @@ public class OsmandAidlApi {
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() {
@Override
public void onReceive(Context context, Intent intent) {
MapActivity mapActivity = mapActivityRef.get();
final AudioVideoNotesPlugin plugin = OsmandPlugin.getEnabledPlugin(AudioVideoNotesPlugin.class);
if (plugin != null) {
if (mapActivity != null && plugin != null) {
plugin.stopRecording(mapActivity, false);
}
}
@ -420,7 +435,8 @@ public class OsmandAidlApi {
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() {
@Override
public void onReceive(Context context, Intent intent) {
@ -433,7 +449,8 @@ public class OsmandAidlApi {
break;
}
}
if (validProfile) {
MapActivity mapActivity = mapActivityRef.get();
if (mapActivity != null && validProfile) {
String startName = intent.getStringExtra(AIDL_START_NAME);
if (Algorithms.isEmpty(startName)) {
startName = "";
@ -468,13 +485,14 @@ public class OsmandAidlApi {
@Override
public void onDismiss(DialogInterface dialog) {
if (!routingHelper.isFollowingMode()) {
startNavigation(mapActivity, null, start, startDesc, dest, destDesc, profile);
MapActivity mapActivity = mapActivityRef.get();
if (mapActivity != null && !routingHelper.isFollowingMode()) {
ExternalApiHelper.startNavigation(mapActivity, start, startDesc, dest, destDesc, profile);
}
}
});
} 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);
}
private void registerNavigateGpxReceiver(final MapActivity mapActivity) {
BroadcastReceiver navigateGpxReceiver = new BroadcastReceiver() {
private void registerNavigateSearchReceiver(MapActivity mapActivity) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
BroadcastReceiver navigateSearchReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
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()));
String profileStr = intent.getStringExtra(AIDL_PROFILE);
final ApplicationMode profile = ApplicationMode.valueOfStringKey(profileStr, DEFAULT_PROFILE);
boolean validProfile = false;
for (ApplicationMode mode : VALID_PROFILES) {
if (mode == profile) {
validProfile = true;
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;
try {
gpxParcelDescriptor = mapActivity.getContentResolver().openFileDescriptor(gpxUri, "r");
} catch (FileNotFoundException e) {
e.printStackTrace();
final LatLon start;
final PointDescription startDesc;
double startLat = intent.getDoubleExtra(AIDL_START_LAT, 0);
double startLon = intent.getDoubleExtra(AIDL_START_LON, 0);
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) {
final RoutingHelper routingHelper = app.getRoutingHelper();
if (routingHelper.isFollowingMode() && !force) {
final GPXFile gpxFile = gpx;
AlertDialog dlg = mapActivity.getMapActions().stopNavigationActionConfirm();
dlg.setOnDismissListener(new DialogInterface.OnDismissListener() {
private void registerNavigateGpxReceiver(MapActivity mapActivity) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
BroadcastReceiver navigateGpxReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
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
public void onDismiss(DialogInterface dialog) {
if (!routingHelper.isFollowingMode()) {
startNavigation(mapActivity, gpxFile, null, null, null, null, null);
}
ParcelFileDescriptor gpxParcelDescriptor = null;
try {
gpxParcelDescriptor = mapActivity.getContentResolver().openFileDescriptor(gpxUri, "r");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
});
} else {
startNavigation(mapActivity, gpx, null, null, null, null, null);
if (gpxParcelDescriptor != null) {
FileDescriptor fileDescriptor = gpxParcelDescriptor.getFileDescriptor();
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);
}
private void startNavigation(MapActivity mapActivity,
GPXFile gpx,
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) {
private void registerPauseNavigationReceiver(MapActivity mapActivity) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
BroadcastReceiver pauseNavigationReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
RoutingHelper routingHelper = mapActivity.getRoutingHelper();
if (routingHelper.isRouteCalculated() && !routingHelper.isRoutePlanningMode()) {
routingHelper.setRoutePlanningMode(true);
routingHelper.setFollowingMode(false);
routingHelper.setPauseNavigation(true);
MapActivity mapActivity = mapActivityRef.get();
if (mapActivity != null) {
RoutingHelper routingHelper = mapActivity.getRoutingHelper();
if (routingHelper.isRouteCalculated() && !routingHelper.isRoutePlanningMode()) {
routingHelper.setRoutePlanningMode(true);
routingHelper.setFollowingMode(false);
routingHelper.setPauseNavigation(true);
}
}
}
};
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() {
@Override
public void onReceive(Context context, Intent intent) {
RoutingHelper routingHelper = mapActivity.getRoutingHelper();
if (routingHelper.isRouteCalculated() && routingHelper.isRoutePlanningMode()) {
routingHelper.setRoutePlanningMode(false);
routingHelper.setFollowingMode(true);
MapActivity mapActivity = mapActivityRef.get();
if (mapActivity != null) {
RoutingHelper routingHelper = mapActivity.getRoutingHelper();
if (routingHelper.isRouteCalculated() && routingHelper.isRoutePlanningMode()) {
routingHelper.setRoutePlanningMode(false);
routingHelper.setFollowingMode(true);
}
}
}
};
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() {
@Override
public void onReceive(Context context, Intent intent) {
RoutingHelper routingHelper = mapActivity.getRoutingHelper();
if (routingHelper.isPauseNavigation() || routingHelper.isFollowingMode()) {
mapActivity.getMapLayers().getMapControlsLayer().stopNavigationWithoutConfirm();
MapActivity mapActivity = mapActivityRef.get();
if (mapActivity != null) {
RoutingHelper routingHelper = mapActivity.getRoutingHelper();
if (routingHelper.isPauseNavigation() || routingHelper.isFollowingMode()) {
mapActivity.getMapLayers().getMapControlsLayer().stopNavigationWithoutConfirm();
}
}
}
};
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() {
@Override
public void onReceive(Context context, Intent intent) {
mapActivity.getMyApplication().getSettings().VOICE_MUTE.set(true);
mapActivity.getRoutingHelper().getVoiceRouter().setMute(true);
MapActivity mapActivity = mapActivityRef.get();
if (mapActivity != null) {
mapActivity.getMyApplication().getSettings().VOICE_MUTE.set(true);
mapActivity.getRoutingHelper().getVoiceRouter().setMute(true);
}
}
};
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() {
@Override
public void onReceive(Context context, Intent intent) {
mapActivity.getMyApplication().getSettings().VOICE_MUTE.set(false);
mapActivity.getRoutingHelper().getVoiceRouter().setMute(false);
MapActivity mapActivity = mapActivityRef.get();
if (mapActivity != null) {
mapActivity.getMyApplication().getSettings().VOICE_MUTE.set(false);
mapActivity.getRoutingHelper().getVoiceRouter().setMute(false);
}
}
};
registerReceiver(unmuteNavigationReceiver, mapActivity, AIDL_UNMUTE_NAVIGATION);
@ -646,7 +723,7 @@ public class OsmandAidlApi {
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) {
@Override
@ -1292,6 +1369,19 @@ public class OsmandAidlApi {
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() {
Intent intent = new Intent();
intent.setAction(AIDL_PAUSE_NAVIGATION);
@ -1350,73 +1440,15 @@ public class OsmandAidlApi {
@Override
public void onFinish(AppInitializer init) {
runSearch(searchQuery, searchType, latitude, longitude, radiusLevel, totalLimit, callback);
ExternalApiHelper.runSearch(app, searchQuery, searchType, latitude, longitude, radiusLevel, totalLimit, callback);
}
});
} else {
runSearch(searchQuery, searchType, latitude, longitude, radiusLevel, totalLimit, callback);
ExternalApiHelper.runSearch(app, searchQuery, searchType, latitude, longitude, radiusLevel, totalLimit, callback);
}
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) {
if (!TextUtils.isEmpty(appPackage) && items != null) {
if (items.isEmpty()) {

View file

@ -8,6 +8,7 @@ import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Parcelable;
import android.os.RemoteException;
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.NavigateGpxParams;
import net.osmand.aidl.navigation.NavigateParams;
import net.osmand.aidl.navigation.NavigateSearchParams;
import net.osmand.aidl.navigation.PauseNavigationParams;
import net.osmand.aidl.navigation.ResumeNavigationParams;
import net.osmand.aidl.navigation.StopNavigationParams;
@ -71,10 +73,8 @@ public class OsmandAidlService extends Service {
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 ArrayList<IOsmAndAidlCallback> mRemoteCallbacks;
private Map<Long, IOsmAndAidlCallback> callbacks;
private ServiceHandler mHandler = null;
HandlerThread mHandlerThread = new HandlerThread("OsmAndAidlServiceThread");
@ -104,7 +104,6 @@ public class OsmandAidlService extends Service {
public void onCreate() {
super.onCreate();
mRemoteCallbacks = new ArrayList<>();
callbacks = new HashMap<>();
}
@ -482,7 +481,10 @@ public class OsmandAidlService extends Service {
@Override
public boolean navigate(NavigateParams params) throws RemoteException {
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) {
handleException(e);
return false;
@ -563,14 +565,18 @@ public class OsmandAidlService extends Service {
public boolean search(SearchParams params, final IOsmAndAidlCallback callback) throws RemoteException {
try {
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
public void onSearchComplete(List<SearchResult> resultSet) {
Bundle data = new Bundle();
if (resultSet.size() > 0) {
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) {
@ -617,56 +623,16 @@ public class OsmandAidlService extends Service {
}
}), 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
public void handleMessage(Message msg) {
callbackIndex = msg.arg1;
switch (msg.what) {
case MSG_RUN_SEARCH:
Bundle data = msg.getData();
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;
public boolean navigateSearch(NavigateSearchParams params) throws RemoteException {
try {
return params != null && getApi("navigateSearch").navigateSearch(
params.getStartName(), params.getStartLat(), params.getStartLon(),
params.getSearchQuery(), params.getProfile(), params.isForce());
} catch (Exception e) {
handleException(e);
return false;
}
}
}
};
}

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

View file

@ -1,17 +1,23 @@
package net.osmand.plus.helpers;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.ParcelFileDescriptor;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import net.osmand.AndroidUtils;
import net.osmand.IndexConstants;
import net.osmand.Location;
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.LatLon;
import net.osmand.data.PointDescription;
@ -23,6 +29,7 @@ import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.TargetPointsHelper;
import net.osmand.plus.activities.MapActivity;
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.RouteDirectionInfo;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.search.listitems.QuickSearchListItem;
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 java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
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 {
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 = "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_RESUME_NAVIGATION = "resume_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_GPX_NOT_FOUND = 1004;
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 int resultCode;
@ -199,12 +226,12 @@ public class ExternalApiHelper {
@Override
public void onDismiss(DialogInterface dialog) {
if (!routingHelper.isFollowingMode()) {
startNavigation(gpxFile, null, null, null, null, null);
startNavigation(mapActivity, gpxFile);
}
}
});
} else {
startNavigation(gpx, null, null, null, null, null);
startNavigation(mapActivity, gpx);
}
} else {
app.getSelectedGpxHelper().setGpxFileToDisplay(gpx);
@ -237,7 +264,6 @@ public class ExternalApiHelper {
destName = "";
}
final LatLon start;
final PointDescription startDesc;
String startLatStr = uri.getQueryParameter(PARAM_START_LAT);
@ -252,7 +278,6 @@ public class ExternalApiHelper {
startDesc = null;
}
String destSearchQuery = uri.getQueryParameter(PARAM_DEST_SEARCH_QUERY);
String destLatStr = uri.getQueryParameter(PARAM_DEST_LAT);
String destLonStr = uri.getQueryParameter(PARAM_DEST_LON);
final LatLon dest;
@ -262,9 +287,6 @@ public class ExternalApiHelper {
dest = new LatLon(destLat, destLon);
} else {
dest = null;
}
if (!Algorithms.isEmpty(destSearchQuery)) {
}
final PointDescription destDesc = new PointDescription(PointDescription.POINT_TYPE_LOCATION, destName);
@ -278,12 +300,76 @@ public class ExternalApiHelper {
@Override
public void onDismiss(DialogInterface dialog) {
if (!routingHelper.isFollowingMode()) {
startNavigation(null, start, startDesc, dest, destDesc, profile);
startNavigation(mapActivity, start, startDesc, dest, destDesc, profile);
}
}
});
} 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);
}
private void startNavigation(GPXFile gpx,
LatLon from, PointDescription fromDesc,
LatLon to, PointDescription toDesc,
ApplicationMode mode) {
static public void startNavigation(MapActivity mapActivity,
@NonNull GPXFile gpx) {
startNavigation(mapActivity, gpx, null, null, null, null, null);
}
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();
RoutingHelper routingHelper = app.getRoutingHelper();
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) {
Uri uri = null;
Intent intent = null;