mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-30 23:03: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(); | ||||
|                 mainStorageVideo = mgr.getMainStorageVideo(); | ||||
|                 downloadManager = mgr.getDownloadManager(); | ||||
|                 askForSavePath = mgr.askForSavePath(); | ||||
|  | ||||
|                 okButton.setEnabled(true); | ||||
|  | ||||
| @@ -509,6 +510,7 @@ public class DownloadDialog extends DialogFragment implements RadioGroup.OnCheck | ||||
|     DownloadManager downloadManager = null; | ||||
|     ActionMenuItemView okButton = null; | ||||
|     Context context; | ||||
|     boolean askForSavePath; | ||||
|  | ||||
|     private String getNameEditText() { | ||||
|         String str = nameEditText.getText().toString().trim(); | ||||
| @@ -567,10 +569,11 @@ public class DownloadDialog extends DialogFragment implements RadioGroup.OnCheck | ||||
|                 throw new RuntimeException("No stream selected"); | ||||
|         } | ||||
|  | ||||
|         if (mainStorage == null) { | ||||
|         if (mainStorage == null || askForSavePath) { | ||||
|             // This part is called if with SAF preferred: | ||||
|             //  * older android version running | ||||
|             //  * 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); | ||||
|             return; | ||||
|   | ||||
| @@ -9,7 +9,6 @@ import android.net.Uri; | ||||
| import android.os.Build; | ||||
| import android.os.Bundle; | ||||
| import android.support.annotation.Nullable; | ||||
| import android.support.annotation.RequiresApi; | ||||
| import android.support.annotation.StringRes; | ||||
| import android.support.v7.preference.Preference; | ||||
| import android.util.Log; | ||||
| @@ -37,50 +36,40 @@ public class DownloadSettingsFragment extends BasePreferenceFragment { | ||||
|     private String DOWNLOAD_PATH_VIDEO_PREFERENCE; | ||||
|     private String DOWNLOAD_PATH_AUDIO_PREFERENCE; | ||||
|  | ||||
|     private String DOWNLOAD_STORAGE_API; | ||||
|     private String DOWNLOAD_STORAGE_API_DEFAULT; | ||||
|     private String DOWNLOAD_STORAGE_ASK; | ||||
|  | ||||
|     private Preference prefPathVideo; | ||||
|     private Preference prefPathAudio; | ||||
|     private Preference prefStorageAsk; | ||||
|  | ||||
|     private Context ctx; | ||||
|  | ||||
|     private boolean lastAPIJavaIO; | ||||
|  | ||||
|     @Override | ||||
|     public void onCreate(@Nullable Bundle savedInstanceState) { | ||||
|         super.onCreate(savedInstanceState); | ||||
|  | ||||
|         DOWNLOAD_PATH_VIDEO_PREFERENCE = getString(R.string.download_path_video_key); | ||||
|         DOWNLOAD_PATH_AUDIO_PREFERENCE = getString(R.string.download_path_audio_key); | ||||
|         DOWNLOAD_STORAGE_API = getString(R.string.downloads_storage_api); | ||||
|         DOWNLOAD_STORAGE_API_DEFAULT = getString(R.string.downloads_storage_api_default); | ||||
|         DOWNLOAD_STORAGE_ASK = getString(R.string.downloads_storage_ask); | ||||
|  | ||||
|         prefPathVideo = findPreference(DOWNLOAD_PATH_VIDEO_PREFERENCE); | ||||
|         prefPathAudio = findPreference(DOWNLOAD_PATH_AUDIO_PREFERENCE); | ||||
|  | ||||
|         lastAPIJavaIO = usingJavaIO(); | ||||
|         prefStorageAsk = findPreference(DOWNLOAD_STORAGE_ASK); | ||||
|  | ||||
|         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 (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | ||||
|             prefStorageAsk.setSummary(R.string.downloads_storage_ask_summary); | ||||
|         } | ||||
|  | ||||
|             if (javaIO == lastAPIJavaIO) return true; | ||||
|             lastAPIJavaIO = javaIO; | ||||
|         if (hasInvalidPath(DOWNLOAD_PATH_VIDEO_PREFERENCE) || hasInvalidPath(DOWNLOAD_PATH_AUDIO_PREFERENCE)) { | ||||
|             Toast.makeText(ctx, R.string.download_pick_path, Toast.LENGTH_SHORT).show(); | ||||
|             updatePreferencesSummary(); | ||||
|         } | ||||
|  | ||||
|             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | ||||
|                 boolean res = forgetPath(DOWNLOAD_PATH_VIDEO_PREFERENCE); | ||||
|                 res |= forgetPath(DOWNLOAD_PATH_AUDIO_PREFERENCE); | ||||
|  | ||||
|                 if (res) { | ||||
|                     Toast.makeText(ctx, R.string.download_pick_path, Toast.LENGTH_SHORT).show(); | ||||
|                     updatePreferencesSummary(); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             updatePathPickers(javaIO); | ||||
|         prefStorageAsk.setOnPreferenceChangeListener((preference, value) -> { | ||||
|             updatePathPickers(!(boolean) value); | ||||
|             return true; | ||||
|         }); | ||||
|     } | ||||
| @@ -100,7 +89,7 @@ public class DownloadSettingsFragment extends BasePreferenceFragment { | ||||
|     public void onDetach() { | ||||
|         super.onDetach(); | ||||
|         ctx = null; | ||||
|         findPreference(DOWNLOAD_STORAGE_API).setOnPreferenceChangeListener(null); | ||||
|         prefStorageAsk.setOnPreferenceChangeListener(null); | ||||
|     } | ||||
|  | ||||
|     private void updatePreferencesSummary() { | ||||
| @@ -133,34 +122,18 @@ public class DownloadSettingsFragment extends BasePreferenceFragment { | ||||
|         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) { | ||||
|         return path.charAt(0) == File.separatorChar || path.startsWith(ContentResolver.SCHEME_FILE); | ||||
|     } | ||||
|  | ||||
|     private void updatePathPickers(boolean useJavaIO) { | ||||
|         boolean enabled = useJavaIO || Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; | ||||
|         prefPathVideo.setEnabled(enabled); | ||||
|         prefPathAudio.setEnabled(enabled); | ||||
|     private boolean hasInvalidPath(String prefKey) { | ||||
|         String value = defaultPreferences.getString(prefKey, null); | ||||
|         return value == null || value.isEmpty(); | ||||
|     } | ||||
|  | ||||
|     private boolean usingJavaIO() { | ||||
|         return DOWNLOAD_STORAGE_API_DEFAULT.equals( | ||||
|                 defaultPreferences.getString(DOWNLOAD_STORAGE_API, DOWNLOAD_STORAGE_API_DEFAULT) | ||||
|         ); | ||||
|     private void updatePathPickers(boolean enabled) { | ||||
|         prefPathVideo.setEnabled(enabled); | ||||
|         prefPathAudio.setEnabled(enabled); | ||||
|     } | ||||
|  | ||||
|     // 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(); | ||||
|         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)) { | ||||
|                 request = REQUEST_DOWNLOAD_VIDEO_PATH; | ||||
|             } 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); | ||||
|         if (key.equals(DOWNLOAD_PATH_VIDEO_PREFERENCE)) { | ||||
|             request = REQUEST_DOWNLOAD_VIDEO_PATH; | ||||
|         } else if (key.equals(DOWNLOAD_PATH_AUDIO_PREFERENCE)) { | ||||
|             request = REQUEST_DOWNLOAD_AUDIO_PATH; | ||||
|         } else { | ||||
|             return super.onPreferenceTreeClick(preference); | ||||
|         } | ||||
|  | ||||
|         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 | ||||
| @@ -252,7 +223,7 @@ public class DownloadSettingsFragment extends BasePreferenceFragment { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (!usingJavaIO() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | ||||
|             // steps: | ||||
|             //       1. revoke permissions on the old save path | ||||
|             //       2. acquire permissions on the new save path | ||||
|   | ||||
| @@ -94,24 +94,7 @@ public class NewPipeSettings { | ||||
|         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) { | ||||
|         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.support.annotation.NonNull; | ||||
| import android.support.annotation.Nullable; | ||||
| import android.support.annotation.RequiresApi; | ||||
| import android.support.v4.provider.DocumentFile; | ||||
|  | ||||
| import java.io.File; | ||||
| @@ -33,7 +32,6 @@ public class StoredDirectoryHelper { | ||||
|  | ||||
|     private String tag; | ||||
|  | ||||
|     @RequiresApi(Build.VERSION_CODES.LOLLIPOP) | ||||
|     public StoredDirectoryHelper(@NonNull Context context, @NonNull Uri path, String tag) throws IOException { | ||||
|         this.tag = tag; | ||||
|  | ||||
| @@ -50,6 +48,9 @@ public class StoredDirectoryHelper { | ||||
|             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); | ||||
|  | ||||
|         if (this.docTree == null) | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| package us.shandian.giga.service; | ||||
|  | ||||
| import android.Manifest; | ||||
| import android.app.AlertDialog; | ||||
| import android.app.Notification; | ||||
| import android.app.NotificationManager; | ||||
| import android.app.PendingIntent; | ||||
| import android.app.Service; | ||||
| import android.content.BroadcastReceiver; | ||||
| import android.content.ContentResolver; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.content.IntentFilter; | ||||
| @@ -20,7 +20,6 @@ import android.net.NetworkRequest; | ||||
| import android.net.Uri; | ||||
| import android.os.Binder; | ||||
| import android.os.Build; | ||||
| import android.os.Environment; | ||||
| import android.os.Handler; | ||||
| import android.os.IBinder; | ||||
| import android.os.Looper; | ||||
| @@ -28,6 +27,7 @@ import android.os.Message; | ||||
| import android.preference.PreferenceManager; | ||||
| import android.support.annotation.NonNull; | ||||
| import android.support.annotation.Nullable; | ||||
| import android.support.annotation.StringRes; | ||||
| import android.support.v4.app.NotificationCompat; | ||||
| import android.support.v4.app.NotificationCompat.Builder; | ||||
| import android.support.v4.content.PermissionChecker; | ||||
| @@ -41,7 +41,6 @@ import org.schabi.newpipe.player.helper.LockManager; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.net.URI; | ||||
| import java.util.ArrayList; | ||||
|  | ||||
| import us.shandian.giga.get.DownloadMission; | ||||
| @@ -141,7 +140,7 @@ public class DownloadManagerService extends Service { | ||||
|  | ||||
|         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) | ||||
|                 .setAction(Intent.ACTION_MAIN); | ||||
| @@ -271,6 +270,33 @@ public class DownloadManagerService extends Service { | ||||
|             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; | ||||
|     } | ||||
|  | ||||
| @@ -348,13 +374,10 @@ public class DownloadManagerService extends Service { | ||||
|             mManager.mPrefMeteredDownloads = prefs.getBoolean(key, false); | ||||
|         } else if (key.equals(getString(R.string.downloads_queue_limit))) { | ||||
|             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))) { | ||||
|             mManager.mMainStorageVideo = loadMainStorage(key, DownloadManager.TAG_VIDEO); | ||||
|             mManager.mMainStorageVideo = loadMainVideoStorage(); | ||||
|         } 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 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) { | ||||
|         Intent intent = new Intent(context, DownloadManagerService.class); | ||||
|         intent.setAction(Intent.ACTION_RUN); | ||||
| @@ -538,56 +561,28 @@ public class DownloadManagerService extends Service { | ||||
|         mLockAcquired = acquire; | ||||
|     } | ||||
|  | ||||
|     private StoredDirectoryHelper getVideoStorage() { | ||||
|         return loadMainStorage(getString(R.string.download_path_video_key), DownloadManager.TAG_VIDEO); | ||||
|     private StoredDirectoryHelper loadMainVideoStorage() { | ||||
|         return loadMainStorage(R.string.download_path_video_key, DownloadManager.TAG_VIDEO); | ||||
|     } | ||||
|  | ||||
|     private StoredDirectoryHelper getAudioStorage() { | ||||
|         return loadMainStorage(getString(R.string.download_path_audio_key), DownloadManager.TAG_AUDIO); | ||||
|     private StoredDirectoryHelper loadMainAudioStorage() { | ||||
|         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) { | ||||
|         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 == null || path.isEmpty()) return null; | ||||
|  | ||||
|         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; | ||||
|             path = Uri.fromFile(new File(path)).toString(); | ||||
|             if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) | ||||
|                 path = Uri.fromFile(new File(path)).toString(); | ||||
|             else | ||||
|                 path = ""; | ||||
|  | ||||
|             mPrefs.edit().putString(prefKey, path).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 | ||||
|             mPrefs.edit().putString(getString(prefKey), "").apply(); | ||||
|         } | ||||
|  | ||||
|         try { | ||||
| @@ -619,6 +614,13 @@ public class DownloadManagerService extends Service { | ||||
|             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) { | ||||
|             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_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_pick_path">Seleccione los directorios de descarga</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="tab_new">Nueva 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_search_history_key" translatable="false">clear_search_history</string> | ||||
|  | ||||
|     <string name="downloads_storage_api" translatable="false">downloads_storage_api</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> | ||||
|     <string name="downloads_storage_ask" translatable="false">downloads_storage_ask</string> | ||||
|  | ||||
|     <!-- FileName Downloads  --> | ||||
|     <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="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="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> | ||||
| @@ -5,14 +5,12 @@ | ||||
|     android:title="@string/settings_category_downloads_title"> | ||||
|  | ||||
|  | ||||
|     <ListPreference | ||||
|     <CheckBoxPreference | ||||
|         app:iconSpaceReserved="false" | ||||
|         android:defaultValue="@string/downloads_storage_api_default" | ||||
|         android:entries="@array/downloads_storage_api_description" | ||||
|         android:entryValues="@array/downloads_storage_api_values" | ||||
|         android:key="@string/downloads_storage_api" | ||||
|         android:summary="@string/downloads_storage_desc" | ||||
|         android:title="@string/downloads_storage" /> | ||||
|         android:defaultValue="false" | ||||
|         android:key="@string/downloads_storage_ask" | ||||
|         android:summary="@string/downloads_storage_ask_summary_kitkat" | ||||
|         android:title="@string/downloads_storage_ask_title" /> | ||||
|  | ||||
|     <Preference | ||||
|         app:iconSpaceReserved="false" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 kapodamy
					kapodamy