mirror of
https://github.com/antebudimir/tempus.git
synced 2025-12-31 17:43:32 +00:00
feat: added external memory cache option
This commit is contained in:
parent
c4e8fe5261
commit
477331da6f
7 changed files with 188 additions and 4 deletions
|
|
@ -0,0 +1,76 @@
|
||||||
|
package com.cappielloantonio.tempo.ui.dialog;
|
||||||
|
|
||||||
|
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.DialogStreamingCacheStorageBinding;
|
||||||
|
import com.cappielloantonio.tempo.interfaces.DialogClickCallback;
|
||||||
|
import com.cappielloantonio.tempo.util.Preferences;
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
|
@OptIn(markerClass = UnstableApi.class)
|
||||||
|
public class StreamingCacheStorageDialog extends DialogFragment {
|
||||||
|
private final DialogClickCallback dialogClickCallback;
|
||||||
|
|
||||||
|
public StreamingCacheStorageDialog(DialogClickCallback dialogClickCallback) {
|
||||||
|
this.dialogClickCallback = dialogClickCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
DialogStreamingCacheStorageBinding bind = DialogStreamingCacheStorageBinding.inflate(getLayoutInflater());
|
||||||
|
|
||||||
|
return new MaterialAlertDialogBuilder(getActivity())
|
||||||
|
.setView(bind.getRoot())
|
||||||
|
.setTitle(R.string.streaming_cache_storage_dialog_title)
|
||||||
|
.setPositiveButton(R.string.streaming_cache_storage_external_dialog_positive_button, null)
|
||||||
|
.setNegativeButton(R.string.streaming_cache_storage_internal_dialog_negative_button, null)
|
||||||
|
.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
setButtonAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setButtonAction() {
|
||||||
|
androidx.appcompat.app.AlertDialog dialog = (androidx.appcompat.app.AlertDialog) getDialog();
|
||||||
|
|
||||||
|
if (dialog != null) {
|
||||||
|
Button positiveButton = dialog.getButton(Dialog.BUTTON_POSITIVE);
|
||||||
|
positiveButton.setOnClickListener(v -> {
|
||||||
|
int currentPreference = Preferences.getStreamingCacheStoragePreference();
|
||||||
|
int newPreference = 1;
|
||||||
|
|
||||||
|
if (currentPreference != newPreference) {
|
||||||
|
Preferences.setStreamingCacheStoragePreference(newPreference);
|
||||||
|
dialogClickCallback.onPositiveClick();
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.dismiss();
|
||||||
|
});
|
||||||
|
|
||||||
|
Button negativeButton = dialog.getButton(Dialog.BUTTON_NEGATIVE);
|
||||||
|
negativeButton.setOnClickListener(v -> {
|
||||||
|
int currentPreference = Preferences.getStreamingCacheStoragePreference();
|
||||||
|
int newPreference = 0;
|
||||||
|
|
||||||
|
if (currentPreference != newPreference) {
|
||||||
|
Preferences.setStreamingCacheStoragePreference(newPreference);
|
||||||
|
dialogClickCallback.onNegativeClick();
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.dismiss();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ package com.cappielloantonio.tempo.ui.fragment;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.media.audiofx.AudioEffect;
|
import android.media.audiofx.AudioEffect;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
@ -30,8 +31,8 @@ import com.cappielloantonio.tempo.ui.activity.MainActivity;
|
||||||
import com.cappielloantonio.tempo.ui.dialog.DeleteDownloadStorageDialog;
|
import com.cappielloantonio.tempo.ui.dialog.DeleteDownloadStorageDialog;
|
||||||
import com.cappielloantonio.tempo.ui.dialog.DownloadStorageDialog;
|
import com.cappielloantonio.tempo.ui.dialog.DownloadStorageDialog;
|
||||||
import com.cappielloantonio.tempo.ui.dialog.StarredSyncDialog;
|
import com.cappielloantonio.tempo.ui.dialog.StarredSyncDialog;
|
||||||
|
import com.cappielloantonio.tempo.ui.dialog.StreamingCacheStorageDialog;
|
||||||
import com.cappielloantonio.tempo.util.DownloadUtil;
|
import com.cappielloantonio.tempo.util.DownloadUtil;
|
||||||
import com.cappielloantonio.tempo.util.MusicUtil;
|
|
||||||
import com.cappielloantonio.tempo.util.Preferences;
|
import com.cappielloantonio.tempo.util.Preferences;
|
||||||
import com.cappielloantonio.tempo.util.UIUtil;
|
import com.cappielloantonio.tempo.util.UIUtil;
|
||||||
import com.cappielloantonio.tempo.viewmodel.SettingViewModel;
|
import com.cappielloantonio.tempo.viewmodel.SettingViewModel;
|
||||||
|
|
@ -84,6 +85,7 @@ public class SettingsFragment extends PreferenceFragmentCompat {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
checkEqualizer();
|
checkEqualizer();
|
||||||
|
checkCacheStorage();
|
||||||
checkStorage();
|
checkStorage();
|
||||||
|
|
||||||
setStreamingCacheSize();
|
setStreamingCacheSize();
|
||||||
|
|
@ -93,6 +95,7 @@ public class SettingsFragment extends PreferenceFragmentCompat {
|
||||||
actionLogout();
|
actionLogout();
|
||||||
actionScan();
|
actionScan();
|
||||||
actionSyncStarredTracks();
|
actionSyncStarredTracks();
|
||||||
|
actionChangeStreamingCacheStorage();
|
||||||
actionChangeDownloadStorage();
|
actionChangeDownloadStorage();
|
||||||
actionDeleteDownloadStorage();
|
actionDeleteDownloadStorage();
|
||||||
actionKeepScreenOn();
|
actionKeepScreenOn();
|
||||||
|
|
@ -135,6 +138,22 @@ public class SettingsFragment extends PreferenceFragmentCompat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkCacheStorage() {
|
||||||
|
Preference storage = findPreference("streaming_cache_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 checkStorage() {
|
private void checkStorage() {
|
||||||
Preference storage = findPreference("download_storage");
|
Preference storage = findPreference("download_storage");
|
||||||
|
|
||||||
|
|
@ -213,7 +232,8 @@ public class SettingsFragment extends PreferenceFragmentCompat {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(boolean isScanning, long count) {
|
public void onSuccess(boolean isScanning, long count) {
|
||||||
getScanStatus();
|
findPreference("scan_library").setSummary("Scanning: counting " + count + " tracks");
|
||||||
|
if (isScanning) getScanStatus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -233,6 +253,24 @@ public class SettingsFragment extends PreferenceFragmentCompat {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void actionChangeStreamingCacheStorage() {
|
||||||
|
findPreference("streaming_cache_storage").setOnPreferenceClickListener(preference -> {
|
||||||
|
StreamingCacheStorageDialog dialog = new StreamingCacheStorageDialog(new DialogClickCallback() {
|
||||||
|
@Override
|
||||||
|
public void onPositiveClick() {
|
||||||
|
findPreference("streaming_cache_storage").setSummary(R.string.streaming_cache_storage_external_dialog_positive_button);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNegativeClick() {
|
||||||
|
findPreference("streaming_cache_storage").setSummary(R.string.streaming_cache_storage_internal_dialog_negative_button);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dialog.show(activity.getSupportFragmentManager(), null);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void actionChangeDownloadStorage() {
|
private void actionChangeDownloadStorage() {
|
||||||
findPreference("download_storage").setOnPreferenceClickListener(preference -> {
|
findPreference("download_storage").setOnPreferenceClickListener(preference -> {
|
||||||
DownloadStorageDialog dialog = new DownloadStorageDialog(new DialogClickCallback() {
|
DownloadStorageDialog dialog = new DownloadStorageDialog(new DialogClickCallback() {
|
||||||
|
|
|
||||||
|
|
@ -38,11 +38,13 @@ public final class DownloadUtil {
|
||||||
public static final String DOWNLOAD_NOTIFICATION_SUCCESSFUL_GROUP = "com.cappielloantonio.tempo.SuccessfulDownload";
|
public static final String DOWNLOAD_NOTIFICATION_SUCCESSFUL_GROUP = "com.cappielloantonio.tempo.SuccessfulDownload";
|
||||||
public static final String DOWNLOAD_NOTIFICATION_FAILED_GROUP = "com.cappielloantonio.tempo.FailedDownload";
|
public static final String DOWNLOAD_NOTIFICATION_FAILED_GROUP = "com.cappielloantonio.tempo.FailedDownload";
|
||||||
|
|
||||||
|
private static final String STREAMING_CACHE_CONTENT_DIRECTORY = "streaming_cache";
|
||||||
private static final String DOWNLOAD_CONTENT_DIRECTORY = "downloads";
|
private static final String DOWNLOAD_CONTENT_DIRECTORY = "downloads";
|
||||||
|
|
||||||
private static DataSource.Factory dataSourceFactory;
|
private static DataSource.Factory dataSourceFactory;
|
||||||
private static DataSource.Factory httpDataSourceFactory;
|
private static DataSource.Factory httpDataSourceFactory;
|
||||||
private static DatabaseProvider databaseProvider;
|
private static DatabaseProvider databaseProvider;
|
||||||
|
private static File streamingCacheDirectory;
|
||||||
private static File downloadDirectory;
|
private static File downloadDirectory;
|
||||||
private static Cache downloadCache;
|
private static Cache downloadCache;
|
||||||
private static SimpleCache streamingCache;
|
private static SimpleCache streamingCache;
|
||||||
|
|
@ -135,7 +137,7 @@ public final class DownloadUtil {
|
||||||
|
|
||||||
private static synchronized SimpleCache getStreamingCache(Context context) {
|
private static synchronized SimpleCache getStreamingCache(Context context) {
|
||||||
if (streamingCache == null) {
|
if (streamingCache == null) {
|
||||||
File streamingCacheDirectory = new File(context.getCacheDir(), "streamingCache");
|
File streamingCacheDirectory = new File(getStreamingCacheDirectory(context), STREAMING_CACHE_CONTENT_DIRECTORY);
|
||||||
|
|
||||||
streamingCache = new SimpleCache(
|
streamingCache = new SimpleCache(
|
||||||
streamingCacheDirectory,
|
streamingCacheDirectory,
|
||||||
|
|
@ -169,6 +171,27 @@ public final class DownloadUtil {
|
||||||
return databaseProvider;
|
return databaseProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static synchronized File getStreamingCacheDirectory(Context context) {
|
||||||
|
if (streamingCacheDirectory == null) {
|
||||||
|
if (Preferences.getStreamingCacheStoragePreference() == 0) {
|
||||||
|
streamingCacheDirectory = context.getExternalFilesDirs(null)[0];
|
||||||
|
if (streamingCacheDirectory == null) {
|
||||||
|
streamingCacheDirectory = context.getFilesDir();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
streamingCacheDirectory = context.getExternalFilesDirs(null)[1];
|
||||||
|
} catch (Exception exception) {
|
||||||
|
streamingCacheDirectory = context.getExternalFilesDirs(null)[0];
|
||||||
|
Preferences.setStreamingCacheStoragePreference(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return streamingCacheDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
private static synchronized File getDownloadDirectory(Context context) {
|
private static synchronized File getDownloadDirectory(Context context) {
|
||||||
if (downloadDirectory == null) {
|
if (downloadDirectory == null) {
|
||||||
if (Preferences.getDownloadStoragePreference() == 0) {
|
if (Preferences.getDownloadStoragePreference() == 0) {
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ object Preferences {
|
||||||
private const val MUSIC_DIRECTORY_SECTION_VISIBILITY = "music_directory_section_visibility"
|
private const val MUSIC_DIRECTORY_SECTION_VISIBILITY = "music_directory_section_visibility"
|
||||||
private const val REPLAY_GAIN_MODE = "replay_gain_mode"
|
private const val REPLAY_GAIN_MODE = "replay_gain_mode"
|
||||||
private const val AUDIO_TRANSCODE_PRIORITY = "audio_transcode_priority"
|
private const val AUDIO_TRANSCODE_PRIORITY = "audio_transcode_priority"
|
||||||
|
private const val STREAMING_CACHE_STORAGE = "streaming_cache_storage"
|
||||||
private const val DOWNLOAD_STORAGE = "download_storage"
|
private const val DOWNLOAD_STORAGE = "download_storage"
|
||||||
private const val DEFAULT_DOWNLOAD_VIEW_TYPE = "default_download_view_type"
|
private const val DEFAULT_DOWNLOAD_VIEW_TYPE = "default_download_view_type"
|
||||||
private const val AUDIO_TRANSCODE_DOWNLOAD = "audio_transcode_download"
|
private const val AUDIO_TRANSCODE_DOWNLOAD = "audio_transcode_download"
|
||||||
|
|
@ -310,6 +311,19 @@ object Preferences {
|
||||||
return App.getInstance().preferences.getBoolean(AUDIO_TRANSCODE_PRIORITY, false)
|
return App.getInstance().preferences.getBoolean(AUDIO_TRANSCODE_PRIORITY, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getStreamingCacheStoragePreference(): Int {
|
||||||
|
return App.getInstance().preferences.getString(STREAMING_CACHE_STORAGE, "0")!!.toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun setStreamingCacheStoragePreference(streamingCachePreference: Int) {
|
||||||
|
return App.getInstance().preferences.edit().putString(
|
||||||
|
STREAMING_CACHE_STORAGE,
|
||||||
|
streamingCachePreference.toString()
|
||||||
|
).apply()
|
||||||
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getDownloadStoragePreference(): Int {
|
fun getDownloadStoragePreference(): Int {
|
||||||
return App.getInstance().preferences.getString(DOWNLOAD_STORAGE, "0")!!.toInt()
|
return App.getInstance().preferences.getString(DOWNLOAD_STORAGE, "0")!!.toInt()
|
||||||
|
|
|
||||||
23
app/src/main/res/layout/dialog_streaming_cache_storage.xml
Normal file
23
app/src/main/res/layout/dialog_streaming_cache_storage.xml
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="24dp"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:layout_marginEnd="24dp"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:text="@string/streaming_cache_storage_dialog_summary" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="24dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginEnd="24dp"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:text="@string/streaming_cache_storage_dialog_sub_summary" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
@ -289,8 +289,9 @@
|
||||||
<string name="settings_scan_title">Scan library</string>
|
<string name="settings_scan_title">Scan library</string>
|
||||||
<string name="settings_scrobble_title">Enable music scrobbling</string>
|
<string name="settings_scrobble_title">Enable music scrobbling</string>
|
||||||
<string name="settings_share_title">Enable music sharing</string>
|
<string name="settings_share_title">Enable music sharing</string>
|
||||||
<string name="settings_sub_summary_scrobble">It\'s important to note that scrobbling also relies on the server being enabled to receive this data.</string>
|
|
||||||
<string name="settings_streaming_cache_size">Size of streaming cache</string>
|
<string name="settings_streaming_cache_size">Size of streaming cache</string>
|
||||||
|
<string name="settings_streaming_cache_storage_title">Streaming cache storage</string>
|
||||||
|
<string name="settings_sub_summary_scrobble">It\'s important to note that scrobbling also relies on the server being enabled to receive this data.</string>
|
||||||
<string name="settings_summary_skip_min_star_rating">When listening to an artist\'s radio, an instant mix or when shuffling all, tracks below a certain user rating will be ignored.</string>
|
<string name="settings_summary_skip_min_star_rating">When listening to an artist\'s radio, an instant mix or when shuffling all, tracks below a certain user rating will be ignored.</string>
|
||||||
<string name="settings_summary_replay_gain">Replay gain is a feature that allows you to adjust the volume level of audio tracks for a consistent listening experience. This setting is only effective if the track contains the necessary metadata.</string>
|
<string name="settings_summary_replay_gain">Replay gain is a feature that allows you to adjust the volume level of audio tracks for a consistent listening experience. This setting is only effective if the track contains the necessary metadata.</string>
|
||||||
<string name="settings_summary_scrobble">Scrobbling is a feature that allows your device to send information about the songs you listen to the music server. This information helps create personalized recommendations based on your music preferences.</string>
|
<string name="settings_summary_scrobble">Scrobbling is a feature that allows your device to send information about the songs you listen to the music server. This information helps create personalized recommendations based on your music preferences.</string>
|
||||||
|
|
@ -355,6 +356,11 @@
|
||||||
<string name="starred_sync_dialog_positive_button">Continue and download</string>
|
<string name="starred_sync_dialog_positive_button">Continue and download</string>
|
||||||
<string name="starred_sync_dialog_summary">Downloading starry tracks may require a large amount of data.</string>
|
<string name="starred_sync_dialog_summary">Downloading starry tracks may require a large amount of data.</string>
|
||||||
<string name="starred_sync_dialog_title">Sync starred tracks</string>
|
<string name="starred_sync_dialog_title">Sync starred tracks</string>
|
||||||
|
<string name="streaming_cache_storage_dialog_sub_summary">For the changes to take effect, restart the app.</string>
|
||||||
|
<string name="streaming_cache_storage_dialog_summary">Changing the destination of cached files from one storage to another may result in the deletion of any previously cached files in the other storage.</string>
|
||||||
|
<string name="streaming_cache_storage_dialog_title">Select storage option</string>
|
||||||
|
<string name="streaming_cache_storage_external_dialog_positive_button">External</string>
|
||||||
|
<string name="streaming_cache_storage_internal_dialog_negative_button">Internal</string>
|
||||||
<string name="track_info_album">Album</string>
|
<string name="track_info_album">Album</string>
|
||||||
<string name="track_info_artist">Artist</string>
|
<string name="track_info_artist">Artist</string>
|
||||||
<string name="track_info_bitrate">Bitrate</string>
|
<string name="track_info_bitrate">Bitrate</string>
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,10 @@
|
||||||
app:summary="@string/settings_buffering_strategy_summary"
|
app:summary="@string/settings_buffering_strategy_summary"
|
||||||
app:useSimpleSummaryProvider="false" />
|
app:useSimpleSummaryProvider="false" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="streaming_cache_storage"
|
||||||
|
app:title="@string/settings_streaming_cache_storage_title" />
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
android:key="download_storage"
|
android:key="download_storage"
|
||||||
app:title="@string/settings_download_storage_title" />
|
app:title="@string/settings_download_storage_title" />
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue