feat: implemented the ability to choose external storage (if available) as storage for offline file downloads

This commit is contained in:
antonio 2023-08-04 23:46:33 +02:00
parent 838d4496e5
commit 5733dca68a
9 changed files with 214 additions and 9 deletions

View file

@ -0,0 +1,13 @@
package com.cappielloantonio.tempo.interfaces;
import androidx.annotation.Keep;
@Keep
public interface DialogClickCallback {
default void onPositiveClick() {}
default void onNegativeClick() {}
default void onNeutralClick() {}
}

View file

@ -89,6 +89,7 @@ public class DownloaderManager {
public void remove(MediaItem mediaItem, com.cappielloantonio.tempo.model.Download download) {
DownloadService.sendRemoveDownload(context, DownloaderService.class, buildDownloadRequest(mediaItem).id, false);
deleteDatabase(download.getId());
}
public void remove(List<MediaItem> mediaItems, List<com.cappielloantonio.tempo.model.Download> downloads) {
@ -97,6 +98,11 @@ public class DownloaderManager {
}
}
public void removeAll() {
DownloadService.sendRemoveAllDownloads(context, DownloaderService.class, false);
deleteAllDatabase();
}
private void loadDownloads() {
try (DownloadCursor loadedDownloads = downloadIndex.getDownloads()) {
while (loadedDownloads.moveToNext()) {
@ -125,6 +131,10 @@ public class DownloaderManager {
getDownloadRepository().delete(id);
}
public static void deleteAllDatabase() {
getDownloadRepository().deleteAll();
}
public static void updateDatabase(String id) {
getDownloadRepository().update(id);
}

View file

@ -0,0 +1,89 @@
package com.cappielloantonio.tempo.ui.dialog;
import android.app.AlertDialog;
import android.app.Dialog;
import android.os.Bundle;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.annotation.OptIn;
import androidx.fragment.app.DialogFragment;
import androidx.media3.common.util.UnstableApi;
import com.cappielloantonio.tempo.R;
import com.cappielloantonio.tempo.databinding.DialogDownloadStorageBinding;
import com.cappielloantonio.tempo.interfaces.DialogClickCallback;
import com.cappielloantonio.tempo.util.DownloadUtil;
import com.cappielloantonio.tempo.util.Preferences;
@OptIn(markerClass = UnstableApi.class)
public class DownloadStorageDialog extends DialogFragment {
private DialogDownloadStorageBinding bind;
private final DialogClickCallback dialogClickCallback;
public DownloadStorageDialog(DialogClickCallback dialogClickCallback) {
this.dialogClickCallback = dialogClickCallback;
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
bind = DialogDownloadStorageBinding.inflate(getLayoutInflater());
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(bind.getRoot())
.setTitle(R.string.download_storage_dialog_title)
.setPositiveButton(R.string.download_storage_external_dialog_positive_button, null)
.setNegativeButton(R.string.download_storage_internal_dialog_negative_button, null);
return builder.create();
}
@Override
public void onResume() {
super.onResume();
setButtonAction();
}
@Override
public void onDestroyView() {
super.onDestroyView();
bind = null;
}
private void setButtonAction() {
AlertDialog dialog = ((AlertDialog) getDialog());
if (dialog != null) {
Button positiveButton = dialog.getButton(Dialog.BUTTON_POSITIVE);
positiveButton.setOnClickListener(v -> {
int currentPreference = Preferences.getDownloadStoragePreference();
int newPreference = 1;
if (currentPreference != newPreference) {
Preferences.setDownloadStoragePreference(newPreference);
DownloadUtil.getDownloadTracker(requireContext()).removeAll();
dialogClickCallback.onPositiveClick();
}
dialog.dismiss();
});
Button negativeButton = dialog.getButton(Dialog.BUTTON_NEGATIVE);
negativeButton.setOnClickListener(v -> {
int currentPreference = Preferences.getDownloadStoragePreference();
int newPreference = 0;
if (currentPreference != newPreference) {
Preferences.setDownloadStoragePreference(newPreference);
DownloadUtil.getDownloadTracker(requireContext()).removeAll();
dialogClickCallback.onNegativeClick();
}
dialog.dismiss();
});
}
}
}

View file

@ -21,8 +21,10 @@ import androidx.preference.PreferenceFragmentCompat;
import com.cappielloantonio.tempo.BuildConfig;
import com.cappielloantonio.tempo.R;
import com.cappielloantonio.tempo.helper.ThemeHelper;
import com.cappielloantonio.tempo.interfaces.DialogClickCallback;
import com.cappielloantonio.tempo.interfaces.ScanCallback;
import com.cappielloantonio.tempo.ui.activity.MainActivity;
import com.cappielloantonio.tempo.ui.dialog.DownloadStorageDialog;
import com.cappielloantonio.tempo.ui.dialog.StarredSyncDialog;
import com.cappielloantonio.tempo.util.Preferences;
import com.cappielloantonio.tempo.viewmodel.SettingViewModel;
@ -73,6 +75,8 @@ public class SettingsFragment extends PreferenceFragmentCompat {
checkEqualizer();
checkStorage();
findPreference("version").setSummary(BuildConfig.VERSION_NAME);
findPreference("logout").setOnPreferenceClickListener(preference -> {
@ -105,6 +109,22 @@ public class SettingsFragment extends PreferenceFragmentCompat {
}
return true;
});
findPreference("download_storage").setOnPreferenceClickListener(preference -> {
DownloadStorageDialog dialog = new DownloadStorageDialog(new DialogClickCallback() {
@Override
public void onPositiveClick() {
findPreference("download_storage").setSummary(R.string.download_storage_external_dialog_positive_button);
}
@Override
public void onNegativeClick() {
findPreference("download_storage").setSummary(R.string.download_storage_internal_dialog_negative_button);
}
});
dialog.show(activity.getSupportFragmentManager(), null);
return true;
});
}
@Override
@ -144,6 +164,22 @@ public class SettingsFragment extends PreferenceFragmentCompat {
}
}
private void checkStorage() {
Preference storage = findPreference("download_storage");
if (storage == null) return;
try {
if (requireContext().getExternalFilesDirs(null)[1] == null) {
storage.setVisible(false);
} else {
storage.setSummary(Preferences.getDownloadStoragePreference() == 0 ? R.string.download_storage_internal_dialog_negative_button : R.string.download_storage_external_dialog_positive_button);
}
} catch (Exception exception) {
storage.setVisible(false);
}
}
private void getScanStatus() {
settingViewModel.getScanStatus(new ScanCallback() {
@Override

View file

@ -127,9 +127,19 @@ public final class DownloadUtil {
private static synchronized File getDownloadDirectory(Context context) {
if (downloadDirectory == null) {
downloadDirectory = context.getExternalFilesDir(null);
if (downloadDirectory == null) {
downloadDirectory = context.getFilesDir();
if (Preferences.getDownloadStoragePreference() == 0) {
downloadDirectory = context.getExternalFilesDirs(null)[0];
if (downloadDirectory == null) {
downloadDirectory = context.getFilesDir();
}
} else {
try {
downloadDirectory = context.getExternalFilesDirs(null)[1];
} catch (Exception exception) {
downloadDirectory = context.getExternalFilesDirs(null)[0];
Preferences.setDownloadStoragePreference(0);
}
}
}

View file

@ -33,6 +33,7 @@ object Preferences {
private const val MUSIC_DIRECTORY_SECTION_VISIBILITY = "music_directory_section_visibility"
private const val REPLAY_GAIN_MODE = "replay_gain_mode"
private const val AUDIO_TRANSCODE_PRIORITY = "audio_transcode_priority"
private const val DOWNLOAD_STORAGE = "download_storage"
@JvmStatic
fun getServer(): String? {
@ -258,4 +259,17 @@ object Preferences {
fun isServerPrioritized(): Boolean {
return App.getInstance().preferences.getBoolean(AUDIO_TRANSCODE_PRIORITY, false)
}
@JvmStatic
fun getDownloadStoragePreference(): Int {
return App.getInstance().preferences.getString(DOWNLOAD_STORAGE, "0")!!.toInt()
}
@JvmStatic
fun setDownloadStoragePreference(storagePreference: Int) {
return App.getInstance().preferences.edit().putString(
DOWNLOAD_STORAGE,
storagePreference.toString()
).apply()
}
}