646 lines
28 KiB
Java
646 lines
28 KiB
Java
package awais.instagrabber.utils;
|
|
|
|
import android.content.ContentResolver;
|
|
import android.content.Context;
|
|
import android.content.DialogInterface;
|
|
import android.content.UriPermission;
|
|
import android.Manifest;
|
|
import android.net.Uri;
|
|
import android.util.Log;
|
|
import android.webkit.MimeTypeMap;
|
|
import android.widget.Toast;
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.annotation.Nullable;
|
|
import androidx.appcompat.app.AlertDialog;
|
|
import androidx.core.util.Pair;
|
|
import androidx.documentfile.provider.DocumentFile;
|
|
import androidx.work.Constraints;
|
|
import androidx.work.Data;
|
|
import androidx.work.NetworkType;
|
|
import androidx.work.OneTimeWorkRequest;
|
|
import androidx.work.WorkManager;
|
|
import androidx.work.WorkRequest;
|
|
|
|
import com.google.gson.Gson;
|
|
|
|
import java.io.BufferedWriter;
|
|
import java.io.IOException;
|
|
import java.io.OutputStreamWriter;
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.HashMap;
|
|
import java.util.LinkedList;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.UUID;
|
|
import java.util.regex.Pattern;
|
|
|
|
import awais.instagrabber.R;
|
|
import awais.instagrabber.fragments.settings.PreferenceKeys;
|
|
import awais.instagrabber.models.StoryModel;
|
|
import awais.instagrabber.models.enums.MediaItemType;
|
|
import awais.instagrabber.repositories.responses.Audio;
|
|
import awais.instagrabber.repositories.responses.Media;
|
|
import awais.instagrabber.repositories.responses.User;
|
|
import awais.instagrabber.repositories.responses.MediaCandidate;
|
|
import awais.instagrabber.workers.DownloadWorker;
|
|
|
|
import static awais.instagrabber.fragments.settings.PreferenceKeys.PREF_BARINSTA_DIR_URI;
|
|
|
|
public final class DownloadUtils {
|
|
private static final String TAG = DownloadUtils.class.getSimpleName();
|
|
// private static final String DIR_BARINSTA = "Barinsta";
|
|
private static final String DIR_DOWNLOADS = "Downloads";
|
|
private static final String DIR_CAMERA = "Camera";
|
|
private static final String DIR_EDIT = "Edit";
|
|
private static final String DIR_RECORDINGS = "Sent Recordings";
|
|
private static final String DIR_TEMP = "Temp";
|
|
private static final String DIR_BACKUPS = "Backups";
|
|
|
|
private static DocumentFile root;
|
|
|
|
public static final String WRITE_PERMISSION = Manifest.permission.WRITE_EXTERNAL_STORAGE;
|
|
public static final String[] PERMS = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};
|
|
|
|
public static void init(@NonNull final Context context,
|
|
@Nullable final String barinstaDirUri) throws ReselectDocumentTreeException {
|
|
if (TextUtils.isEmpty(barinstaDirUri)) {
|
|
throw new ReselectDocumentTreeException("folder path is null or empty");
|
|
}
|
|
if (!barinstaDirUri.startsWith("content://com.android.externalstorage.documents")) {
|
|
// reselect the folder in selector view
|
|
throw new ReselectDocumentTreeException(Uri.parse(barinstaDirUri));
|
|
}
|
|
final Uri uri = Uri.parse(barinstaDirUri);
|
|
final List<UriPermission> existingPermissions = context.getContentResolver().getPersistedUriPermissions();
|
|
if (existingPermissions.isEmpty()) {
|
|
// reselect the folder in selector view
|
|
throw new ReselectDocumentTreeException(uri);
|
|
}
|
|
final boolean anyMatch = existingPermissions.stream().anyMatch(uriPermission -> uriPermission.getUri().equals(uri));
|
|
if (!anyMatch) {
|
|
// reselect the folder in selector view
|
|
throw new ReselectDocumentTreeException(uri);
|
|
}
|
|
root = DocumentFile.fromTreeUri(context, uri);
|
|
if (root == null || !root.exists() || root.lastModified() == 0) {
|
|
root = null;
|
|
throw new ReselectDocumentTreeException(uri);
|
|
}
|
|
Utils.settingsHelper.putString(PREF_BARINSTA_DIR_URI, uri.toString());
|
|
}
|
|
|
|
public static void destroy() {
|
|
root = null;
|
|
}
|
|
|
|
@Nullable
|
|
public static DocumentFile getDownloadDir(final String... dirs) {
|
|
if (root == null) {
|
|
return null;
|
|
}
|
|
DocumentFile subDir = root;
|
|
if (dirs != null) {
|
|
for (final String dir : dirs) {
|
|
if (subDir == null || TextUtils.isEmpty(dir)) continue;
|
|
final DocumentFile subDirFile = subDir.findFile(dir);
|
|
final boolean exists = subDirFile != null && subDirFile.exists();
|
|
subDir = exists ? subDirFile : subDir.createDirectory(dir);
|
|
}
|
|
}
|
|
return subDir;
|
|
}
|
|
|
|
@Nullable
|
|
public static DocumentFile getDownloadDir() {
|
|
// final File parent = new File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_DOWNLOADS);
|
|
// final File dir = new File(new File(parent, "barinsta"), "downloads");
|
|
// if (!dir.exists()) {
|
|
// final boolean mkdirs = dir.mkdirs();
|
|
// if (!mkdirs) {
|
|
// Log.e(TAG, "getDownloadDir: failed to create dir");
|
|
// }
|
|
// }
|
|
// if (Utils.settingsHelper.getBoolean(FOLDER_SAVE_TO)) {
|
|
// final String customPath = Utils.settingsHelper.getString(FOLDER_PATH);
|
|
// if (!TextUtils.isEmpty(customPath)) {
|
|
// dir = new File(customPath);
|
|
// }
|
|
// }
|
|
return getDownloadDir(DIR_DOWNLOADS);
|
|
}
|
|
|
|
@Nullable
|
|
public static DocumentFile getCameraDir() {
|
|
return getDownloadDir(DIR_CAMERA);
|
|
}
|
|
|
|
@Nullable
|
|
public static DocumentFile getImageEditDir(final String sessionId) {
|
|
return getDownloadDir(DIR_EDIT, sessionId);
|
|
}
|
|
|
|
@Nullable
|
|
public static DocumentFile getRecordingsDir() {
|
|
return getDownloadDir(DIR_RECORDINGS);
|
|
}
|
|
|
|
@Nullable
|
|
public static DocumentFile getBackupsDir() {
|
|
return getDownloadDir(DIR_BACKUPS);
|
|
}
|
|
|
|
// @Nullable
|
|
// private static DocumentFile getDownloadDir(@NonNull final Context context, @Nullable final String username) {
|
|
// return getDownloadDir(context, username, false);
|
|
// }
|
|
|
|
@Nullable
|
|
private static DocumentFile getDownloadDir(final Context context,
|
|
@Nullable final String username) {
|
|
final List<String> userFolderPaths = getSubPathForUserFolder(username);
|
|
DocumentFile dir = root;
|
|
for (final String dirName : userFolderPaths) {
|
|
final DocumentFile file = dir.findFile(dirName);
|
|
if (file != null) {
|
|
dir = file;
|
|
continue;
|
|
}
|
|
dir = dir.createDirectory(dirName);
|
|
if (dir == null) break;
|
|
}
|
|
// final String joined = android.text.TextUtils.join("/", userFolderPaths);
|
|
// final Uri userFolderUri = DocumentsContract.buildDocumentUriUsingTree(root.getUri(), joined);
|
|
// final DocumentFile userFolder = DocumentFile.fromSingleUri(context, userFolderUri);
|
|
if (context != null && (dir == null || !dir.exists())) {
|
|
Toast.makeText(context, R.string.error_creating_folders, Toast.LENGTH_SHORT).show();
|
|
return null;
|
|
}
|
|
return dir;
|
|
}
|
|
|
|
private static List<String> getSubPathForUserFolder(final String username) {
|
|
final List<String> list = new ArrayList<>();
|
|
if (!Utils.settingsHelper.getBoolean(PreferenceKeys.DOWNLOAD_USER_FOLDER) || TextUtils.isEmpty(username)) {
|
|
list.add(DIR_DOWNLOADS);
|
|
return list;
|
|
}
|
|
final String finalUsername = username.startsWith("@") ? username.substring(1) : username;
|
|
list.add(DIR_DOWNLOADS);
|
|
list.add(finalUsername);
|
|
return list;
|
|
}
|
|
|
|
private static DocumentFile getTempDir() {
|
|
DocumentFile file = root.findFile(DIR_TEMP);
|
|
if (file == null) {
|
|
file = root.createDirectory(DIR_TEMP);
|
|
}
|
|
return file;
|
|
}
|
|
|
|
// public static void dmDownload(@NonNull final Context context,
|
|
// @Nullable final String username,
|
|
// final String modelId,
|
|
// final String url) {
|
|
// if (url == null) return;
|
|
// if (ContextCompat.checkSelfPermission(context, PERMS[0]) == PackageManager.PERMISSION_GRANTED) {
|
|
// dmDownloadImpl(context, username, modelId, url);
|
|
// } else if (context instanceof Activity) {
|
|
// ActivityCompat.requestPermissions((Activity) context, PERMS, 8020);
|
|
// }
|
|
// }
|
|
|
|
// private static void dmDownloadImpl(@NonNull final Context context,
|
|
// @Nullable final String username,
|
|
// final String modelId,
|
|
// final String url) {
|
|
// final DocumentFile dir = getDownloadDir(context, username);
|
|
// if (dir != null && dir.exists()) {
|
|
// download(context, url, getDownloadSavePaths(dir, modelId, url));
|
|
// return;
|
|
// }
|
|
// Toast.makeText(context, R.string.error_creating_folders, Toast.LENGTH_SHORT).show();
|
|
// }
|
|
|
|
private static Pair<List<String>, String> getDownloadSavePaths(final List<String> paths,
|
|
final String postId,
|
|
final String displayUrl) {
|
|
return getDownloadSavePaths(paths, postId, "", displayUrl, "");
|
|
}
|
|
|
|
private static Pair<List<String>, String> getDownloadSavePaths(final List<String> paths,
|
|
final String postId,
|
|
final String displayUrl,
|
|
final String username) {
|
|
return getDownloadSavePaths(paths, postId, "", displayUrl, username);
|
|
}
|
|
|
|
private static Pair<List<String>, String> getDownloadChildSavePaths(final List<String> paths,
|
|
final String postId,
|
|
final int childPosition,
|
|
final String url,
|
|
final String username) {
|
|
final String sliderPostfix = "_slide_" + childPosition;
|
|
return getDownloadSavePaths(paths, postId, sliderPostfix, url, username);
|
|
}
|
|
|
|
private static Pair<List<String>, String> getDownloadSavePaths(final List<String> paths,
|
|
final String postId,
|
|
final String sliderPostfix,
|
|
final String displayUrl,
|
|
final String username) {
|
|
if (paths == null) return null;
|
|
final String extension = getFileExtensionFromUrl(displayUrl);
|
|
final String usernamePrepend = TextUtils.isEmpty(username) ? "" : (username + "_");
|
|
final String fileName = usernamePrepend + postId + sliderPostfix + extension;
|
|
// return new File(finalDir, fileName);
|
|
// DocumentFile file = finalDir.findFile(fileName);
|
|
// if (file == null) {
|
|
final String mimeType = Utils.mimeTypeMap.getMimeTypeFromExtension(extension.startsWith(".") ? extension.substring(1) : extension);
|
|
// file = finalDir.createFile(mimeType, fileName);
|
|
// }
|
|
paths.add(fileName);
|
|
return new Pair<>(paths, mimeType);
|
|
}
|
|
|
|
// public static DocumentFile getTempFile() {
|
|
// return getTempFile(null, null);
|
|
// }
|
|
|
|
public static DocumentFile getTempFile(final String fileName, final String extension) {
|
|
final DocumentFile dir = getTempDir();
|
|
String name = fileName;
|
|
if (TextUtils.isEmpty(name)) {
|
|
name = UUID.randomUUID().toString();
|
|
}
|
|
String mimeType = "application/octet-stream";
|
|
if (!TextUtils.isEmpty(extension)) {
|
|
name += "." + extension;
|
|
final String mimeType1 = Utils.mimeTypeMap.getMimeTypeFromExtension(extension);
|
|
if (mimeType1 != null) {
|
|
mimeType = mimeType1;
|
|
}
|
|
}
|
|
DocumentFile file = dir.findFile(name);
|
|
if (file == null) {
|
|
file = dir.createFile(mimeType, name);
|
|
}
|
|
return file;
|
|
}
|
|
|
|
/**
|
|
* Copied from {@link MimeTypeMap#getFileExtensionFromUrl(String)})
|
|
* <p>
|
|
* Returns the file extension or an empty string if there is no
|
|
* extension. This method is a convenience method for obtaining the
|
|
* extension of a url and has undefined results for other Strings.
|
|
*
|
|
* @param url URL
|
|
* @return The file extension of the given url.
|
|
*/
|
|
public static String getFileExtensionFromUrl(String url) {
|
|
if (!TextUtils.isEmpty(url)) {
|
|
int fragment = url.lastIndexOf('#');
|
|
if (fragment > 0) {
|
|
url = url.substring(0, fragment);
|
|
}
|
|
|
|
int query = url.lastIndexOf('?');
|
|
if (query > 0) {
|
|
url = url.substring(0, query);
|
|
}
|
|
|
|
int filenamePos = url.lastIndexOf('/');
|
|
String filename =
|
|
0 <= filenamePos ? url.substring(filenamePos + 1) : url;
|
|
|
|
// if the filename contains special characters, we don't
|
|
// consider it valid for our matching purposes:
|
|
if (!filename.isEmpty() &&
|
|
Pattern.matches("[a-zA-Z_0-9.\\-()%]+", filename)) {
|
|
int dotPos = filename.lastIndexOf('.');
|
|
if (0 <= dotPos) {
|
|
return filename.substring(dotPos);
|
|
}
|
|
}
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
public static List<Boolean> checkDownloaded(@NonNull final Media media) {
|
|
final List<Boolean> checkList = new LinkedList<>();
|
|
final User user = media.getUser();
|
|
String username = "username";
|
|
if (user != null) {
|
|
username = user.getUsername();
|
|
}
|
|
final List<String> userFolderPaths = getSubPathForUserFolder(username);
|
|
switch (media.getMediaType()) {
|
|
case MEDIA_TYPE_IMAGE:
|
|
case MEDIA_TYPE_VIDEO: {
|
|
final String url = media.getMediaType() == MediaItemType.MEDIA_TYPE_VIDEO
|
|
? ResponseBodyUtils.getVideoUrl(media) : ResponseBodyUtils.getImageUrl(media);
|
|
final Pair<List<String>, String> file = getDownloadSavePaths(new ArrayList<>(userFolderPaths), media.getCode(), url, "");
|
|
final boolean fileExists = file.first != null && checkPathExists(file.first);
|
|
boolean usernameFileExists = false;
|
|
if (!fileExists) {
|
|
final Pair<List<String>, String> usernameFile = getDownloadSavePaths(
|
|
new ArrayList<>(userFolderPaths), media.getCode(), url, username);
|
|
usernameFileExists = usernameFile.first != null && checkPathExists(usernameFile.first);
|
|
}
|
|
checkList.add(fileExists || usernameFileExists);
|
|
break;
|
|
}
|
|
case MEDIA_TYPE_SLIDER:
|
|
final List<Media> sliderItems = media.getCarouselMedia();
|
|
for (int i = 0; i < sliderItems.size(); i++) {
|
|
final Media child = sliderItems.get(i);
|
|
if (child == null) continue;
|
|
final String url = child.getMediaType() == MediaItemType.MEDIA_TYPE_VIDEO
|
|
? ResponseBodyUtils.getVideoUrl(child) : ResponseBodyUtils.getImageUrl(child);
|
|
final Pair<List<String>, String> file = getDownloadChildSavePaths(
|
|
new ArrayList<>(userFolderPaths), media.getCode(), i + 1, url, "");
|
|
final boolean fileExists = file.first != null && checkPathExists(file.first);
|
|
boolean usernameFileExists = false;
|
|
if (!fileExists) {
|
|
final Pair<List<String>, String> usernameFile = getDownloadChildSavePaths(
|
|
new ArrayList<>(userFolderPaths), media.getCode(), i + 1, url, username);
|
|
usernameFileExists = usernameFile.first != null && checkPathExists(usernameFile.first);
|
|
}
|
|
checkList.add(fileExists || usernameFileExists);
|
|
}
|
|
break;
|
|
default:
|
|
}
|
|
return checkList;
|
|
}
|
|
|
|
private static boolean checkPathExists(@NonNull final List<String> paths) {
|
|
if (root == null) return false;
|
|
DocumentFile dir = root;
|
|
for (final String path : paths) {
|
|
dir = dir.findFile(path);
|
|
if (dir == null || !dir.exists()) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static void showDownloadDialog(@NonNull Context context,
|
|
@NonNull final Media feedModel,
|
|
final int childPosition) {
|
|
if (childPosition >= 0) {
|
|
final DialogInterface.OnClickListener clickListener = (dialog, which) -> {
|
|
switch (which) {
|
|
case 0:
|
|
DownloadUtils.download(context, feedModel, childPosition);
|
|
break;
|
|
case 1:
|
|
DownloadUtils.download(context, feedModel);
|
|
break;
|
|
case DialogInterface.BUTTON_NEGATIVE:
|
|
default:
|
|
dialog.dismiss();
|
|
break;
|
|
}
|
|
};
|
|
final String[] items = new String[]{
|
|
context.getString(R.string.post_viewer_download_current),
|
|
context.getString(R.string.post_viewer_download_album),
|
|
};
|
|
new AlertDialog.Builder(context)
|
|
.setTitle(R.string.post_viewer_download_dialog_title)
|
|
.setItems(items, clickListener)
|
|
.setNegativeButton(R.string.cancel, null)
|
|
.show();
|
|
return;
|
|
}
|
|
DownloadUtils.download(context, feedModel);
|
|
}
|
|
|
|
public static void download(@NonNull final Context context,
|
|
@NonNull final StoryModel storyModel) {
|
|
final DocumentFile downloadDir = getDownloadDir(context, storyModel.getUsername());
|
|
if (downloadDir == null) return;
|
|
final String url = storyModel.getItemType() == MediaItemType.MEDIA_TYPE_VIDEO
|
|
? storyModel.getVideoUrl()
|
|
: storyModel.getStoryUrl();
|
|
final String extension = DownloadUtils.getFileExtensionFromUrl(url);
|
|
final String baseFileName = storyModel.getStoryMediaId() + "_"
|
|
+ storyModel.getTimestamp() + extension;
|
|
final String usernamePrepend = Utils.settingsHelper.getBoolean(PreferenceKeys.DOWNLOAD_PREPEND_USER_NAME)
|
|
&& storyModel.getUsername() != null ? storyModel.getUsername() + "_" : "";
|
|
final String fileName = usernamePrepend + baseFileName;
|
|
DocumentFile saveFile = downloadDir.findFile(fileName);
|
|
if (saveFile == null) {
|
|
final String mimeType = Utils.mimeTypeMap.getMimeTypeFromExtension(extension.startsWith(".") ? extension.substring(1) : extension);
|
|
if (mimeType == null) return;
|
|
saveFile = downloadDir.createFile(mimeType, fileName);
|
|
}
|
|
// final File saveFile = new File(downloadDir, fileName);
|
|
download(context, url, saveFile);
|
|
}
|
|
|
|
public static void download(@NonNull final Context context,
|
|
@NonNull final Media feedModel) {
|
|
download(context, feedModel, -1);
|
|
}
|
|
|
|
public static void download(@NonNull final Context context,
|
|
@NonNull final Media feedModel,
|
|
final int position) {
|
|
download(context, Collections.singletonList(feedModel), position);
|
|
}
|
|
|
|
public static void download(@NonNull final Context context,
|
|
@NonNull final List<Media> feedModels) {
|
|
download(context, feedModels, -1);
|
|
}
|
|
|
|
private static void download(@NonNull final Context context,
|
|
@NonNull final List<Media> feedModels,
|
|
final int childPositionIfSingle) {
|
|
final Map<String, DocumentFile> map = new HashMap<>();
|
|
for (final Media media : feedModels) {
|
|
final User mediaUser = media.getUser();
|
|
final String username = mediaUser == null ? "" : mediaUser.getUsername();
|
|
final List<String> userFolderPaths = getSubPathForUserFolder(username);
|
|
// final DocumentFile downloadDir = getDownloadDir(context, mediaUser == null ? "" : mediaUser.getUsername());
|
|
switch (media.getMediaType()) {
|
|
case MEDIA_TYPE_IMAGE:
|
|
case MEDIA_TYPE_VIDEO: {
|
|
final String url = getUrlOfType(media);
|
|
String fileName = media.getId();
|
|
if (mediaUser != null && TextUtils.isEmpty(media.getCode())) {
|
|
fileName = mediaUser.getUsername() + "_" + fileName;
|
|
}
|
|
if (!TextUtils.isEmpty(media.getCode())) {
|
|
fileName = media.getCode();
|
|
if (Utils.settingsHelper.getBoolean(PreferenceKeys.DOWNLOAD_PREPEND_USER_NAME) && mediaUser != null) {
|
|
fileName = mediaUser.getUsername() + "_" + fileName;
|
|
}
|
|
}
|
|
final Pair<List<String>, String> pair = getDownloadSavePaths(userFolderPaths, fileName, url);
|
|
final DocumentFile file = createFile(pair);
|
|
if (file == null) continue;
|
|
map.put(url, file);
|
|
break;
|
|
}
|
|
case MEDIA_TYPE_VOICE: {
|
|
final String url = getUrlOfType(media);
|
|
String fileName = media.getId();
|
|
if (mediaUser != null) {
|
|
fileName = mediaUser.getUsername() + "_" + fileName;
|
|
}
|
|
final Pair<List<String>, String> pair = getDownloadSavePaths(userFolderPaths, fileName, url);
|
|
final DocumentFile file = createFile(pair);
|
|
if (file == null) continue;
|
|
map.put(url, file);
|
|
break;
|
|
}
|
|
case MEDIA_TYPE_SLIDER:
|
|
final List<Media> sliderItems = media.getCarouselMedia();
|
|
for (int i = 0; i < sliderItems.size(); i++) {
|
|
if (childPositionIfSingle >= 0 && feedModels.size() == 1 && i != childPositionIfSingle) continue;
|
|
final Media child = sliderItems.get(i);
|
|
final String url = getUrlOfType(child);
|
|
final String usernamePrepend = Utils.settingsHelper.getBoolean(PreferenceKeys.DOWNLOAD_PREPEND_USER_NAME) && mediaUser != null
|
|
? mediaUser.getUsername()
|
|
: "";
|
|
final Pair<List<String>, String> pair = getDownloadChildSavePaths(
|
|
new ArrayList<>(userFolderPaths), media.getCode(), i + 1, url, usernamePrepend);
|
|
final DocumentFile file = createFile(pair);
|
|
if (file == null) continue;
|
|
map.put(url, file);
|
|
}
|
|
break;
|
|
default:
|
|
}
|
|
}
|
|
if (map.isEmpty()) return;
|
|
download(context, map);
|
|
}
|
|
|
|
@Nullable
|
|
private static DocumentFile createFile(@NonNull final Pair<List<String>, String> pair) {
|
|
if (root == null) return null;
|
|
if (pair.first == null || pair.second == null) return null;
|
|
DocumentFile dir = root;
|
|
final List<String> first = pair.first;
|
|
for (int i = 0; i < first.size(); i++) {
|
|
final String name = first.get(i);
|
|
final DocumentFile file = dir.findFile(name);
|
|
if (file != null) {
|
|
dir = file;
|
|
continue;
|
|
}
|
|
dir = i == first.size() - 1 ? dir.createFile(pair.second, name) : dir.createDirectory(name);
|
|
if (dir == null) break;
|
|
}
|
|
return dir;
|
|
}
|
|
|
|
@Nullable
|
|
private static String getUrlOfType(@NonNull final Media media) {
|
|
switch (media.getMediaType()) {
|
|
case MEDIA_TYPE_IMAGE: {
|
|
return ResponseBodyUtils.getImageUrl(media);
|
|
}
|
|
case MEDIA_TYPE_VIDEO: {
|
|
final List<MediaCandidate> videoVersions = media.getVideoVersions();
|
|
String url = null;
|
|
if (videoVersions != null && !videoVersions.isEmpty()) {
|
|
final MediaCandidate videoVersion = videoVersions.get(0);
|
|
if (videoVersion != null) {
|
|
url = videoVersion.getUrl();
|
|
}
|
|
}
|
|
return url;
|
|
}
|
|
case MEDIA_TYPE_VOICE: {
|
|
final Audio audio = media.getAudio();
|
|
String url = null;
|
|
if (audio != null) {
|
|
url = audio.getAudioSrc();
|
|
}
|
|
return url;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static void download(final Context context,
|
|
final String url,
|
|
final DocumentFile filePath) {
|
|
if (context == null || url == null || filePath == null) return;
|
|
download(context, Collections.singletonMap(url, filePath));
|
|
}
|
|
|
|
private static void download(final Context context, final Map<String, DocumentFile> urlFilePathMap) {
|
|
if (context == null) return;
|
|
final Constraints constraints = new Constraints.Builder()
|
|
.setRequiredNetworkType(NetworkType.CONNECTED)
|
|
.build();
|
|
final DownloadWorker.DownloadRequest request = DownloadWorker.DownloadRequest.builder()
|
|
.setUrlToFilePathMap(urlFilePathMap)
|
|
.build();
|
|
final String requestJson = new Gson().toJson(request);
|
|
final DocumentFile tempFile = getTempFile(null, "json");
|
|
if (tempFile == null) {
|
|
Log.e(TAG, "download: temp file is null");
|
|
return;
|
|
}
|
|
final Uri uri = tempFile.getUri();
|
|
final ContentResolver contentResolver = context.getContentResolver();
|
|
if (contentResolver == null) return;
|
|
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(contentResolver.openOutputStream(uri)))) {
|
|
writer.write(requestJson);
|
|
} catch (IOException e) {
|
|
Log.e(TAG, "download: Error writing request to file", e);
|
|
tempFile.delete();
|
|
return;
|
|
}
|
|
final WorkRequest downloadWorkRequest = new OneTimeWorkRequest.Builder(DownloadWorker.class)
|
|
.setInputData(
|
|
new Data.Builder()
|
|
.putString(DownloadWorker.KEY_DOWNLOAD_REQUEST_JSON, tempFile.getUri().toString())
|
|
.build()
|
|
)
|
|
.setConstraints(constraints)
|
|
.addTag("download")
|
|
.build();
|
|
WorkManager.getInstance(context)
|
|
.enqueue(downloadWorkRequest);
|
|
}
|
|
|
|
@Nullable
|
|
public static Uri getRootDirUri() {
|
|
return root != null ? root.getUri() : null;
|
|
}
|
|
|
|
public static class ReselectDocumentTreeException extends Exception {
|
|
private final Uri initialUri;
|
|
|
|
public ReselectDocumentTreeException() {
|
|
initialUri = null;
|
|
}
|
|
|
|
public ReselectDocumentTreeException(final String message) {
|
|
super(message);
|
|
initialUri = null;
|
|
}
|
|
|
|
public ReselectDocumentTreeException(final Uri initialUri) {
|
|
this.initialUri = initialUri;
|
|
}
|
|
|
|
public Uri getInitialUri() {
|
|
return initialUri;
|
|
}
|
|
}
|
|
}
|