[android] Introduce a getDatabasePath() method that enables switching storage paths
Fixes #5589
This commit is contained in:
@@ -30,6 +30,16 @@ public class MapboxConstants {
|
||||
*/
|
||||
public static final String KEY_META_DATA_STAGING_ACCESS_TOKEN = "com.mapbox.TestEventsAccessToken";
|
||||
|
||||
/**
|
||||
* Key used to switch storage to external in AndroidManifest.xml
|
||||
*/
|
||||
public final static String KEY_META_DATA_SET_STORAGE_EXTERNAL = "com.mapbox.SetStorageExternal";
|
||||
|
||||
/**
|
||||
* Default value for KEY_META_DATA_SET_STORAGE_EXTERNAL (default is internal storage)
|
||||
*/
|
||||
public final static boolean DEFAULT_SET_STORAGE_EXTERNAL = false;
|
||||
|
||||
/**
|
||||
* Default animation time
|
||||
*/
|
||||
|
||||
@@ -15,6 +15,7 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
|
||||
import com.mapbox.mapboxsdk.geometry.ProjectedMeters;
|
||||
import com.mapbox.mapboxsdk.layers.CustomLayer;
|
||||
import com.mapbox.mapboxsdk.offline.OfflineManager;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -51,7 +52,7 @@ final class NativeMapView {
|
||||
|
||||
public NativeMapView(MapView mapView) {
|
||||
Context context = mapView.getContext();
|
||||
String dataPath = context.getFilesDir().getAbsolutePath();
|
||||
String dataPath = OfflineManager.getDatabasePath(context);
|
||||
|
||||
// With the availability of offline, we're unifying the ambient (cache) and the offline
|
||||
// databases to be in the same folder, outside cache, to avoid automatic deletion from
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
package com.mapbox.mapboxsdk.offline;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
|
||||
import com.mapbox.mapboxsdk.MapboxAccountManager;
|
||||
import com.mapbox.mapboxsdk.constants.MapboxConstants;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
@@ -88,7 +94,7 @@ public class OfflineManager {
|
||||
|
||||
private OfflineManager(Context context) {
|
||||
// Get a pointer to the DefaultFileSource instance
|
||||
String assetRoot = context.getFilesDir().getAbsolutePath();
|
||||
String assetRoot = getDatabasePath(context);
|
||||
String cachePath = assetRoot + File.separator + DATABASE_NAME;
|
||||
mDefaultFileSourcePtr = createDefaultFileSource(cachePath, assetRoot, DEFAULT_MAX_CACHE_SIZE);
|
||||
|
||||
@@ -100,6 +106,61 @@ public class OfflineManager {
|
||||
deleteAmbientDatabase(context);
|
||||
}
|
||||
|
||||
public static String getDatabasePath(Context context) {
|
||||
// Default value
|
||||
boolean setStorageExternal = MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL;
|
||||
|
||||
try {
|
||||
// Try getting a custom value from the app Manifest
|
||||
ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(
|
||||
context.getPackageName(), PackageManager.GET_META_DATA);
|
||||
setStorageExternal = appInfo.metaData.getBoolean(
|
||||
MapboxConstants.KEY_META_DATA_SET_STORAGE_EXTERNAL,
|
||||
MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.e(LOG_TAG, "Failed to read the package metadata: " + e.getMessage());
|
||||
} catch (Exception e) {
|
||||
Log.e(LOG_TAG, "Failed to read the storage key: " + e.getMessage());
|
||||
}
|
||||
|
||||
String databasePath = null;
|
||||
if (setStorageExternal && isExternalStorageReadable()) {
|
||||
try {
|
||||
// Try getting the external storage path
|
||||
databasePath = context.getExternalFilesDir(null).getAbsolutePath();
|
||||
} catch (NullPointerException e) {
|
||||
Log.e(LOG_TAG, "Failed to obtain the external storage path: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (databasePath == null) {
|
||||
// Default to internal storage
|
||||
databasePath = context.getFilesDir().getAbsolutePath();
|
||||
}
|
||||
|
||||
return databasePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if external storage is available to at least read. In order for this to work, make
|
||||
* sure you include <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
* (or WRITE_EXTERNAL_STORAGE) for API level < 18 in your app Manifest.
|
||||
*
|
||||
* Code from https://developer.android.com/guide/topics/data/data-storage.html#filesExternal
|
||||
*/
|
||||
public static boolean isExternalStorageReadable() {
|
||||
String state = Environment.getExternalStorageState();
|
||||
if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Log.w(LOG_TAG, "External storage was requested but it isn't readable. For API level < 18"
|
||||
+ " make sure you've requested READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE"
|
||||
+ " permissions in your app Manifest (defaulting to internal storage).");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void deleteAmbientDatabase(final Context context) {
|
||||
// Delete the file in a separate thread to avoid affecting the UI
|
||||
new Thread(new Runnable() {
|
||||
|
||||
Reference in New Issue
Block a user