mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-31 07:13:00 +00:00 
			
		
		
		
	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:
		| @@ -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) -> { |  | ||||||
|             boolean javaIO = DOWNLOAD_STORAGE_API_DEFAULT.equals(value); |  | ||||||
|  |  | ||||||
|             if (javaIO == lastAPIJavaIO) return true; |  | ||||||
|             lastAPIJavaIO = javaIO; |  | ||||||
|  |  | ||||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { |         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | ||||||
|                 boolean res = forgetPath(DOWNLOAD_PATH_VIDEO_PREFERENCE); |             prefStorageAsk.setSummary(R.string.downloads_storage_ask_summary); | ||||||
|                 res |= forgetPath(DOWNLOAD_PATH_AUDIO_PREFERENCE); |         } | ||||||
|  |  | ||||||
|                 if (res) { |         if (hasInvalidPath(DOWNLOAD_PATH_VIDEO_PREFERENCE) || hasInvalidPath(DOWNLOAD_PATH_AUDIO_PREFERENCE)) { | ||||||
|             Toast.makeText(ctx, R.string.download_pick_path, Toast.LENGTH_SHORT).show(); |             Toast.makeText(ctx, R.string.download_pick_path, Toast.LENGTH_SHORT).show(); | ||||||
|             updatePreferencesSummary(); |             updatePreferencesSummary(); | ||||||
|         } |         } | ||||||
|             } |  | ||||||
|  |  | ||||||
|             updatePathPickers(javaIO); |         prefStorageAsk.setOnPreferenceChangeListener((preference, value) -> { | ||||||
|  |             updatePathPickers(!(boolean) value); | ||||||
|             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,19 +171,18 @@ 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)) { |  | ||||||
|             boolean safPick = !usingJavaIO(); |  | ||||||
|  |  | ||||||
|             int request = 0; |  | ||||||
|         if (key.equals(DOWNLOAD_PATH_VIDEO_PREFERENCE)) { |         if (key.equals(DOWNLOAD_PATH_VIDEO_PREFERENCE)) { | ||||||
|             request = REQUEST_DOWNLOAD_VIDEO_PATH; |             request = REQUEST_DOWNLOAD_VIDEO_PATH; | ||||||
|         } else if (key.equals(DOWNLOAD_PATH_AUDIO_PREFERENCE)) { |         } else if (key.equals(DOWNLOAD_PATH_AUDIO_PREFERENCE)) { | ||||||
|             request = REQUEST_DOWNLOAD_AUDIO_PATH; |             request = REQUEST_DOWNLOAD_AUDIO_PATH; | ||||||
|  |         } else { | ||||||
|  |             return super.onPreferenceTreeClick(preference); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         Intent i; |         Intent i; | ||||||
|             if (safPick && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { |         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | ||||||
|             i = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE) |             i = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE) | ||||||
|                     .putExtra("android.content.extra.SHOW_ADVANCED", true) |                     .putExtra("android.content.extra.SHOW_ADVANCED", true) | ||||||
|                     .addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | StoredDirectoryHelper.PERMISSION_FLAGS); |                     .addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | StoredDirectoryHelper.PERMISSION_FLAGS); | ||||||
| @@ -222,9 +194,8 @@ public class DownloadSettingsFragment extends BasePreferenceFragment { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         startActivityForResult(i, request); |         startActivityForResult(i, request); | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return super.onPreferenceTreeClick(preference); |         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" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 kapodamy
					kapodamy