diff --git a/OsmAnd-java/src/net/osmand/search/core/SearchPhrase.java b/OsmAnd-java/src/net/osmand/search/core/SearchPhrase.java index ee4c881168..5d313ea136 100644 --- a/OsmAnd-java/src/net/osmand/search/core/SearchPhrase.java +++ b/OsmAnd-java/src/net/osmand/search/core/SearchPhrase.java @@ -587,6 +587,9 @@ public class SearchPhrase { Iterator it = indexes.iterator(); while (it.hasNext()) { BinaryMapIndexReader r = it.next(); + if(r == null || r.getFile() == null) { + continue; + } String filename = r.getFile().getName(); if (filename.matches("([a-zA-Z-]+_)+([0-9]+_){2}[0-9]+\\.obf")) { String currRegionName = r.getRegionName(); diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java index 47330d8464..787ac4a13c 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java +++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java @@ -599,7 +599,11 @@ public class OsmandApplication extends MultiDexApplication { } if (routingHelper.isFollowingMode()) { AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE); - mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 2000, intent); + if (Build.VERSION.SDK_INT >= 19) { + mgr.setExact(AlarmManager.RTC, System.currentTimeMillis() + 2000, intent); + } else { + mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 2000, intent); + } System.exit(2); } defaultHandler.uncaughtException(thread, ex); diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 6ec8ed06fb..c227c9fbca 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -951,7 +951,11 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven .getActivity(c, mPendingIntentId, mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT); AlarmManager mgr = (AlarmManager) c.getSystemService(Context.ALARM_SERVICE); - mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent); + if (Build.VERSION.SDK_INT >= 19) { + mgr.setExact(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent); + } else { + mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent); + } //kill the application res = true; android.os.Process.killProcess(android.os.Process.myPid()); diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDbHelper.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDbHelper.java index fdb2b315ef..3cab3d6b15 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDbHelper.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDbHelper.java @@ -12,12 +12,16 @@ import net.osmand.plus.api.SQLiteAPI.SQLiteConnection; import net.osmand.plus.api.SQLiteAPI.SQLiteCursor; import net.osmand.plus.helpers.SearchHistoryHelper; +import java.util.ArrayList; import java.util.Calendar; -import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Random; +import java.util.Set; public class MapMarkersDbHelper { @@ -406,8 +410,8 @@ public class MapMarkersDbHelper { } public List getActiveMarkers() { - List res = new LinkedList<>(); - HashMap markers = new LinkedHashMap<>(); + Map markers = new LinkedHashMap<>(); + Set nextKeys = new HashSet<>(); SQLiteConnection db = openConnection(true); if (db != null) { try { @@ -417,15 +421,15 @@ public class MapMarkersDbHelper { do { MapMarker marker = readItem(query); markers.put(marker.id, marker); + nextKeys.add(marker.nextKey); } while (query.moveToNext()); } query.close(); } finally { db.close(); } - buildLinkedList(markers, res); } - return res; + return buildLinkedList(markers, nextKeys); } private MapMarker readItem(SQLiteCursor query) { @@ -457,19 +461,32 @@ public class MapMarkersDbHelper { return marker; } - private void buildLinkedList(HashMap markers, List res) { - if (!markers.isEmpty()) { - int count = 1; - for (MapMarker marker : markers.values()) { - if (!markers.keySet().contains(marker.nextKey) || count == markers.size()) { - res.add(0, marker); - markers.remove(marker.id); + private List buildLinkedList(Map markers, Set nextKeys) { + List res = new ArrayList<>(markers.size()); + + while (!markers.isEmpty()) { + MapMarker head = null; + + Iterator iterator = markers.values().iterator(); + while (iterator.hasNext()) { + MapMarker marker = iterator.next(); + if (!nextKeys.contains(marker.id) || !iterator.hasNext()) { + head = marker; break; } - count++; } - buildLinkedList(markers, res); + + if (head == null) { + break; + } + + do { + res.add(head); + markers.remove(head.id); + } while ((head = markers.get(head.nextKey)) != null); } + + return res; } public void updateMarker(MapMarker marker) { diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/MainActivity.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/MainActivity.java index ffef7a4dca..a3303fede5 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/MainActivity.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/MainActivity.java @@ -6,6 +6,7 @@ import android.content.DialogInterface; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.content.pm.PackageManager; +import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.PointF; @@ -341,38 +342,39 @@ public class MainActivity extends AppCompatActivity implements SampleLocationLis public void initMapMarkers() { // Create my location marker - Drawable myLocationDrawable = OsmandResources.getDrawable("map_pedestrian_location"); myMarkersCollection = new MapMarkersCollection(); - myLocationMarker = new MapMarkerBuilder() - .setMarkerId(MARKER_ID_MY_LOCATION) - .setIsAccuracyCircleSupported(true) - .setAccuracyCircleBaseColor(new FColorRGB(32/255f, 173/255f, 229/255f)) - .setBaseOrder(-206000) - .setIsHidden(true) - //.addOnMapSurfaceIcon(SwigUtilities.getOnSurfaceIconKey(0), SwigUtilities.createSkBitmapARGB888With( - // myLocationDrawable.getIntrinsicWidth(), myLocationDrawable.getIntrinsicHeight(), - // SampleUtils.getDrawableAsByteArray(myLocationDrawable))) - .setPinIcon(SwigUtilities.createSkBitmapARGB888With( - myLocationDrawable.getIntrinsicWidth(), myLocationDrawable.getIntrinsicHeight(), - SampleUtils.getDrawableAsByteArray(myLocationDrawable))) - .buildAndAddToCollection(myMarkersCollection); + MapMarkerBuilder myLocMarkerBuilder = new MapMarkerBuilder(); + myLocMarkerBuilder.setMarkerId(MARKER_ID_MY_LOCATION); + myLocMarkerBuilder.setIsAccuracyCircleSupported(true); + myLocMarkerBuilder.setAccuracyCircleBaseColor(new FColorRGB(32/255f, 173/255f, 229/255f)); + myLocMarkerBuilder.setBaseOrder(-206000); + myLocMarkerBuilder.setIsHidden(true); + Bitmap myLocationBitmap = OsmandResources.getBitmap("map_pedestrian_location"); + if (myLocationBitmap != null) { + myLocMarkerBuilder.setPinIcon(SwigUtilities.createSkBitmapARGB888With( + myLocationBitmap.getWidth(), myLocationBitmap.getHeight(), + SampleUtils.getBitmapAsByteArray(myLocationBitmap))); + } + myLocationMarker = myLocMarkerBuilder.buildAndAddToCollection(myMarkersCollection); mapView.addSymbolsProvider(myMarkersCollection); // Create context pin marker - Drawable pinDrawable = OsmandResources.getDrawable("map_pin_context_menu"); contextPinMarkersCollection = new MapMarkersCollection(); - contextPinMarker = new MapMarkerBuilder() - .setMarkerId(MARKER_ID_CONTEXT_PIN) - .setIsAccuracyCircleSupported(false) - .setBaseOrder(-210000) - .setIsHidden(true) - .setPinIcon(SwigUtilities.createSkBitmapARGB888With( - pinDrawable.getIntrinsicWidth(), pinDrawable.getIntrinsicHeight(), - SampleUtils.getDrawableAsByteArray(pinDrawable))) - .setPinIconVerticalAlignment(MapMarker.PinIconVerticalAlignment.Top) - .setPinIconHorisontalAlignment(MapMarker.PinIconHorisontalAlignment.CenterHorizontal) - .buildAndAddToCollection(contextPinMarkersCollection); + MapMarkerBuilder contextMarkerBuilder = new MapMarkerBuilder(); + contextMarkerBuilder.setMarkerId(MARKER_ID_CONTEXT_PIN); + contextMarkerBuilder.setIsAccuracyCircleSupported(false); + contextMarkerBuilder.setBaseOrder(-210000); + contextMarkerBuilder.setIsHidden(true); + Bitmap pinBitmap = OsmandResources.getBitmap("map_pin_context_menu"); + if (pinBitmap != null) { + contextMarkerBuilder.setPinIcon(SwigUtilities.createSkBitmapARGB888With( + pinBitmap.getWidth(), pinBitmap.getHeight(), + SampleUtils.getBitmapAsByteArray(pinBitmap))); + contextMarkerBuilder.setPinIconVerticalAlignment(MapMarker.PinIconVerticalAlignment.Top); + contextMarkerBuilder.setPinIconHorisontalAlignment(MapMarker.PinIconHorisontalAlignment.CenterHorizontal); + } + contextPinMarker = contextMarkerBuilder.buildAndAddToCollection(contextPinMarkersCollection); mapView.addSymbolsProvider(contextPinMarkersCollection); } diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/OsmandResources.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/OsmandResources.java index dc1c2cf9c3..06788ba2b3 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/OsmandResources.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/OsmandResources.java @@ -3,7 +3,11 @@ package net.osmand.core.samples.android.sample1; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.graphics.drawable.Drawable; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.v4.graphics.drawable.DrawableCompat; import java.util.HashMap; @@ -50,15 +54,18 @@ public class OsmandResources { } } + @Nullable public static Resources getOsmandResources() { return osmandResources; } - public static String getString(String id) { + @Nullable + public static String getString(@NonNull String id) { return getStringInternal(resolveStringId(id)); } - public static String getString(String id, Object... formatArgs) { + @Nullable + public static String getString(@NonNull String id, @NonNull Object... formatArgs) { int resolvedId = resolveStringId(id); if (resolvedId != 0) { return osmandResources.getString(resolvedId, formatArgs); @@ -66,18 +73,31 @@ public class OsmandResources { return null; } - public static Drawable getDrawable(String id) { + @Nullable + public static Drawable getDrawable(@NonNull String id) { return getDrawableInternal(resolveDrawableId(id)); } - public static Drawable getBigDrawable(String id) { + @Nullable + public static Drawable getBigDrawable(@NonNull String id) { return getDrawableInternal(resolveDrawableId(BIG_ICON_PREFIX + id)); } + @Nullable public static Drawable getDrawable(int id) { return getDrawableInternal(id); } + @Nullable + public static Bitmap getBitmap(@NonNull String id) { + int resId = resolveDrawableId(id); + if (osmandResources != null && resId != 0) { + return BitmapFactory.decodeResource(osmandResources, resId); + } + return null; + } + + @Nullable public static Drawable getDrawableNonCached(int id) { if (osmandResources != null && id != 0) { Drawable d = osmandResources.getDrawable(id); @@ -90,14 +110,15 @@ public class OsmandResources { return null; } - public static int getDrawableId(String id) { + public static int getDrawableId(@NonNull String id) { return resolveDrawableId(id); } - public static int getBigDrawableId(String id) { + public static int getBigDrawableId(@NonNull String id) { return resolveDrawableId(BIG_ICON_PREFIX + id); } + @Nullable private static Drawable getDrawableInternal(int resId) { if (osmandResources != null && resId != 0) { long hash = getResIdHash(resId); @@ -115,6 +136,7 @@ public class OsmandResources { return null; } + @Nullable private static String getStringInternal(int resId) { if (osmandResources != null && resId != 0) { long hash = getResIdHash(resId); @@ -128,7 +150,7 @@ public class OsmandResources { return null; } - private static int resolveStringId(String id) { + private static int resolveStringId(@NonNull String id) { if (osmandResources != null) { Integer resolvedId = stringIds.get(id); if (resolvedId == null) { @@ -140,7 +162,7 @@ public class OsmandResources { return 0; } - private static int resolveDrawableId(String id) { + private static int resolveDrawableId(@NonNull String id) { if (osmandResources != null) { Integer resolvedId = drawableIds.get(id); if (resolvedId == null) { diff --git a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/SampleUtils.java b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/SampleUtils.java index 7ad1917244..acda86e651 100644 --- a/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/SampleUtils.java +++ b/OsmAndCore-sample/src/net/osmand/core/samples/android/sample1/SampleUtils.java @@ -10,6 +10,8 @@ import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.util.DisplayMetrics; import android.util.Log; import android.view.Surface; @@ -189,7 +191,8 @@ public class SampleUtils { return files; } - public static byte[] getDrawableAsByteArray(Drawable drawable) { + @Nullable + public static byte[] getDrawableAsByteArray(@NonNull Drawable drawable) { if (drawable instanceof BitmapDrawable) { Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap(); return getBitmapAsByteArray(bitmap); @@ -197,7 +200,8 @@ public class SampleUtils { return null; } - public static byte[] getBitmapAsByteArray(Bitmap bitmap) { + @NonNull + public static byte[] getBitmapAsByteArray(@NonNull Bitmap bitmap) { int size = bitmap.getRowBytes() * bitmap.getHeight(); ByteBuffer byteBuffer = ByteBuffer.allocate(size); bitmap.copyPixelsToBuffer(byteBuffer);