diff --git a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java index a9afc93d5..f77daa092 100644 --- a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java +++ b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java @@ -329,7 +329,7 @@ public class DownloadDialog extends DialogFragment implements RadioGroup.OnCheck return; } - if (data.getData().getAuthority() != null && data.getData().getAuthority().startsWith(context.getPackageName())) { + if (FilePickerActivityHelper.isOwnFileUri(context, data.getData())) { File file = Utils.getFileForUri(data.getData()); checkSelectedDownload(null, Uri.fromFile(file), file.getName(), StoredFileHelper.DEFAULT_MIME); return; @@ -592,7 +592,7 @@ public class DownloadDialog extends DialogFragment implements RadioGroup.OnCheck if (!askForSavePath) Toast.makeText(context, getString(R.string.no_available_dir), Toast.LENGTH_LONG).show(); - if (NewPipeSettings.hasCreateDocumentSupport) { + if (NewPipeSettings.useStorageAccessFramework(context)) { StoredFileHelper.requestSafWithFileCreation(this, REQUEST_DOWNLOAD_SAVE_AS, filename, mime); } else { File initialSavePath; diff --git a/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java index db7754caf..7c2cb46e9 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java @@ -178,7 +178,7 @@ public class DownloadSettingsFragment extends BasePreferenceFragment { } Intent i; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && NewPipeSettings.hasOpenDocumentTreeSupport) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && NewPipeSettings.useStorageAccessFramework(ctx)) { 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); @@ -226,7 +226,7 @@ public class DownloadSettingsFragment extends BasePreferenceFragment { forgetSAFTree(ctx, defaultPreferences.getString(key, "")); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && NewPipeSettings.hasOpenDocumentTreeSupport) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && !FilePickerActivityHelper.isOwnFileUri(ctx, uri)) { // steps to acquire the selected path: // 1. acquire permissions on the new save path // 2. save the new path, if step(2) was successful @@ -244,7 +244,7 @@ public class DownloadSettingsFragment extends BasePreferenceFragment { return; } } else { - File target = Utils.getFileForUri(data.getData()); + File target = Utils.getFileForUri(uri); if (!target.canWrite()) { showMessageDialog(R.string.download_to_sdcard_error_title, R.string.download_to_sdcard_error_message); return; diff --git a/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java b/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java index 6f26534fb..44da38c35 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java +++ b/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java @@ -21,11 +21,7 @@ package org.schabi.newpipe.settings; import android.content.Context; -import android.content.Intent; import android.content.SharedPreferences; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.os.Build; import android.os.Environment; import android.preference.PreferenceManager; import android.support.annotation.NonNull; @@ -33,7 +29,6 @@ import android.support.annotation.NonNull; import org.schabi.newpipe.R; import java.io.File; -import java.util.List; /** * Helper for global settings @@ -62,20 +57,6 @@ public class NewPipeSettings { private NewPipeSettings() { } - /** - * Indicates if is possible pick a directory though the Storage Access Framework. - * {@code true} if at least one provider can handle {@link Intent#ACTION_OPEN_DOCUMENT_TREE} - * otherwise {@code false} - */ - public static boolean hasOpenDocumentTreeSupport = false; - - /** - * Indicates if is possible create a file though the Storage Access Framework. - * {@code true} if at least one provider can handle {@link Intent#ACTION_CREATE_DOCUMENT} - * otherwise {@code false} - */ - public static boolean hasCreateDocumentSupport = false; - public static void initSettings(Context context) { PreferenceManager.setDefaultValues(context, R.xml.appearance_settings, true); PreferenceManager.setDefaultValues(context, R.xml.content_settings, true); @@ -85,17 +66,8 @@ public class NewPipeSettings { PreferenceManager.setDefaultValues(context, R.xml.video_audio_settings, true); PreferenceManager.setDefaultValues(context, R.xml.debug_settings, true); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - hasOpenDocumentTreeSupport = testFor(context, Intent.ACTION_OPEN_DOCUMENT_TREE, false); - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - hasCreateDocumentSupport = testFor(context, Intent.ACTION_CREATE_DOCUMENT, true); - } - - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP || !hasOpenDocumentTreeSupport) { - getVideoDownloadFolder(context); - getAudioDownloadFolder(context); - } + getVideoDownloadFolder(context); + getAudioDownloadFolder(context); } private static void getVideoDownloadFolder(Context context) { @@ -126,25 +98,11 @@ public class NewPipeSettings { return new File(dir, "NewPipe").toURI().toString(); } - private static boolean testFor(@NonNull Context ctx, @NonNull String intentAction, boolean isFile) { - Intent queryIntent = new Intent(intentAction) - .addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); + public static boolean useStorageAccessFramework(Context context) { + final String key = context.getString(R.string.storage_use_saf); + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - if (isFile) { - queryIntent.setType("*/*"); - queryIntent.addCategory(Intent.CATEGORY_OPENABLE); - } - - List infoList = ctx.getPackageManager() - .queryIntentActivities(queryIntent, PackageManager.MATCH_DEFAULT_ONLY); - - int availableProviders = 0; - for (ResolveInfo info : infoList) { - if (info.activityInfo != null && info.activityInfo.enabled && info.activityInfo.exported) { - availableProviders++; - } - } - - return availableProviders > 0; + return prefs.getBoolean(key, false); } + } diff --git a/app/src/main/java/org/schabi/newpipe/util/FilePickerActivityHelper.java b/app/src/main/java/org/schabi/newpipe/util/FilePickerActivityHelper.java index 20554ce59..8e70e4f8d 100644 --- a/app/src/main/java/org/schabi/newpipe/util/FilePickerActivityHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/FilePickerActivityHelper.java @@ -2,6 +2,7 @@ package org.schabi.newpipe.util; import android.content.Context; import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.support.annotation.NonNull; @@ -29,7 +30,7 @@ public class FilePickerActivityHelper extends com.nononsenseapps.filepicker.File @Override public void onCreate(Bundle savedInstanceState) { - if(ThemeHelper.isLightThemeSelected(this)) { + if (ThemeHelper.isLightThemeSelected(this)) { this.setTheme(R.style.FilePickerThemeLight); } else { this.setTheme(R.style.FilePickerThemeDark); @@ -73,6 +74,11 @@ public class FilePickerActivityHelper extends com.nononsenseapps.filepicker.File .putExtra(FilePickerActivityHelper.EXTRA_MODE, FilePickerActivityHelper.MODE_NEW_FILE); } + public static boolean isOwnFileUri(@NonNull Context context, @NonNull Uri uri) { + if (uri.getAuthority() == null) return false; + return uri.getAuthority().startsWith(context.getPackageName()); + } + /*////////////////////////////////////////////////////////////////////////// // Internal //////////////////////////////////////////////////////////////////////////*/ diff --git a/app/src/main/java/us/shandian/giga/service/DownloadManager.java b/app/src/main/java/us/shandian/giga/service/DownloadManager.java index b168ef474..beb5e6dc9 100644 --- a/app/src/main/java/us/shandian/giga/service/DownloadManager.java +++ b/app/src/main/java/us/shandian/giga/service/DownloadManager.java @@ -35,8 +35,8 @@ public class DownloadManager { public final static int SPECIAL_PENDING = 1; public final static int SPECIAL_FINISHED = 2; - static final String TAG_AUDIO = "audio"; - static final String TAG_VIDEO = "video"; + public static final String TAG_AUDIO = "audio"; + public static final String TAG_VIDEO = "video"; private final FinishedMissionStore mFinishedMissionStore; diff --git a/app/src/main/java/us/shandian/giga/ui/fragment/MissionsFragment.java b/app/src/main/java/us/shandian/giga/ui/fragment/MissionsFragment.java index 69c8e8f50..2b2c09750 100644 --- a/app/src/main/java/us/shandian/giga/ui/fragment/MissionsFragment.java +++ b/app/src/main/java/us/shandian/giga/ui/fragment/MissionsFragment.java @@ -7,7 +7,9 @@ import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.SharedPreferences; +import android.net.Uri; import android.os.Bundle; +import android.os.Environment; import android.os.IBinder; import android.preference.PreferenceManager; import android.support.annotation.NonNull; @@ -22,9 +24,14 @@ import android.view.View; import android.view.ViewGroup; import android.widget.Toast; +import com.nononsenseapps.filepicker.Utils; + import org.schabi.newpipe.R; +import org.schabi.newpipe.settings.NewPipeSettings; +import org.schabi.newpipe.util.FilePickerActivityHelper; import org.schabi.newpipe.util.ThemeHelper; +import java.io.File; import java.io.IOException; import us.shandian.giga.get.DownloadMission; @@ -37,7 +44,7 @@ import us.shandian.giga.ui.adapter.MissionAdapter; public class MissionsFragment extends Fragment { private static final int SPAN_SIZE = 2; - private static final int REQUEST_DOWNLOAD_PATH_SAF = 0x1230; + private static final int REQUEST_DOWNLOAD_SAVE_AS = 0x1230; private SharedPreferences mPrefs; private boolean mLinear; @@ -242,12 +249,28 @@ public class MissionsFragment extends Fragment { private void recoverMission(@NonNull DownloadMission mission) { unsafeMissionTarget = mission; - StoredFileHelper.requestSafWithFileCreation( - MissionsFragment.this, - REQUEST_DOWNLOAD_PATH_SAF, - mission.storage.getName(), - mission.storage.getType() - ); + + if (NewPipeSettings.useStorageAccessFramework(mContext)) { + StoredFileHelper.requestSafWithFileCreation( + MissionsFragment.this, + REQUEST_DOWNLOAD_SAVE_AS, + mission.storage.getName(), + mission.storage.getType() + ); + + } else { + File initialSavePath; + if (DownloadManager.TAG_VIDEO.equals(mission.storage.getType())) + initialSavePath = NewPipeSettings.getDir(Environment.DIRECTORY_MOVIES); + else + initialSavePath = NewPipeSettings.getDir(Environment.DIRECTORY_MUSIC); + + initialSavePath = new File(initialSavePath, mission.storage.getName()); + startActivityForResult( + FilePickerActivityHelper.chooseFileToSave(mContext, initialSavePath.getAbsolutePath()), + REQUEST_DOWNLOAD_SAVE_AS + ); + } } @Override @@ -290,15 +313,20 @@ public class MissionsFragment extends Fragment { public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); - if (requestCode != REQUEST_DOWNLOAD_PATH_SAF || resultCode != Activity.RESULT_OK) return; + if (requestCode != REQUEST_DOWNLOAD_SAVE_AS || resultCode != Activity.RESULT_OK) return; if (unsafeMissionTarget == null || data.getData() == null) { - return;// unsafeMissionTarget cannot be null + return; } try { + Uri fileUri = data.getData(); + if (fileUri.getAuthority() != null && FilePickerActivityHelper.isOwnFileUri(mContext, fileUri)) { + fileUri = Uri.fromFile(Utils.getFileForUri(fileUri)); + } + String tag = unsafeMissionTarget.storage.getTag(); - unsafeMissionTarget.storage = new StoredFileHelper(mContext, null, data.getData(), tag); + unsafeMissionTarget.storage = new StoredFileHelper(mContext, null, fileUri, tag); mAdapter.recoverMission(unsafeMissionTarget); } catch (IOException e) { Toast.makeText(mContext, R.string.general_error, Toast.LENGTH_LONG).show(); diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index fcc5afda9..028f146fc 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -458,7 +458,9 @@ abrir en modo popup Preguntar dónde descargar Se preguntará dónde guardar cada descarga - Se preguntará dónde guardar cada descarga.\nHabilita esta opción si quieres descargar en la tarjeta SD externa + Se preguntará dónde guardar cada descarga.\nHabilita esta opción junto con SAF si quieres descargar en la tarjeta SD externa + Usar SAF + El Framework de Acceso al Almacenamiento permite descargar en la tarjeta SD externa.\nNota: Algunos los dispositivos no son compatibles Desuscribirse Nueva pestaña diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 49f38b667..6c51fbb1c 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -163,6 +163,7 @@ clear_search_history downloads_storage_ask + storage_use_saf file_rename_charset diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 91b0953cc..721fbcac4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -556,6 +556,8 @@ Ask where to download You will be asked where to save each download - You will be asked where to save each download.\nEnable this option if you want download to the external SD Card + You will be asked where to save each download.\nEnable this option with SAF if you want download to the external SD Card + Use SAF + The Storage Access Framework allow download to the external SD Card.\nNote: some devices are not compatible diff --git a/app/src/main/res/xml/download_settings.xml b/app/src/main/res/xml/download_settings.xml index 7a6fab841..0df021842 100644 --- a/app/src/main/res/xml/download_settings.xml +++ b/app/src/main/res/xml/download_settings.xml @@ -12,6 +12,13 @@ android:summary="@string/downloads_storage_ask_summary_kitkat" android:title="@string/downloads_storage_ask_title" /> + +