Simplify the storage APIs use
* use Java I/O (classic way) on older android versions * use Storage Access Framework on newer android versions (Android Lollipop or later) * both changes have the external SD Card write permission * add option to ask the save path on each download * warn the user if the save paths are not defined, this only happens on the first NewPipe run (Android Lollipop or later)
This commit is contained in:
parent
d1573a0a6e
commit
34b2b96158
|
@ -212,6 +212,7 @@ public class DownloadDialog extends DialogFragment implements RadioGroup.OnCheck
|
||||||
mainStorageAudio = mgr.getMainStorageAudio();
|
mainStorageAudio = mgr.getMainStorageAudio();
|
||||||
mainStorageVideo = mgr.getMainStorageVideo();
|
mainStorageVideo = mgr.getMainStorageVideo();
|
||||||
downloadManager = mgr.getDownloadManager();
|
downloadManager = mgr.getDownloadManager();
|
||||||
|
askForSavePath = mgr.askForSavePath();
|
||||||
|
|
||||||
okButton.setEnabled(true);
|
okButton.setEnabled(true);
|
||||||
|
|
||||||
|
@ -509,6 +510,7 @@ public class DownloadDialog extends DialogFragment implements RadioGroup.OnCheck
|
||||||
DownloadManager downloadManager = null;
|
DownloadManager downloadManager = null;
|
||||||
ActionMenuItemView okButton = null;
|
ActionMenuItemView okButton = null;
|
||||||
Context context;
|
Context context;
|
||||||
|
boolean askForSavePath;
|
||||||
|
|
||||||
private String getNameEditText() {
|
private String getNameEditText() {
|
||||||
String str = nameEditText.getText().toString().trim();
|
String str = nameEditText.getText().toString().trim();
|
||||||
|
@ -567,10 +569,11 @@ public class DownloadDialog extends DialogFragment implements RadioGroup.OnCheck
|
||||||
throw new RuntimeException("No stream selected");
|
throw new RuntimeException("No stream selected");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mainStorage == null) {
|
if (mainStorage == null || askForSavePath) {
|
||||||
// This part is called if with SAF preferred:
|
// This part is called if with SAF preferred:
|
||||||
// * older android version running
|
// * older android version running
|
||||||
// * save path not defined (via download settings)
|
// * save path not defined (via download settings)
|
||||||
|
// * the user as checked the "ask where to download" option
|
||||||
|
|
||||||
StoredFileHelper.requestSafWithFileCreation(this, REQUEST_DOWNLOAD_PATH_SAF, filename, mime);
|
StoredFileHelper.requestSafWithFileCreation(this, REQUEST_DOWNLOAD_PATH_SAF, filename, mime);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -9,7 +9,6 @@ import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.annotation.RequiresApi;
|
|
||||||
import android.support.annotation.StringRes;
|
import android.support.annotation.StringRes;
|
||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -37,50 +36,40 @@ public class DownloadSettingsFragment extends BasePreferenceFragment {
|
||||||
private String DOWNLOAD_PATH_VIDEO_PREFERENCE;
|
private String DOWNLOAD_PATH_VIDEO_PREFERENCE;
|
||||||
private String DOWNLOAD_PATH_AUDIO_PREFERENCE;
|
private String DOWNLOAD_PATH_AUDIO_PREFERENCE;
|
||||||
|
|
||||||
private String DOWNLOAD_STORAGE_API;
|
private String DOWNLOAD_STORAGE_ASK;
|
||||||
private String DOWNLOAD_STORAGE_API_DEFAULT;
|
|
||||||
|
|
||||||
private Preference prefPathVideo;
|
private Preference prefPathVideo;
|
||||||
private Preference prefPathAudio;
|
private Preference prefPathAudio;
|
||||||
|
private Preference prefStorageAsk;
|
||||||
|
|
||||||
private Context ctx;
|
private Context ctx;
|
||||||
|
|
||||||
private boolean lastAPIJavaIO;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
DOWNLOAD_PATH_VIDEO_PREFERENCE = getString(R.string.download_path_video_key);
|
DOWNLOAD_PATH_VIDEO_PREFERENCE = getString(R.string.download_path_video_key);
|
||||||
DOWNLOAD_PATH_AUDIO_PREFERENCE = getString(R.string.download_path_audio_key);
|
DOWNLOAD_PATH_AUDIO_PREFERENCE = getString(R.string.download_path_audio_key);
|
||||||
DOWNLOAD_STORAGE_API = getString(R.string.downloads_storage_api);
|
DOWNLOAD_STORAGE_ASK = getString(R.string.downloads_storage_ask);
|
||||||
DOWNLOAD_STORAGE_API_DEFAULT = getString(R.string.downloads_storage_api_default);
|
|
||||||
|
|
||||||
prefPathVideo = findPreference(DOWNLOAD_PATH_VIDEO_PREFERENCE);
|
prefPathVideo = findPreference(DOWNLOAD_PATH_VIDEO_PREFERENCE);
|
||||||
prefPathAudio = findPreference(DOWNLOAD_PATH_AUDIO_PREFERENCE);
|
prefPathAudio = findPreference(DOWNLOAD_PATH_AUDIO_PREFERENCE);
|
||||||
|
prefStorageAsk = findPreference(DOWNLOAD_STORAGE_ASK);
|
||||||
lastAPIJavaIO = usingJavaIO();
|
|
||||||
|
|
||||||
updatePreferencesSummary();
|
updatePreferencesSummary();
|
||||||
updatePathPickers(lastAPIJavaIO);
|
updatePathPickers(!defaultPreferences.getBoolean(DOWNLOAD_STORAGE_ASK, false));
|
||||||
|
|
||||||
findPreference(DOWNLOAD_STORAGE_API).setOnPreferenceChangeListener((preference, value) -> {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
boolean javaIO = DOWNLOAD_STORAGE_API_DEFAULT.equals(value);
|
prefStorageAsk.setSummary(R.string.downloads_storage_ask_summary);
|
||||||
|
}
|
||||||
|
|
||||||
if (javaIO == lastAPIJavaIO) return true;
|
if (hasInvalidPath(DOWNLOAD_PATH_VIDEO_PREFERENCE) || hasInvalidPath(DOWNLOAD_PATH_AUDIO_PREFERENCE)) {
|
||||||
lastAPIJavaIO = javaIO;
|
Toast.makeText(ctx, R.string.download_pick_path, Toast.LENGTH_SHORT).show();
|
||||||
|
updatePreferencesSummary();
|
||||||
|
}
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
prefStorageAsk.setOnPreferenceChangeListener((preference, value) -> {
|
||||||
boolean res = forgetPath(DOWNLOAD_PATH_VIDEO_PREFERENCE);
|
updatePathPickers(!(boolean) value);
|
||||||
res |= forgetPath(DOWNLOAD_PATH_AUDIO_PREFERENCE);
|
|
||||||
|
|
||||||
if (res) {
|
|
||||||
Toast.makeText(ctx, R.string.download_pick_path, Toast.LENGTH_SHORT).show();
|
|
||||||
updatePreferencesSummary();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updatePathPickers(javaIO);
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -100,7 +89,7 @@ public class DownloadSettingsFragment extends BasePreferenceFragment {
|
||||||
public void onDetach() {
|
public void onDetach() {
|
||||||
super.onDetach();
|
super.onDetach();
|
||||||
ctx = null;
|
ctx = null;
|
||||||
findPreference(DOWNLOAD_STORAGE_API).setOnPreferenceChangeListener(null);
|
prefStorageAsk.setOnPreferenceChangeListener(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updatePreferencesSummary() {
|
private void updatePreferencesSummary() {
|
||||||
|
@ -133,34 +122,18 @@ public class DownloadSettingsFragment extends BasePreferenceFragment {
|
||||||
target.setSummary(rawUri);
|
target.setSummary(rawUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
private boolean forgetPath(String prefKey) {
|
|
||||||
String path = defaultPreferences.getString(prefKey, "");
|
|
||||||
if (path == null || path.isEmpty()) return true;
|
|
||||||
|
|
||||||
// forget SAF path if necessary
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
forgetSAFTree(getContext(), path);
|
|
||||||
|
|
||||||
defaultPreferences.edit().putString(prefKey, "").apply();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isFileUri(String path) {
|
private boolean isFileUri(String path) {
|
||||||
return path.charAt(0) == File.separatorChar || path.startsWith(ContentResolver.SCHEME_FILE);
|
return path.charAt(0) == File.separatorChar || path.startsWith(ContentResolver.SCHEME_FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updatePathPickers(boolean useJavaIO) {
|
private boolean hasInvalidPath(String prefKey) {
|
||||||
boolean enabled = useJavaIO || Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
|
String value = defaultPreferences.getString(prefKey, null);
|
||||||
prefPathVideo.setEnabled(enabled);
|
return value == null || value.isEmpty();
|
||||||
prefPathAudio.setEnabled(enabled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean usingJavaIO() {
|
private void updatePathPickers(boolean enabled) {
|
||||||
return DOWNLOAD_STORAGE_API_DEFAULT.equals(
|
prefPathVideo.setEnabled(enabled);
|
||||||
defaultPreferences.getString(DOWNLOAD_STORAGE_API, DOWNLOAD_STORAGE_API_DEFAULT)
|
prefPathAudio.setEnabled(enabled);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: after releasing the old path, all downloads created on the folder becomes inaccessible
|
// FIXME: after releasing the old path, all downloads created on the folder becomes inaccessible
|
||||||
|
@ -198,33 +171,31 @@ public class DownloadSettingsFragment extends BasePreferenceFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
String key = preference.getKey();
|
String key = preference.getKey();
|
||||||
|
int request;
|
||||||
|
|
||||||
if (key.equals(DOWNLOAD_PATH_VIDEO_PREFERENCE) || key.equals(DOWNLOAD_PATH_AUDIO_PREFERENCE)) {
|
if (key.equals(DOWNLOAD_PATH_VIDEO_PREFERENCE)) {
|
||||||
boolean safPick = !usingJavaIO();
|
request = REQUEST_DOWNLOAD_VIDEO_PATH;
|
||||||
|
} else if (key.equals(DOWNLOAD_PATH_AUDIO_PREFERENCE)) {
|
||||||
int request = 0;
|
request = REQUEST_DOWNLOAD_AUDIO_PATH;
|
||||||
if (key.equals(DOWNLOAD_PATH_VIDEO_PREFERENCE)) {
|
} else {
|
||||||
request = REQUEST_DOWNLOAD_VIDEO_PATH;
|
return super.onPreferenceTreeClick(preference);
|
||||||
} else if (key.equals(DOWNLOAD_PATH_AUDIO_PREFERENCE)) {
|
|
||||||
request = REQUEST_DOWNLOAD_AUDIO_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
Intent i;
|
|
||||||
if (safPick && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
i = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
|
|
||||||
.putExtra("android.content.extra.SHOW_ADVANCED", true)
|
|
||||||
.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | StoredDirectoryHelper.PERMISSION_FLAGS);
|
|
||||||
} else {
|
|
||||||
i = new Intent(getActivity(), FilePickerActivityHelper.class)
|
|
||||||
.putExtra(FilePickerActivityHelper.EXTRA_ALLOW_MULTIPLE, false)
|
|
||||||
.putExtra(FilePickerActivityHelper.EXTRA_ALLOW_CREATE_DIR, true)
|
|
||||||
.putExtra(FilePickerActivityHelper.EXTRA_MODE, FilePickerActivityHelper.MODE_DIR);
|
|
||||||
}
|
|
||||||
|
|
||||||
startActivityForResult(i, request);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.onPreferenceTreeClick(preference);
|
Intent i;
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
i = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
|
||||||
|
.putExtra("android.content.extra.SHOW_ADVANCED", true)
|
||||||
|
.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | StoredDirectoryHelper.PERMISSION_FLAGS);
|
||||||
|
} else {
|
||||||
|
i = new Intent(getActivity(), FilePickerActivityHelper.class)
|
||||||
|
.putExtra(FilePickerActivityHelper.EXTRA_ALLOW_MULTIPLE, false)
|
||||||
|
.putExtra(FilePickerActivityHelper.EXTRA_ALLOW_CREATE_DIR, true)
|
||||||
|
.putExtra(FilePickerActivityHelper.EXTRA_MODE, FilePickerActivityHelper.MODE_DIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
startActivityForResult(i, request);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -252,7 +223,7 @@ public class DownloadSettingsFragment extends BasePreferenceFragment {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!usingJavaIO() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
// steps:
|
// steps:
|
||||||
// 1. revoke permissions on the old save path
|
// 1. revoke permissions on the old save path
|
||||||
// 2. acquire permissions on the new save path
|
// 2. acquire permissions on the new save path
|
||||||
|
|
|
@ -94,24 +94,7 @@ public class NewPipeSettings {
|
||||||
return new File(Environment.getExternalStorageDirectory(), defaultDirectoryName);
|
return new File(Environment.getExternalStorageDirectory(), defaultDirectoryName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void resetDownloadFolders(Context context) {
|
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
|
||||||
|
|
||||||
prefs.edit()
|
|
||||||
.putString(context.getString(R.string.downloads_storage_api), context.getString(R.string.downloads_storage_api_default))
|
|
||||||
.apply();
|
|
||||||
|
|
||||||
resetDownloadFolder(prefs, context.getString(R.string.download_path_audio_key), Environment.DIRECTORY_MUSIC);
|
|
||||||
resetDownloadFolder(prefs, context.getString(R.string.download_path_video_key), Environment.DIRECTORY_MOVIES);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void resetDownloadFolder(SharedPreferences prefs, String key, String defaultDirectoryName) {
|
|
||||||
SharedPreferences.Editor spEditor = prefs.edit();
|
|
||||||
spEditor.putString(key, getNewPipeChildFolderPathForDir(getDir(defaultDirectoryName)));
|
|
||||||
spEditor.apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getNewPipeChildFolderPathForDir(File dir) {
|
private static String getNewPipeChildFolderPathForDir(File dir) {
|
||||||
return new File(dir, "NewPipe").getAbsolutePath();
|
return new File(dir, "NewPipe").toURI().toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ import android.os.Build;
|
||||||
import android.provider.DocumentsContract;
|
import android.provider.DocumentsContract;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.annotation.RequiresApi;
|
|
||||||
import android.support.v4.provider.DocumentFile;
|
import android.support.v4.provider.DocumentFile;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -33,7 +32,6 @@ public class StoredDirectoryHelper {
|
||||||
|
|
||||||
private String tag;
|
private String tag;
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
public StoredDirectoryHelper(@NonNull Context context, @NonNull Uri path, String tag) throws IOException {
|
public StoredDirectoryHelper(@NonNull Context context, @NonNull Uri path, String tag) throws IOException {
|
||||||
this.tag = tag;
|
this.tag = tag;
|
||||||
|
|
||||||
|
@ -50,6 +48,9 @@ public class StoredDirectoryHelper {
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
throw new IOException("Storage Access Framework with Directory API is not available");
|
||||||
|
|
||||||
this.docTree = DocumentFile.fromTreeUri(context, path);
|
this.docTree = DocumentFile.fromTreeUri(context, path);
|
||||||
|
|
||||||
if (this.docTree == null)
|
if (this.docTree == null)
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package us.shandian.giga.service;
|
package us.shandian.giga.service;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
|
import android.app.AlertDialog;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
@ -20,7 +20,6 @@ import android.net.NetworkRequest;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Environment;
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
@ -28,6 +27,7 @@ import android.os.Message;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.annotation.StringRes;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.support.v4.app.NotificationCompat.Builder;
|
import android.support.v4.app.NotificationCompat.Builder;
|
||||||
import android.support.v4.content.PermissionChecker;
|
import android.support.v4.content.PermissionChecker;
|
||||||
|
@ -41,7 +41,6 @@ import org.schabi.newpipe.player.helper.LockManager;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import us.shandian.giga.get.DownloadMission;
|
import us.shandian.giga.get.DownloadMission;
|
||||||
|
@ -141,7 +140,7 @@ public class DownloadManagerService extends Service {
|
||||||
|
|
||||||
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
|
||||||
mManager = new DownloadManager(this, mHandler, getVideoStorage(), getAudioStorage());
|
mManager = new DownloadManager(this, mHandler, loadMainVideoStorage(), loadMainAudioStorage());
|
||||||
|
|
||||||
Intent openDownloadListIntent = new Intent(this, DownloadActivity.class)
|
Intent openDownloadListIntent = new Intent(this, DownloadActivity.class)
|
||||||
.setAction(Intent.ACTION_MAIN);
|
.setAction(Intent.ACTION_MAIN);
|
||||||
|
@ -271,6 +270,33 @@ public class DownloadManagerService extends Service {
|
||||||
Toast.makeText(this, "Permission denied (write)", Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, "Permission denied (write)", Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check download save paths
|
||||||
|
|
||||||
|
String msg = "";
|
||||||
|
if (mManager.mMainStorageVideo == null)
|
||||||
|
msg += getString(R.string.download_path_title);
|
||||||
|
else if (mManager.mMainStorageAudio == null)
|
||||||
|
msg += getString(R.string.download_path_audio_title);
|
||||||
|
|
||||||
|
if (!msg.isEmpty()) {
|
||||||
|
String title;
|
||||||
|
if (mManager.mMainStorageVideo == null && mManager.mMainStorageAudio == null) {
|
||||||
|
title = getString(R.string.general_error);
|
||||||
|
msg = getString(R.string.no_available_dir) + ":\n" + msg;
|
||||||
|
} else {
|
||||||
|
title = msg;
|
||||||
|
msg = getString(R.string.no_available_dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
new AlertDialog.Builder(this)
|
||||||
|
.setPositiveButton(android.R.string.ok, null)
|
||||||
|
.setTitle(title)
|
||||||
|
.setMessage(msg)
|
||||||
|
.create()
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return mBinder;
|
return mBinder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,13 +374,10 @@ public class DownloadManagerService extends Service {
|
||||||
mManager.mPrefMeteredDownloads = prefs.getBoolean(key, false);
|
mManager.mPrefMeteredDownloads = prefs.getBoolean(key, false);
|
||||||
} else if (key.equals(getString(R.string.downloads_queue_limit))) {
|
} else if (key.equals(getString(R.string.downloads_queue_limit))) {
|
||||||
mManager.mPrefQueueLimit = prefs.getBoolean(key, true);
|
mManager.mPrefQueueLimit = prefs.getBoolean(key, true);
|
||||||
} else if (key.equals(getString(R.string.downloads_storage_api))) {
|
|
||||||
mManager.mMainStorageVideo = loadMainStorage(getString(R.string.download_path_video_key), DownloadManager.TAG_VIDEO);
|
|
||||||
mManager.mMainStorageAudio = loadMainStorage(getString(R.string.download_path_audio_key), DownloadManager.TAG_AUDIO);
|
|
||||||
} else if (key.equals(getString(R.string.download_path_video_key))) {
|
} else if (key.equals(getString(R.string.download_path_video_key))) {
|
||||||
mManager.mMainStorageVideo = loadMainStorage(key, DownloadManager.TAG_VIDEO);
|
mManager.mMainStorageVideo = loadMainVideoStorage();
|
||||||
} else if (key.equals(getString(R.string.download_path_audio_key))) {
|
} else if (key.equals(getString(R.string.download_path_audio_key))) {
|
||||||
mManager.mMainStorageAudio = loadMainStorage(key, DownloadManager.TAG_AUDIO);
|
mManager.mMainStorageAudio = loadMainAudioStorage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,7 +408,7 @@ public class DownloadManagerService extends Service {
|
||||||
* @param psArgs the arguments for the post-processing algorithm.
|
* @param psArgs the arguments for the post-processing algorithm.
|
||||||
* @param nearLength the approximated final length of the file
|
* @param nearLength the approximated final length of the file
|
||||||
*/
|
*/
|
||||||
public static void startMission(Context context, String urls[], StoredFileHelper storage, char kind,
|
public static void startMission(Context context, String[] urls, StoredFileHelper storage, char kind,
|
||||||
int threads, String source, String psName, String[] psArgs, long nearLength) {
|
int threads, String source, String psName, String[] psArgs, long nearLength) {
|
||||||
Intent intent = new Intent(context, DownloadManagerService.class);
|
Intent intent = new Intent(context, DownloadManagerService.class);
|
||||||
intent.setAction(Intent.ACTION_RUN);
|
intent.setAction(Intent.ACTION_RUN);
|
||||||
|
@ -538,56 +561,28 @@ public class DownloadManagerService extends Service {
|
||||||
mLockAcquired = acquire;
|
mLockAcquired = acquire;
|
||||||
}
|
}
|
||||||
|
|
||||||
private StoredDirectoryHelper getVideoStorage() {
|
private StoredDirectoryHelper loadMainVideoStorage() {
|
||||||
return loadMainStorage(getString(R.string.download_path_video_key), DownloadManager.TAG_VIDEO);
|
return loadMainStorage(R.string.download_path_video_key, DownloadManager.TAG_VIDEO);
|
||||||
}
|
}
|
||||||
|
|
||||||
private StoredDirectoryHelper getAudioStorage() {
|
private StoredDirectoryHelper loadMainAudioStorage() {
|
||||||
return loadMainStorage(getString(R.string.download_path_audio_key), DownloadManager.TAG_AUDIO);
|
return loadMainStorage(R.string.download_path_audio_key, DownloadManager.TAG_AUDIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private StoredDirectoryHelper loadMainStorage(@StringRes int prefKey, String tag) {
|
||||||
|
String path = mPrefs.getString(getString(prefKey), null);
|
||||||
|
|
||||||
private StoredDirectoryHelper loadMainStorage(String prefKey, String tag) {
|
if (path == null || path.isEmpty()) return null;
|
||||||
String path = mPrefs.getString(prefKey, null);
|
|
||||||
|
|
||||||
final String JAVA_IO = getString(R.string.downloads_storage_api_default);
|
|
||||||
boolean useJavaIO = JAVA_IO.equals(mPrefs.getString(getString(R.string.downloads_storage_api), JAVA_IO));
|
|
||||||
|
|
||||||
final String defaultPath;
|
|
||||||
switch (tag) {
|
|
||||||
case DownloadManager.TAG_VIDEO:
|
|
||||||
defaultPath = Environment.DIRECTORY_MOVIES;
|
|
||||||
break;
|
|
||||||
case DownloadManager.TAG_AUDIO:
|
|
||||||
defaultPath = Environment.DIRECTORY_MUSIC;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path == null || path.isEmpty()) {
|
|
||||||
if (useJavaIO)
|
|
||||||
return new StoredDirectoryHelper(new File(defaultPath).toURI(), tag);
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path.charAt(0) == File.separatorChar) {
|
if (path.charAt(0) == File.separatorChar) {
|
||||||
Log.i(TAG, "Migrating old save path: " + path);
|
Log.i(TAG, "Old save path style present: " + path);
|
||||||
|
|
||||||
useJavaIO = true;
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
|
||||||
path = Uri.fromFile(new File(path)).toString();
|
path = Uri.fromFile(new File(path)).toString();
|
||||||
|
else
|
||||||
|
path = "";
|
||||||
|
|
||||||
mPrefs.edit().putString(prefKey, path).apply();
|
mPrefs.edit().putString(getString(prefKey), "").apply();
|
||||||
}
|
|
||||||
|
|
||||||
boolean override = path.startsWith(ContentResolver.SCHEME_FILE) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
|
|
||||||
if (useJavaIO || override) {
|
|
||||||
return new StoredDirectoryHelper(URI.create(path), tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
return null;// SAF Directory API is not available in older versions
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -619,6 +614,13 @@ public class DownloadManagerService extends Service {
|
||||||
return mManager.mMainStorageAudio;
|
return mManager.mMainStorageAudio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean askForSavePath() {
|
||||||
|
return DownloadManagerService.this.mPrefs.getBoolean(
|
||||||
|
DownloadManagerService.this.getString(R.string.downloads_storage_ask),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public void addMissionEventListener(Handler handler) {
|
public void addMissionEventListener(Handler handler) {
|
||||||
manageObservers(handler, true);
|
manageObservers(handler, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -459,19 +459,15 @@ abrir en modo popup</string>
|
||||||
<string name="error_progress_lost">Se perdió el progreso porque el archivo fue eliminado</string>
|
<string name="error_progress_lost">Se perdió el progreso porque el archivo fue eliminado</string>
|
||||||
<string name="error_timeout">Tiempo de espera excedido</string>
|
<string name="error_timeout">Tiempo de espera excedido</string>
|
||||||
|
|
||||||
<string name="downloads_storage">API de almacenamiento</string>
|
|
||||||
<string name="downloads_storage_desc">Seleccione que API utilizar para almacenar las descargas</string>
|
|
||||||
|
|
||||||
<string name="storage_access_framework_description">Framework de acceso a almacenamiento</string>
|
|
||||||
<string name="java_io_description">Java I/O</string>
|
|
||||||
|
|
||||||
<string name="save_as">Guardar como…</string>
|
|
||||||
|
|
||||||
<string name="download_to_sdcard_error_message">No es posible descargar a una tarjeta SD externa. \¿Restablecer la ubicación de la carpeta de descarga\?</string>
|
<string name="download_to_sdcard_error_message">No es posible descargar a una tarjeta SD externa. \¿Restablecer la ubicación de la carpeta de descarga\?</string>
|
||||||
|
|
||||||
<string name="download_pick_path">Seleccione los directorios de descarga</string>
|
<string name="download_pick_path">Seleccione los directorios de descarga</string>
|
||||||
<string name="missions_header_pending">Pendiente</string>
|
<string name="missions_header_pending">Pendiente</string>
|
||||||
|
|
||||||
|
<string name="downloads_storage_ask_title">Preguntar dónde descargar</string>
|
||||||
|
<string name="downloads_storage_ask_summary">Se preguntará dónde guardar cada descarga</string>
|
||||||
|
<string name="downloads_storage_ask_summary_kitkat">Se preguntará dónde guardar cada descarga.\nHabilita esta opción si quieres descargar en la tarjeta SD externa</string>
|
||||||
|
|
||||||
<string name="unsubscribe">Desuscribirse</string>
|
<string name="unsubscribe">Desuscribirse</string>
|
||||||
<string name="tab_new">Nueva pestaña</string>
|
<string name="tab_new">Nueva pestaña</string>
|
||||||
<string name="tab_choose">Elige la pestaña</string>
|
<string name="tab_choose">Elige la pestaña</string>
|
||||||
|
|
|
@ -160,20 +160,7 @@
|
||||||
<string name="clear_views_history_key" translatable="false">clear_play_history</string>
|
<string name="clear_views_history_key" translatable="false">clear_play_history</string>
|
||||||
<string name="clear_search_history_key" translatable="false">clear_search_history</string>
|
<string name="clear_search_history_key" translatable="false">clear_search_history</string>
|
||||||
|
|
||||||
<string name="downloads_storage_api" translatable="false">downloads_storage_api</string>
|
<string name="downloads_storage_ask" translatable="false">downloads_storage_ask</string>
|
||||||
|
|
||||||
<!-- WARNING: changing the default value will require update the code too -->
|
|
||||||
<string name="downloads_storage_api_default" translatable="false">javaIO</string>
|
|
||||||
|
|
||||||
<string-array name="downloads_storage_api_values" translatable="false">
|
|
||||||
<item translatable="false">SAF</item>
|
|
||||||
<item translatable="false">javaIO</item>
|
|
||||||
</string-array>
|
|
||||||
|
|
||||||
<string-array name="downloads_storage_api_description" translatable="true">
|
|
||||||
<item translatable="true">@string/storage_access_framework_description</item>
|
|
||||||
<item translatable="true">@string/java_io_description</item>
|
|
||||||
</string-array>
|
|
||||||
|
|
||||||
<!-- FileName Downloads -->
|
<!-- FileName Downloads -->
|
||||||
<string name="settings_file_charset_key" translatable="false">file_rename_charset</string>
|
<string name="settings_file_charset_key" translatable="false">file_rename_charset</string>
|
||||||
|
|
|
@ -550,14 +550,10 @@
|
||||||
<string name="start_downloads">Start downloads</string>
|
<string name="start_downloads">Start downloads</string>
|
||||||
<string name="pause_downloads">Pause downloads</string>
|
<string name="pause_downloads">Pause downloads</string>
|
||||||
|
|
||||||
<string name="downloads_storage">Storage API</string>
|
|
||||||
<string name="downloads_storage_desc">Select which API use to store the downloads</string>
|
|
||||||
|
|
||||||
<string name="storage_access_framework_description">Storage Access Framework</string>
|
|
||||||
<string name="java_io_description">Java I/O</string>
|
|
||||||
|
|
||||||
<string name="save_as">Save as…</string>
|
|
||||||
|
|
||||||
<string name="download_pick_path">Select the downloads save path</string>
|
<string name="download_pick_path">Select the downloads save path</string>
|
||||||
|
|
||||||
|
<string name="downloads_storage_ask_title">Ask where to download</string>
|
||||||
|
<string name="downloads_storage_ask_summary">You will be asked where to save each download</string>
|
||||||
|
<string name="downloads_storage_ask_summary_kitkat">You will be asked where to save each download.\nEnable this option if you want download to the external SD Card</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
|
@ -5,14 +5,12 @@
|
||||||
android:title="@string/settings_category_downloads_title">
|
android:title="@string/settings_category_downloads_title">
|
||||||
|
|
||||||
|
|
||||||
<ListPreference
|
<CheckBoxPreference
|
||||||
app:iconSpaceReserved="false"
|
app:iconSpaceReserved="false"
|
||||||
android:defaultValue="@string/downloads_storage_api_default"
|
android:defaultValue="false"
|
||||||
android:entries="@array/downloads_storage_api_description"
|
android:key="@string/downloads_storage_ask"
|
||||||
android:entryValues="@array/downloads_storage_api_values"
|
android:summary="@string/downloads_storage_ask_summary_kitkat"
|
||||||
android:key="@string/downloads_storage_api"
|
android:title="@string/downloads_storage_ask_title" />
|
||||||
android:summary="@string/downloads_storage_desc"
|
|
||||||
android:title="@string/downloads_storage" />
|
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
app:iconSpaceReserved="false"
|
app:iconSpaceReserved="false"
|
||||||
|
|
Loading…
Reference in New Issue