diff options
author | Tom Hennen <TomHennen@users.noreply.github.com> | 2016-02-06 11:19:13 -0500 |
---|---|---|
committer | Tom Hennen <TomHennen@users.noreply.github.com> | 2016-02-06 11:19:13 -0500 |
commit | 6e6a452a4d42ed7528b1d9d708bb5b171263ceb9 (patch) | |
tree | c4c3759c743992de1a31256ca724f5c6321f0b1c /app/src | |
parent | 4f70ff15633c8e508fb9ef180b8682c0209df45b (diff) | |
parent | 15a1c3e9f8d57acf8a4f60f8d382c722b22e25bc (diff) | |
download | AntennaPod-6e6a452a4d42ed7528b1d9d708bb5b171263ceb9.zip |
Merge pull request #1639 from mfietz/issue/975-no-external-storage
No external storage / Choose Data Folder redo
Diffstat (limited to 'app/src')
5 files changed, 425 insertions, 289 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/DirectoryChooserActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/DirectoryChooserActivity.java index 25dc64232..62e85120d 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/DirectoryChooserActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/DirectoryChooserActivity.java @@ -6,8 +6,8 @@ import android.os.Bundle; import android.os.Environment; import android.os.FileObserver; import android.support.v4.app.NavUtils; -import android.support.v7.app.ActionBarActivity; import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; @@ -34,7 +34,8 @@ import de.danoeh.antennapod.core.preferences.UserPreferences; * Let's the user choose a directory on the storage device. The selected folder * will be sent back to the starting activity as an activity result. */ -public class DirectoryChooserActivity extends ActionBarActivity { +public class DirectoryChooserActivity extends AppCompatActivity { + private static final String TAG = "DirectoryChooserActivit"; private static final String CREATE_DIRECTORY_NAME = "AntennaPod"; @@ -250,8 +251,7 @@ public class DirectoryChooserActivity extends ActionBarActivity { @Override public boolean onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); - menu.findItem(R.id.new_folder_item) - .setVisible(isValidFile(selectedDir)); + menu.findItem(R.id.new_folder_item).setVisible(isValidFile(selectedDir)); return true; } @@ -333,4 +333,5 @@ public class DirectoryChooserActivity extends ActionBarActivity { private boolean isValidFile(File file) { return file != null && file.isDirectory() && file.canRead() && file.canWrite(); } + } diff --git a/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java index b02e82f0b..e980764ec 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java @@ -1,30 +1,109 @@ package de.danoeh.antennapod.activity; +import android.Manifest; +import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.os.Build; import android.os.Bundle; -import android.support.v7.app.ActionBarActivity; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.text.Html; import android.text.TextUtils; import android.util.Log; +import android.widget.Button; + +import com.afollestad.materialdialogs.MaterialDialog; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; -import de.danoeh.antennapod.BuildConfig; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.preferences.UserPreferences; +import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.StorageUtils; /** Is show if there is now external storage available. */ -public class StorageErrorActivity extends ActionBarActivity { +public class StorageErrorActivity extends AppCompatActivity { + private static final String TAG = "StorageErrorActivity"; + private static final String[] EXTERNAL_STORAGE_PERMISSIONS = { + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE }; + private static final int PERMISSION_REQUEST_EXTERNAL_STORAGE = 42; + @Override protected void onCreate(Bundle savedInstanceState) { setTheme(UserPreferences.getTheme()); super.onCreate(savedInstanceState); setContentView(R.layout.storage_error); - } + + Button btnChooseDataFolder = (Button) findViewById(R.id.btnChooseDataFolder); + btnChooseDataFolder.setOnClickListener(v -> { + if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT && + Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) { + showChooseDataFolderDialog(); + } else { + openDirectoryChooser(); + } + }); + if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) { + int readPermission = ActivityCompat.checkSelfPermission(this, + Manifest.permission.READ_EXTERNAL_STORAGE); + int writePermission = ActivityCompat.checkSelfPermission(this, + Manifest.permission.WRITE_EXTERNAL_STORAGE); + if (readPermission != PackageManager.PERMISSION_GRANTED || + writePermission != PackageManager.PERMISSION_GRANTED) { + requestPermission(); + } + } + } + + private void requestPermission() { + ActivityCompat.requestPermissions(this, EXTERNAL_STORAGE_PERMISSIONS, + PERMISSION_REQUEST_EXTERNAL_STORAGE); + } + + private void openDirectoryChooser() { + Intent intent = new Intent(this, DirectoryChooserActivity.class); + startActivityForResult(intent, DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED); + } + + @Override + public void onRequestPermissionsResult(int requestCode, + String[] permissions, + int[] grantResults) { + if (requestCode != PERMISSION_REQUEST_EXTERNAL_STORAGE || grantResults.length != 2) { + return; + } + if (grantResults[0] != PackageManager.PERMISSION_GRANTED || + grantResults[1] != PackageManager.PERMISSION_GRANTED) { + new MaterialDialog.Builder(this) + .content(R.string.choose_data_directory_permission_rationale) + .positiveText(android.R.string.ok) + .onPositive((dialog, which) -> requestPermission()) + .onNegative((dialog, which) -> finish()) + .show(); + } + } + + @Override + protected void onResume() { + super.onResume(); + if (StorageUtils.storageAvailable()) { + leaveErrorState(); + } else { + registerReceiver(mediaUpdate, new IntentFilter(Intent.ACTION_MEDIA_MOUNTED)); + } + } @Override protected void onPause() { @@ -32,18 +111,102 @@ public class StorageErrorActivity extends ActionBarActivity { try { unregisterReceiver(mediaUpdate); } catch (IllegalArgumentException e) { - + Log.e(TAG, Log.getStackTraceString(e)); } } - @Override - protected void onResume() { - super.onResume(); - if (StorageUtils.storageAvailable()) { - leaveErrorState(); - } else { - registerReceiver(mediaUpdate, new IntentFilter( - Intent.ACTION_MEDIA_MOUNTED)); + // see PreferenceController.showChooseDataFolderDialog() + private void showChooseDataFolderDialog() { + File dataFolder = UserPreferences.getDataFolder(null); + if(dataFolder == null) { + new MaterialDialog.Builder(this) + .title(R.string.error_label) + .content(R.string.external_storage_error_msg) + .neutralText(android.R.string.ok) + .show(); + return; + } + String dataFolderPath = dataFolder.getAbsolutePath(); + int selectedIndex = -1; + File[] mediaDirs = ContextCompat.getExternalFilesDirs(this, null); + List<String> folders = new ArrayList<>(mediaDirs.length); + List<CharSequence> choices = new ArrayList<>(mediaDirs.length); + for(int i=0; i < mediaDirs.length; i++) { + if(mediaDirs[i] == null) { + continue; + } + String path = mediaDirs[i].getAbsolutePath(); + folders.add(path); + if(dataFolderPath.equals(path)) { + selectedIndex = i; + } + int index = path.indexOf("Android"); + String choice; + if(index >= 0) { + choice = path.substring(0, index); + } else { + choice = path; + } + long bytes = StorageUtils.getFreeSpaceAvailable(path); + String freeSpace = String.format(getString(R.string.free_space_label), + Converter.byteToString(bytes)); + choices.add(Html.fromHtml("<html><small>" + choice + " [" + freeSpace + "]" + + "</small></html>")); + } + if(choices.size() == 0) { + new MaterialDialog.Builder(this) + .title(R.string.error_label) + .content(R.string.external_storage_error_msg) + .neutralText(android.R.string.ok) + .show(); + return; + } + MaterialDialog dialog = new MaterialDialog.Builder(this) + .title(R.string.choose_data_directory) + .content(R.string.choose_data_directory_message) + .items(choices.toArray(new CharSequence[choices.size()])) + .itemsCallbackSingleChoice(selectedIndex, (dialog1, itemView, which, text) -> { + String folder = folders.get(which); + UserPreferences.setDataFolder(folder); + leaveErrorState(); + return true; + }) + .negativeText(R.string.cancel_label) + .cancelable(true) + .build(); + dialog.show(); + } + + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (resultCode == Activity.RESULT_OK && + requestCode == DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED) { + String dir = data.getStringExtra(DirectoryChooserActivity.RESULT_SELECTED_DIR); + + File path; + if (dir != null) { + path = new File(dir); + } else { + path = getExternalFilesDir(null); + } + String message = null; + if(!path.exists()) { + message = String.format(getString(R.string.folder_does_not_exist_error), dir); + } else if(!path.canRead()) { + message = String.format(getString(R.string.folder_not_readable_error), dir); + } else if(!path.canWrite()) { + message = String.format(getString(R.string.folder_not_writable_error), dir); + } + + if(message == null) { + Log.d(TAG, "Setting data folder: " + dir); + UserPreferences.setDataFolder(dir); + leaveErrorState(); + } else { + AlertDialog.Builder ab = new AlertDialog.Builder(this); + ab.setMessage(message); + ab.setPositiveButton(android.R.string.ok, null); + ab.show(); + } } } @@ -58,13 +221,10 @@ public class StorageErrorActivity extends ActionBarActivity { public void onReceive(Context context, Intent intent) { if (TextUtils.equals(intent.getAction(), Intent.ACTION_MEDIA_MOUNTED)) { if (intent.getBooleanExtra("read-only", true)) { - if (BuildConfig.DEBUG) - Log.d(TAG, "Media was mounted; Finishing activity"); + Log.d(TAG, "Media was mounted; Finishing activity"); leaveErrorState(); } else { - if (BuildConfig.DEBUG) - Log.d(TAG, - "Media seemed to have been mounted read only"); + Log.d(TAG, "Media seemed to have been mounted read only"); } } } diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java index 785944768..c563d278f 100644 --- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java +++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java @@ -1,12 +1,13 @@ package de.danoeh.antennapod.preferences; +import android.Manifest; import android.annotation.SuppressLint; import android.app.Activity; import android.app.TimePickerDialog; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.content.res.Resources; import android.net.Uri; import android.net.wifi.WifiConfiguration; @@ -18,6 +19,7 @@ import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceManager; import android.preference.PreferenceScreen; +import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; import android.text.Editable; @@ -85,6 +87,11 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc private CheckBoxPreference[] selectedNetworks; + private static final String[] EXTERNAL_STORAGE_PERMISSIONS = { + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE }; + private static final int PERMISSION_REQUEST_EXTERNAL_STORAGE = 41; + public PreferenceController(PreferenceUI ui) { this.ui = ui; PreferenceManager.getDefaultSharedPreferences(ui.getActivity().getApplicationContext()) @@ -121,54 +128,51 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc // disable expanded notification option on unsupported android versions ui.findPreference(PreferenceController.PREF_EXPANDED_NOTIFICATION).setEnabled(false); ui.findPreference(PreferenceController.PREF_EXPANDED_NOTIFICATION).setOnPreferenceClickListener( - new Preference.OnPreferenceClickListener() { - - @Override - public boolean onPreferenceClick(Preference preference) { - Toast toast = Toast.makeText(activity, R.string.pref_expand_notify_unsupport_toast, Toast.LENGTH_SHORT); - toast.show(); - return true; - } + preference -> { + Toast toast = Toast.makeText(activity, + R.string.pref_expand_notify_unsupport_toast, Toast.LENGTH_SHORT); + toast.show(); + return true; } ); } - ui.findPreference(PreferenceController.PREF_FLATTR_REVOKE).setOnPreferenceClickListener( - new Preference.OnPreferenceClickListener() { - - @Override - public boolean onPreferenceClick(Preference preference) { - FlattrUtils.revokeAccessToken(activity); - checkItemVisibility(); - return true; - } - + preference -> { + FlattrUtils.revokeAccessToken(activity); + checkItemVisibility(); + return true; } ); - ui.findPreference(PreferenceController.PREF_ABOUT).setOnPreferenceClickListener( - new Preference.OnPreferenceClickListener() { - - @Override - public boolean onPreferenceClick(Preference preference) { - activity.startActivity(new Intent( - activity, AboutActivity.class)); - return true; - } - + preference -> { + activity.startActivity(new Intent(activity, AboutActivity.class)); + return true; } ); - ui.findPreference(PreferenceController.PREF_OPML_EXPORT).setOnPreferenceClickListener( - new Preference.OnPreferenceClickListener() { - - @Override - public boolean onPreferenceClick(Preference preference) { - new OpmlExportWorker(activity) - .executeAsync(); - - return true; + preference -> { + new OpmlExportWorker(activity).executeAsync(); + return true; + } + ); + ui.findPreference(PreferenceController.PREF_CHOOSE_DATA_DIR).setOnPreferenceClickListener( + preference -> { + if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT && + Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) { + showChooseDataFolderDialog(); + } else { + int readPermission = ActivityCompat.checkSelfPermission( + activity, Manifest.permission.READ_EXTERNAL_STORAGE); + int writePermission = ActivityCompat.checkSelfPermission( + activity, Manifest.permission.WRITE_EXTERNAL_STORAGE); + if (readPermission == PackageManager.PERMISSION_GRANTED && + writePermission == PackageManager.PERMISSION_GRANTED) { + openDirectoryChooser(); + } else { + requestPermission(); + } } + return true; } ); ui.findPreference(PreferenceController.PREF_CHOOSE_DATA_DIR) @@ -185,40 +189,29 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc } return true; } - } - ); + } + ); ui.findPreference(UserPreferences.PREF_THEME) .setOnPreferenceChangeListener( - new Preference.OnPreferenceChangeListener() { - - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - Intent i = new Intent(activity, MainActivity.class); - i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK - | Intent.FLAG_ACTIVITY_NEW_TASK); - activity.finish(); - activity.startActivity(i); - return true; - } + (preference, newValue) -> { + Intent i = new Intent(activity, MainActivity.class); + i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK + | Intent.FLAG_ACTIVITY_NEW_TASK); + activity.finish(); + activity.startActivity(i); + return true; } ); ui.findPreference(UserPreferences.PREF_HIDDEN_DRAWER_ITEMS) - .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - showDrawerPreferencesDialog(); - return true; - } + .setOnPreferenceClickListener(preference -> { + showDrawerPreferencesDialog(); + return true; }); ui.findPreference(UserPreferences.PREF_UPDATE_INTERVAL) - .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - showUpdateIntervalTimePreferencesDialog(); - return true; - } + .setOnPreferenceClickListener(preference -> { + showUpdateIntervalTimePreferencesDialog(); + return true; }); ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL).setOnPreferenceChangeListener( @@ -234,38 +227,30 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc }); ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL_WIFI_FILTER) .setOnPreferenceChangeListener( - new Preference.OnPreferenceChangeListener() { - - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - if (newValue instanceof Boolean) { - setSelectedNetworksEnabled((Boolean) newValue); - return true; - } else { - return false; - } + (preference, newValue) -> { + if (newValue instanceof Boolean) { + setSelectedNetworksEnabled((Boolean) newValue); + return true; + } else { + return false; } } ); ui.findPreference(UserPreferences.PREF_PARALLEL_DOWNLOADS) .setOnPreferenceChangeListener( - new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object o) { - if (o instanceof String) { - try { - int value = Integer.valueOf((String) o); - if (1 <= value && value <= 50) { - setParallelDownloadsText(value); - return true; - } - } catch (NumberFormatException e) { - return false; + (preference, o) -> { + if (o instanceof String) { + try { + int value = Integer.valueOf((String) o); + if (1 <= value && value <= 50) { + setParallelDownloadsText(value); + return true; } + } catch (NumberFormatException e) { + return false; } - return false; } + return false; } ); // validate and set correct value: number of downloads between 1 and 50 (inclusive) @@ -298,102 +283,79 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc }); ui.findPreference(UserPreferences.PREF_EPISODE_CACHE_SIZE) .setOnPreferenceChangeListener( - new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object o) { - if (o instanceof String) { - setEpisodeCacheSizeText(UserPreferences.readEpisodeCacheSize((String) o)); - } - return true; + (preference, o) -> { + if (o instanceof String) { + setEpisodeCacheSizeText(UserPreferences.readEpisodeCacheSize((String) o)); } + return true; } ); ui.findPreference(PreferenceController.PREF_PLAYBACK_SPEED_LAUNCHER) - .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - VariableSpeedDialog.showDialog(activity); - return true; - } + .setOnPreferenceClickListener(preference -> { + VariableSpeedDialog.showDialog(activity); + return true; }); - ui.findPreference(PreferenceController.PREF_GPODNET_SETLOGIN_INFORMATION).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - AuthenticationDialog dialog = new AuthenticationDialog(activity, - R.string.pref_gpodnet_setlogin_information_title, false, false, GpodnetPreferences.getUsername(), - null) { - - @Override - protected void onConfirmed(String username, String password, boolean saveUsernamePassword) { - GpodnetPreferences.setPassword(password); - } - }; - dialog.show(); - return true; - } - }); - ui.findPreference(PreferenceController.PREF_GPODNET_LOGOUT).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - GpodnetPreferences.logout(); - Toast toast = Toast.makeText(activity, R.string.pref_gpodnet_logout_toast, Toast.LENGTH_SHORT); - toast.show(); - updateGpodnetPreferenceScreen(); - return true; - } - }); - ui.findPreference(PreferenceController.PREF_GPODNET_HOSTNAME).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - GpodnetSetHostnameDialog.createDialog(activity).setOnDismissListener(new DialogInterface.OnDismissListener() { - @Override - public void onDismiss(DialogInterface dialog) { - updateGpodnetPreferenceScreen(); - } + ui.findPreference(PreferenceController.PREF_GPODNET_SETLOGIN_INFORMATION) + .setOnPreferenceClickListener(preference -> { + AuthenticationDialog dialog = new AuthenticationDialog(activity, + R.string.pref_gpodnet_setlogin_information_title, false, false, GpodnetPreferences.getUsername(), + null) { + + @Override + protected void onConfirmed(String username, String password, boolean saveUsernamePassword) { + GpodnetPreferences.setPassword(password); + } + }; + dialog.show(); + return true; + }); + ui.findPreference(PreferenceController.PREF_GPODNET_LOGOUT).setOnPreferenceClickListener( + preference -> { + GpodnetPreferences.logout(); + Toast toast = Toast.makeText(activity, R.string.pref_gpodnet_logout_toast, Toast.LENGTH_SHORT); + toast.show(); + updateGpodnetPreferenceScreen(); + return true; + }); + ui.findPreference(PreferenceController.PREF_GPODNET_HOSTNAME).setOnPreferenceClickListener( + preference -> { + GpodnetSetHostnameDialog.createDialog(activity).setOnDismissListener(dialog -> updateGpodnetPreferenceScreen()); + return true; }); - return true; - } - }); - ui.findPreference(PreferenceController.PREF_AUTO_FLATTR_PREFS).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - AutoFlattrPreferenceDialog.newAutoFlattrPreferenceDialog(activity, - new AutoFlattrPreferenceDialog.AutoFlattrPreferenceDialogInterface() { - @Override - public void onCancelled() { + ui.findPreference(PreferenceController.PREF_AUTO_FLATTR_PREFS) + .setOnPreferenceClickListener(preference -> { + AutoFlattrPreferenceDialog.newAutoFlattrPreferenceDialog(activity, + new AutoFlattrPreferenceDialog.AutoFlattrPreferenceDialogInterface() { + @Override + public void onCancelled() { - } + } - @Override - public void onConfirmed(boolean autoFlattrEnabled, float autoFlattrValue) { - UserPreferences.setAutoFlattrSettings(autoFlattrEnabled, autoFlattrValue); - checkItemVisibility(); - } - }); - return true; - } - }); - ui.findPreference(UserPreferences.PREF_IMAGE_CACHE_SIZE) - .setOnPreferenceChangeListener( - new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object o) { - if (o instanceof String) { - int newValue = Integer.valueOf((String) o) * 1024 * 1024; - if (newValue != UserPreferences.getImageCacheSize()) { - AlertDialog.Builder dialog = new AlertDialog.Builder(ui.getActivity()); - dialog.setTitle(android.R.string.dialog_alert_title); - dialog.setMessage(R.string.pref_restart_required); - dialog.setPositiveButton(android.R.string.ok, null); - dialog.show(); - } - return true; + @Override + public void onConfirmed(boolean autoFlattrEnabled, float autoFlattrValue) { + UserPreferences.setAutoFlattrSettings(autoFlattrEnabled, autoFlattrValue); + checkItemVisibility(); } - return false; - } + }); + return true; + }); + ui.findPreference(UserPreferences.PREF_IMAGE_CACHE_SIZE).setOnPreferenceChangeListener( + (preference, o) -> { + if (o instanceof String) { + int newValue = Integer.valueOf((String) o) * 1024 * 1024; + if (newValue != UserPreferences.getImageCacheSize()) { + AlertDialog.Builder dialog = new AlertDialog.Builder(ui.getActivity()); + dialog.setTitle(android.R.string.dialog_alert_title); + dialog.setMessage(R.string.pref_restart_required); + dialog.setPositiveButton(android.R.string.ok, null); + dialog.show(); } - ); + return true; + } + return false; + } + ); ui.findPreference("prefSendCrashReport").setOnPreferenceClickListener(preference -> { Intent emailIntent = new Intent(Intent.ACTION_SEND); emailIntent.setType("text/plain"); @@ -427,7 +389,12 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc requestCode == DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED) { String dir = data.getStringExtra(DirectoryChooserActivity.RESULT_SELECTED_DIR); - File path = new File(dir); + File path; + if(dir != null) { + path = new File(dir); + } else { + path = ui.getActivity().getExternalFilesDir(null); + } String message = null; final Context context= ui.getActivity().getApplicationContext(); if(!path.exists()) { @@ -628,35 +595,31 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc List<String> prefValues = Arrays.asList(UserPreferences .getAutodownloadSelectedNetworks()); PreferenceScreen prefScreen = (PreferenceScreen) ui.findPreference(PreferenceController.AUTO_DL_PREF_SCREEN); - Preference.OnPreferenceClickListener clickListener = new Preference.OnPreferenceClickListener() { - - @Override - public boolean onPreferenceClick(Preference preference) { - if (preference instanceof CheckBoxPreference) { - String key = preference.getKey(); - ArrayList<String> prefValuesList = new ArrayList<String>( - Arrays.asList(UserPreferences - .getAutodownloadSelectedNetworks()) - ); - boolean newValue = ((CheckBoxPreference) preference) - .isChecked(); - Log.d(TAG, "Selected network " + key + ". New state: " + newValue); - - int index = prefValuesList.indexOf(key); - if (index >= 0 && newValue == false) { - // remove network - prefValuesList.remove(index); - } else if (index < 0 && newValue == true) { - prefValuesList.add(key); - } - - UserPreferences.setAutodownloadSelectedNetworks( - prefValuesList.toArray(new String[prefValuesList.size()]) - ); - return true; - } else { - return false; + Preference.OnPreferenceClickListener clickListener = preference -> { + if (preference instanceof CheckBoxPreference) { + String key = preference.getKey(); + ArrayList<String> prefValuesList = new ArrayList<String>( + Arrays.asList(UserPreferences + .getAutodownloadSelectedNetworks()) + ); + boolean newValue = ((CheckBoxPreference) preference) + .isChecked(); + Log.d(TAG, "Selected network " + key + ". New state: " + newValue); + + int index = prefValuesList.indexOf(key); + if (index >= 0 && newValue == false) { + // remove network + prefValuesList.remove(index); + } else if (index < 0 && newValue == true) { + prefValuesList.add(key); } + + UserPreferences.setAutodownloadSelectedNetworks( + prefValuesList.toArray(new String[prefValuesList.size()]) + ); + return true; + } else { + return false; } }; // create preference for each known network. attach listener and set @@ -703,7 +666,6 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc checked[i] = true; } } - AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(R.string.drawer_preferences); builder.setMultiChoiceItems(navTitles, checked, (dialog, which, isChecked) -> { @@ -713,16 +675,26 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc hiddenDrawerItems.add(NAV_DRAWER_TAGS[which]); } }); - builder.setPositiveButton(R.string.confirm_label, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - UserPreferences.setHiddenDrawerItems(hiddenDrawerItems); - } + builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> { + UserPreferences.setHiddenDrawerItems(hiddenDrawerItems); }); builder.setNegativeButton(R.string.cancel_label, null); builder.create().show(); } + // CHOOSE DATA FOLDER + + private void requestPermission() { + ActivityCompat.requestPermissions(ui.getActivity(), EXTERNAL_STORAGE_PERMISSIONS, + PERMISSION_REQUEST_EXTERNAL_STORAGE); + } + + private void openDirectoryChooser() { + Activity activity = ui.getActivity(); + Intent intent = new Intent(activity, DirectoryChooserActivity.class); + activity.startActivityForResult(intent, DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED); + } + private void showChooseDataFolderDialog() { Context context = ui.getActivity(); File dataFolder = UserPreferences.getDataFolder(null); @@ -786,6 +758,8 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc dialog.show(); } + // UPDATE TIME/INTERVAL DIALOG + private void showUpdateIntervalTimePreferencesDialog() { final Context context = ui.getActivity(); @@ -795,38 +769,34 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc builder.positiveText(R.string.pref_autoUpdateIntervallOrTime_Interval); builder.negativeText(R.string.pref_autoUpdateIntervallOrTime_TimeOfDay); builder.neutralText(R.string.pref_autoUpdateIntervallOrTime_Disable); - builder.callback(new MaterialDialog.ButtonCallback() { - @Override - public void onPositive(MaterialDialog dialog) { - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(context.getString(R.string.pref_autoUpdateIntervallOrTime_Interval)); - final String[] values = context.getResources().getStringArray(R.array.update_intervall_values); - final String[] entries = getUpdateIntervalEntries(values); - long currInterval = UserPreferences.getUpdateInterval(); - int checkedItem = -1; - if(currInterval > 0) { - String currIntervalStr = String.valueOf(TimeUnit.MILLISECONDS.toHours(currInterval)); - checkedItem = ArrayUtils.indexOf(values, currIntervalStr); - } - builder.setSingleChoiceItems(entries, checkedItem, (dialog1, which) -> { - int hours = Integer.valueOf(values[which]); - UserPreferences.setUpdateInterval(hours); - dialog1.dismiss(); - setUpdateIntervalText(); - }); - builder.setNegativeButton(context.getString(R.string.cancel_label), null); - builder.show(); + builder.onPositive((dialog, which) -> { + AlertDialog.Builder builder1 = new AlertDialog.Builder(context); + builder1.setTitle(context.getString(R.string.pref_autoUpdateIntervallOrTime_Interval)); + final String[] values = context.getResources().getStringArray(R.array.update_intervall_values); + final String[] entries = getUpdateIntervalEntries(values); + long currInterval = UserPreferences.getUpdateInterval(); + int checkedItem = -1; + if(currInterval > 0) { + String currIntervalStr = String.valueOf(TimeUnit.MILLISECONDS.toHours(currInterval)); + checkedItem = ArrayUtils.indexOf(values, currIntervalStr); } - - @Override - public void onNegative(MaterialDialog dialog) { - int hourOfDay = 7, minute = 0; - int[] updateTime = UserPreferences.getUpdateTimeOfDay(); - if (updateTime.length == 2) { - hourOfDay = updateTime[0]; - minute = updateTime[1]; - } - TimePickerDialog timePickerDialog = new TimePickerDialog(context, + builder1.setSingleChoiceItems(entries, checkedItem, (dialog1, which1) -> { + int hours = Integer.valueOf(values[which1]); + UserPreferences.setUpdateInterval(hours); + dialog1.dismiss(); + setUpdateIntervalText(); + }); + builder1.setNegativeButton(context.getString(R.string.cancel_label), null); + builder1.show(); + }); + builder.onNegative((dialog, which) -> { + int hourOfDay = 7, minute = 0; + int[] updateTime = UserPreferences.getUpdateTimeOfDay(); + if (updateTime.length == 2) { + hourOfDay = updateTime[0]; + minute = updateTime[1]; + } + TimePickerDialog timePickerDialog = new TimePickerDialog(context, (view, selectedHourOfDay, selectedMinute) -> { if (view.getTag() == null) { // onTimeSet() may get called twice! view.setTag("TAGGED"); @@ -834,17 +804,13 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc setUpdateIntervalText(); } }, hourOfDay, minute, DateFormat.is24HourFormat(context)); - timePickerDialog.setTitle(context.getString(R.string.pref_autoUpdateIntervallOrTime_TimeOfDay)); - timePickerDialog.show(); - } - - @Override - public void onNeutral(MaterialDialog dialog) { - UserPreferences.setUpdateInterval(0); - setUpdateIntervalText(); - } + timePickerDialog.setTitle(context.getString(R.string.pref_autoUpdateIntervallOrTime_TimeOfDay)); + timePickerDialog.show(); + }); + builder.onNeutral((dialog, which) -> { + UserPreferences.setUpdateInterval(0); + setUpdateIntervalText(); }); - builder.forceStacking(true); builder.show(); } diff --git a/app/src/main/res/layout/storage_error.xml b/app/src/main/res/layout/storage_error.xml index c1ee77262..8ff28b3c1 100644 --- a/app/src/main/res/layout/storage_error.xml +++ b/app/src/main/res/layout/storage_error.xml @@ -1,25 +1,32 @@ <?xml version="1.0" encoding="utf-8"?> -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" - android:layout_height="match_parent" > + android:layout_height="match_parent" + android:orientation="vertical" + android:gravity="center" + android:padding="16dp"> <ImageView android:id="@+id/imageView1" android:contentDescription="@string/external_storage_error_msg" - android:layout_width="30dp" - android:layout_height="30dp" - android:layout_centerHorizontal="true" - android:layout_centerVertical="true" - android:layout_margin="16dp" - android:src="@android:drawable/stat_notify_sdcard_usb" /> + android:layout_width="36dp" + android:layout_height="36dp" + android:layout_margin="8dp" + android:src="?attr/ic_sd_storage" /> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_below="@+id/imageView1" - android:layout_centerHorizontal="true" android:layout_margin="8dp" android:text="@string/external_storage_error_msg" /> -</RelativeLayout>
\ No newline at end of file + <Button + android:id="@+id/btnChooseDataFolder" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_margin="8dp" + android:text="@string/choose_data_directory"/> + +</LinearLayout> diff --git a/app/src/main/res/menu/directory_chooser.xml b/app/src/main/res/menu/directory_chooser.xml index 7735ffd2c..3f860d636 100644 --- a/app/src/main/res/menu/directory_chooser.xml +++ b/app/src/main/res/menu/directory_chooser.xml @@ -1,14 +1,16 @@ <?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:custom="http://schemas.android.com/apk/res-auto"> +<menu + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:custom="http://schemas.android.com/apk/res-auto"> + <item android:id="@+id/new_folder_item" android:title="@string/create_folder_label" - custom:showAsAction="ifRoom|withText"/> + android:icon="?attr/ic_create_new_folder" + custom:showAsAction="ifRoom|withText" /> <item android:id="@+id/set_to_default_folder_item" - custom:showAsAction="collapseActionView" - android:title="@string/set_to_default_folder"/> - + android:title="@string/set_to_default_folder" + custom:showAsAction="collapseActionView" /> -</menu>
\ No newline at end of file +</menu> |