Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[android] check external database's read/write permissions asynchrono…
Browse files Browse the repository at this point in the history
…usly
  • Loading branch information
LukasPaczos committed Sep 26, 2018
1 parent 5e747ea commit 22c2c88
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
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;
Expand Down Expand Up @@ -235,20 +236,32 @@ public void run() {
*/
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> {
Expand Down
Original file line number Diff line number Diff line change
@@ -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();
}
}

0 comments on commit 22c2c88

Please sign in to comment.