package org.mozilla.osmdroid;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.DisplayMetrics;
import org.mozilla.mozstumbler.service.core.logging.ClientLog;
import org.mozilla.mozstumbler.svclocator.services.log.LoggerUtil;
import org.mozilla.osmdroid.views.util.constants.MapViewConstants;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
/**
* Default implementation of {@link org.mozilla.osmdroid.ResourceProxy} that returns fixed string to get
* string resources and reads the jar package to get bitmap resources.
*/
public class DefaultResourceProxyImpl implements ResourceProxy, MapViewConstants {
private static final String LOG_TAG = LoggerUtil.makeLogTag(DefaultResourceProxyImpl.class);
private Resources mResources;
private DisplayMetrics mDisplayMetrics;
/**
* Constructor.
*
* @param pContext Used to get the display metrics that are used for scaling the bitmaps returned by
* {@link #getBitmap} and {@link #getDrawable}.
* Can be null, in which case the bitmaps are not scaled.
*/
public DefaultResourceProxyImpl(final Context pContext) {
if (pContext != null) {
mResources = pContext.getResources();
mDisplayMetrics = mResources.getDisplayMetrics();
if (DEBUGMODE) {
ClientLog.d(LOG_TAG, "mDisplayMetrics=" + mDisplayMetrics);
}
}
}
@Override
public String getString(final string pResId) {
switch (pResId) {
case mapnik:
return "Mapnik";
case cyclemap:
return "Cycle Map";
case public_transport:
return "Public transport";
case cloudmade_standard:
return "CloudMade (Standard tiles)";
case cloudmade_small:
return "CloudMade (small tiles)";
case mapquest_osm:
return "Mapquest";
case mapquest_aerial:
return "Mapquest Aerial";
case bing:
return "Bing";
case mapbox:
return "MapBox";
case fiets_nl:
return "OpenFietsKaart overlay";
case base_nl:
return "Netherlands base overlay";
case roads_nl:
return "Netherlands roads overlay";
case unknown:
return "Unknown";
case format_distance_meters:
return "%s m";
case format_distance_kilometers:
return "%s km";
case format_distance_miles:
return "%s mi";
case format_distance_nautical_miles:
return "%s nm";
case format_distance_feet:
return "%s ft";
case online_mode:
return "Online mode";
case offline_mode:
return "Offline mode";
case my_location:
return "My location";
case compass:
return "Compass";
case map_mode:
return "Map mode";
default:
throw new IllegalArgumentException();
}
}
@Override
public String getString(final string pResId, final Object... formatArgs) {
return String.format(getString(pResId), formatArgs);
}
@Override
public Bitmap getBitmap(final bitmap pResId) {
InputStream is = null;
try {
final String resName = pResId.name() + ".png";
is = ResourceProxy.class.getResourceAsStream(resName);
if (is == null) {
throw new IllegalArgumentException("Resource not found: " + resName);
}
BitmapFactory.Options options = null;
if (mDisplayMetrics != null) {
options = getBitmapOptions();
}
return BitmapFactory.decodeStream(is, null, options);
} catch (final OutOfMemoryError e) {
ClientLog.e(LOG_TAG, "OutOfMemoryError getting bitmap resource: " + pResId, e);
System.gc();
// there's not much we can do here
// - when we load a bitmap from resources we expect it to be found
throw e;
} finally {
if (is != null) {
try {
is.close();
} catch (final IOException ignore) {
}
}
}
}
private BitmapFactory.Options getBitmapOptions() {
try {
// TODO I think this can all be done without reflection now because all these properties are SDK 4
final Field density = DisplayMetrics.class.getDeclaredField("DENSITY_DEFAULT");
final Field inDensity = BitmapFactory.Options.class.getDeclaredField("inDensity");
final Field inTargetDensity = BitmapFactory.Options.class
.getDeclaredField("inTargetDensity");
final Field targetDensity = DisplayMetrics.class.getDeclaredField("densityDpi");
final BitmapFactory.Options options = new BitmapFactory.Options();
inDensity.setInt(options, density.getInt(null));
inTargetDensity.setInt(options, targetDensity.getInt(mDisplayMetrics));
return options;
} catch (final IllegalAccessException ex) {
// ignore
} catch (final NoSuchFieldException ex) {
// ignore
}
return null;
}
@Override
public Drawable getDrawable(final bitmap pResId) {
return mResources != null
? new BitmapDrawable(mResources, getBitmap(pResId))
: new BitmapDrawable(getBitmap(pResId));
}
@Override
public float getDisplayMetricsDensity() {
return mDisplayMetrics.density;
}
}