[android] check external database's read/write permissions asynchronously

This commit is contained in:
Łukasz Paczos
2018-09-24 16:04:07 +02:00
committed by Łukasz Paczos
parent 5e747eafa7
commit 22c2c88974
2 changed files with 147 additions and 13 deletions

View File

@@ -15,6 +15,7 @@ import com.mapbox.mapboxsdk.geometry.LatLngBounds;
import com.mapbox.mapboxsdk.log.Logger;
import com.mapbox.mapboxsdk.net.ConnectivityReceiver;
import com.mapbox.mapboxsdk.storage.FileSource;
import com.mapbox.mapboxsdk.utils.FileUtils;
import java.io.File;
import java.io.FileInputStream;
@@ -235,20 +236,32 @@ public class OfflineManager {
*/
public void mergeOfflineRegions(@NonNull String path, @NonNull final MergeOfflineRegionsCallback callback) {
File src = new File(path);
if (!src.canRead()) {
// path not readable, abort
callback.onError("Secondary database needs to be located in a readable path.");
return;
}
new FileUtils.CheckFileReadPermissionTask(new FileUtils.OnCheckFileReadPermissionListener() {
@Override
public void onReadPermissionGranted() {
new FileUtils.CheckFileWritePermissionTask(new FileUtils.OnCheckFileWritePermissionListener() {
@Override
public void onWritePermissionGranted() {
// path writable, merge and update schema in place if necessary
mergeOfflineDatabaseFiles(src, callback, false);
}
if (src.canWrite()) {
// path writable, merge and update schema in place if necessary
mergeOfflineDatabaseFiles(src, callback, false);
} else {
// path not writable, copy the the file to temp directory, then merge and update schema on a copy if necessary
File dst = new File(FileSource.getInternalCachePath(context), src.getName());
new CopyTempDatabaseFileTask(this, callback).execute(src, dst);
}
@Override
public void onError() {
// path not writable, copy the the file to temp directory, then merge and update schema on a copy if
// necessary
File dst = new File(FileSource.getInternalCachePath(context), src.getName());
new CopyTempDatabaseFileTask(OfflineManager.this, callback).execute(src, dst);
}
}).execute(src);
}
@Override
public void onError() {
// path not readable, abort
callback.onError("Secondary database needs to be located in a readable path.");
}
}).execute(src);
}
private static final class CopyTempDatabaseFileTask extends AsyncTask<Object, Void, Object> {

View File

@@ -0,0 +1,121 @@
package com.mapbox.mapboxsdk.utils;
import android.os.AsyncTask;
import java.io.File;
import java.lang.ref.WeakReference;
public class FileUtils {
/**
* Task checking whether app's process can read a file.
*/
public static class CheckFileReadPermissionTask extends AsyncTask<File, Void, Boolean> {
private final WeakReference<OnCheckFileReadPermissionListener> listenerWeakReference;
public CheckFileReadPermissionTask(OnCheckFileReadPermissionListener listener) {
this.listenerWeakReference = new WeakReference<>(listener);
}
@Override
protected Boolean doInBackground(File... files) {
try {
return files[0].canRead();
} catch (Exception ex) {
return false;
}
}
@Override
protected void onCancelled() {
OnCheckFileReadPermissionListener listener = listenerWeakReference.get();
if (listener != null) {
listener.onError();
}
}
@Override
protected void onPostExecute(Boolean result) {
OnCheckFileReadPermissionListener listener = listenerWeakReference.get();
if (listener != null) {
if (result) {
listener.onReadPermissionGranted();
} else {
listener.onError();
}
}
}
}
/**
* Interface definition for a callback invoked when checking file's read permissions.
*/
public interface OnCheckFileReadPermissionListener {
/**
* Invoked when app's process has a permission to read a file.
*/
void onReadPermissionGranted();
/**
* Invoked when app's process doesn't have a permission to read a file or an error occurs.
*/
void onError();
}
/**
* Task checking whether app's process can write to a file.
*/
public static class CheckFileWritePermissionTask extends AsyncTask<File, Void, Boolean> {
private final WeakReference<OnCheckFileWritePermissionListener> listenerWeakReference;
public CheckFileWritePermissionTask(OnCheckFileWritePermissionListener listener) {
this.listenerWeakReference = new WeakReference<>(listener);
}
@Override
protected Boolean doInBackground(File... files) {
try {
return files[0].canWrite();
} catch (Exception ex) {
return false;
}
}
@Override
protected void onCancelled() {
OnCheckFileWritePermissionListener listener = listenerWeakReference.get();
if (listener != null) {
listener.onError();
}
}
@Override
protected void onPostExecute(Boolean result) {
OnCheckFileWritePermissionListener listener = listenerWeakReference.get();
if (listener != null) {
if (result) {
listener.onWritePermissionGranted();
} else {
listener.onError();
}
}
}
}
/**
* Interface definition for a callback invoked when checking file's write permissions.
*/
public interface OnCheckFileWritePermissionListener {
/**
* Invoked when app's process has a permission to write to a file.
*/
void onWritePermissionGranted();
/**
* Invoked when app's process doesn't have a permission to write to a file or an error occurs.
*/
void onError();
}
}