diff options
author | Antonio Zugaldia <antonio@mapbox.com> | 2016-07-15 09:58:31 -0400 |
---|---|---|
committer | Antonio Zugaldia <antonio@mapbox.com> | 2016-07-15 09:58:53 -0400 |
commit | 5c037f4745e5a9a3c5f5d050c59d39e3f763bb5a (patch) | |
tree | 77203751dc00c197935a09a54a48057cc6df8339 /platform/android/MapboxGLAndroidSDK/src/main/java/com | |
parent | 244700e56033179726a164b1a0801dbd4c382770 (diff) | |
download | qtlocation-mapboxgl-5c037f4745e5a9a3c5f5d050c59d39e3f763bb5a.tar.gz |
[android] Introduce a getDatabasePath() method that enables switching storage paths
Fixes #5589
Diffstat (limited to 'platform/android/MapboxGLAndroidSDK/src/main/java/com')
3 files changed, 74 insertions, 2 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java index ece992ad54..7936ab4d14 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java @@ -31,6 +31,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 */ public static final int ANIMATION_DURATION = 300; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java index 5a1cfa7a6f..e908912846 100755 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java @@ -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 diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java index e81c366dba..ba6434e06d 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java @@ -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() { |