first = pair.first;
@@ -558,4 +606,21 @@ public final class DownloadUtils {
WorkManager.getInstance(context)
.enqueue(downloadWorkRequest);
}
+
+
+ public static class ReselectDocumentTreeException extends Exception {
+ private final Uri initialUri;
+
+ public ReselectDocumentTreeException() {
+ initialUri = null;
+ }
+
+ public ReselectDocumentTreeException(final Uri initialUri) {
+ this.initialUri = initialUri;
+ }
+
+ public Uri getInitialUri() {
+ return initialUri;
+ }
+ }
}
diff --git a/app/src/main/java/awais/instagrabber/utils/Utils.java b/app/src/main/java/awais/instagrabber/utils/Utils.java
index b7c8e429..e9832715 100644
--- a/app/src/main/java/awais/instagrabber/utils/Utils.java
+++ b/app/src/main/java/awais/instagrabber/utils/Utils.java
@@ -36,6 +36,7 @@ import android.widget.Toast;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
@@ -70,6 +71,8 @@ import awais.instagrabber.models.PostsLayoutPreferences;
import awais.instagrabber.models.Tab;
import awais.instagrabber.models.enums.FavoriteType;
+import static awais.instagrabber.utils.Constants.FOLDER_PATH;
+
public final class Utils {
private static final String TAG = "Utils";
private static final int VIDEO_CACHE_MAX_BYTES = 10 * 1024 * 1024;
@@ -520,7 +523,8 @@ public final class Utils {
callback);
}
- private static File getDocumentFileRealPath(Context context, DocumentFile documentFile)
+ public static File getDocumentFileRealPath(@NonNull final Context context,
+ @NonNull final DocumentFile documentFile)
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
final String docId = DocumentsContract.getDocumentId(documentFile.getUri());
final String[] split = docId.split(":");
@@ -530,18 +534,19 @@ public final class Utils {
return new File(Environment.getExternalStorageDirectory(), split[1]);
} else {
if (volumes == null) {
- StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
- Method getVolumeListMethod = sm.getClass().getMethod("getVolumeList");
+ final StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
+ if (sm == null) return null;
+ final Method getVolumeListMethod = sm.getClass().getMethod("getVolumeList");
volumes = (Object[]) getVolumeListMethod.invoke(sm);
}
-
+ if (volumes == null) return null;
for (Object volume : volumes) {
- Method getUuidMethod = volume.getClass().getMethod("getUuid");
- String uuid = (String) getUuidMethod.invoke(volume);
+ final Method getUuidMethod = volume.getClass().getMethod("getUuid");
+ final String uuid = (String) getUuidMethod.invoke(volume);
if (uuid != null && uuid.equalsIgnoreCase(type)) {
- Method getPathMethod = volume.getClass().getMethod("getPath");
- String path = (String) getPathMethod.invoke(volume);
+ final Method getPathMethod = volume.getClass().getMethod("getPath");
+ final String path = (String) getPathMethod.invoke(volume);
return new File(path, split[1]);
}
}
@@ -549,4 +554,72 @@ public final class Utils {
return null;
}
+
+ public static void setupSelectedDir(@NonNull final Context context,
+ @NonNull final Intent intent) throws DownloadUtils.ReselectDocumentTreeException {
+ final Uri dirUri = intent.getData();
+ Log.d(TAG, "onActivityResult: " + dirUri);
+ if (dirUri == null) return;
+ final int takeFlags = intent.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ context.getContentResolver().takePersistableUriPermission(dirUri, takeFlags);
+ settingsHelper.putString(FOLDER_PATH, dirUri.toString());
+ // re-init DownloadUtils
+ DownloadUtils.init(context);
+ }
+
+ /**
+ * Ing.N.Nyerges 2019 V2.0
+ *
+ * Storage Access Framework(SAF) Uri's creator from File (java.IO),
+ * for removable external storages
+ *
+ * @param context Application Context
+ * @param file File path + file name
+ * @return Uri[]:
+ * uri[0] = SAF TREE Uri
+ * uri[1] = SAF DOCUMENT Uri
+ */
+ @RequiresApi(api = Build.VERSION_CODES.KITKAT)
+ public static Uri[] getSafUris(Context context, File file) {
+
+ Uri[] uri = new Uri[2];
+ String scheme = "content";
+ String authority = "com.android.externalstorage.documents";
+
+ // Separate each element of the File path
+ // File format: "/storage/XXXX-XXXX/sub-folder1/sub-folder2..../filename"
+ // (XXXX-XXXX is external removable number
+ String[] ele = file.getPath().split(File.separator);
+ // ele[0] = not used (empty)
+ // ele[1] = not used (storage name)
+ // ele[2] = storage number
+ // ele[3 to (n-1)] = folders
+ // ele[n] = file name
+
+ // Construct folders strings using SAF format
+ StringBuilder folders = new StringBuilder();
+ if (ele.length > 4) {
+ folders.append(ele[3]);
+ for (int i = 4; i < ele.length - 1; ++i) folders.append("%2F").append(ele[i]);
+ }
+
+ String common = ele[2] + "%3A" + folders.toString();
+
+ // Construct TREE Uri
+ Uri.Builder builder = new Uri.Builder();
+ builder.scheme(scheme);
+ builder.authority(authority);
+ builder.encodedPath("/tree/" + common);
+ uri[0] = builder.build();
+
+ // Construct DOCUMENT Uri
+ builder = new Uri.Builder();
+ builder.scheme(scheme);
+ builder.authority(authority);
+ if (ele.length > 4) common = common + "%2F";
+ builder.encodedPath("/document/" + common + file.getName());
+ uri[1] = builder.build();
+
+ return uri;
+ }
}
diff --git a/app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.java b/app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.java
index 440d4765..fd23f755 100644
--- a/app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.java
+++ b/app/src/main/java/awais/instagrabber/viewmodels/DirectThreadViewModel.java
@@ -72,7 +72,7 @@ public class DirectThreadViewModel extends AndroidViewModel {
throw new IllegalArgumentException("User is not logged in!");
}
contentResolver = application.getContentResolver();
- recordingsDir = DownloadUtils.getDownloadDir("Recordings");
+ recordingsDir = DownloadUtils.getRecordingsDir();
final DirectMessagesManager messagesManager = DirectMessagesManager.getInstance();
threadManager = messagesManager.getThreadManager(threadId, pending, currentUser, contentResolver);
threadManager.fetchPendingRequests();
diff --git a/app/src/main/res/layout/activity_directory_select.xml b/app/src/main/res/layout/activity_directory_select.xml
new file mode 100644
index 00000000..01f81a9f
--- /dev/null
+++ b/app/src/main/res/layout/activity_directory_select.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file