From 06cdd987e0f3bb676eb49054ba59c47ff881e837 Mon Sep 17 00:00:00 2001 From: Martin Fietz Date: Thu, 17 Sep 2015 17:19:05 +0200 Subject: [PATCH] Replace DirectoryChooser with simple dialog listing all external directories --- app/build.gradle | 1 + .../activity/DirectoryChooserActivity.java | 84 ++++++------- .../preferences/PreferenceController.java | 117 ++++++++++++++---- .../core/preferences/UserPreferences.java | 2 +- core/src/main/res/values/strings.xml | 6 + 5 files changed, 137 insertions(+), 73 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 3368af0d6..5a391b45e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -19,6 +19,7 @@ dependencies { compile("org.shredzone.flattr4j:flattr4j-core:$flattr4jVersion") { exclude group: "org.json", module: "json" } + compile "commons-io:commons-io:$commonsioVersion" compile "org.jsoup:jsoup:$jsoupVersion" compile "com.github.bumptech.glide:glide:$glideVersion" 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 86ca90eb5..c68e7f862 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/DirectoryChooserActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/DirectoryChooserActivity.java @@ -1,7 +1,6 @@ package de.danoeh.antennapod.activity; import android.app.Activity; -import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.os.Environment; @@ -15,23 +14,28 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; -import android.widget.*; -import android.widget.AdapterView.OnItemClickListener; -import de.danoeh.antennapod.BuildConfig; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.core.preferences.UserPreferences; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.ImageButton; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.Toast; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import de.danoeh.antennapod.BuildConfig; +import de.danoeh.antennapod.R; +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 { - private static final String TAG = "DirectoryChooserActivity"; + private static final String TAG = "DirectoryChooserActivit"; private static final String CREATE_DIRECTORY_NAME = "AntennaPod"; @@ -103,7 +107,7 @@ public class DirectoryChooserActivity extends ActionBarActivity { listDirectories.setOnItemClickListener((adapter, view, position, id) -> { Log.d(TAG, "Selected index: " + position); - if (filesInDir != null && position >= 0 + if (filesInDir != null && position >= 0 && position < filesInDir.length) { changeDirectory(filesInDir[position]); } @@ -137,7 +141,7 @@ public class DirectoryChooserActivity extends ActionBarActivity { resultData.putExtra(RESULT_SELECTED_DIR, selectedDir.getAbsolutePath()); } - setResult(RESULT_CODE_DIR_SELECTED, resultData); + setResult(Activity.RESULT_OK, resultData); finish(); } @@ -157,6 +161,13 @@ public class DirectoryChooserActivity extends ActionBarActivity { } } + @Override + public void onStop() { + super.onStop(); + listDirectoriesAdapter = null; + fileObserver = null; + } + /** * Change the directory that is currently being displayed. * @@ -191,20 +202,15 @@ public class DirectoryChooserActivity extends ActionBarActivity { listDirectoriesAdapter.notifyDataSetChanged(); fileObserver = createFileObserver(dir.getAbsolutePath()); fileObserver.startWatching(); - if (BuildConfig.DEBUG) - Log.d(TAG, "Changed directory to " + dir.getAbsolutePath()); + Log.d(TAG, "Changed directory to " + dir.getAbsolutePath()); } else { - if (BuildConfig.DEBUG) - Log.d(TAG, - "Could not change folder: contents of dir were null"); + Log.d(TAG, "Could not change folder: contents of dir were null"); } } else { if (dir == null) { - if (BuildConfig.DEBUG) - Log.d(TAG, "Could not change folder: dir was null"); + Log.d(TAG, "Could not change folder: dir was null"); } else { - if (BuildConfig.DEBUG) - Log.d(TAG, "Could not change folder: dir is no directory"); + Log.d(TAG, "Could not change folder: dir is no directory"); } } refreshButtonState(); @@ -235,15 +241,8 @@ public class DirectoryChooserActivity extends ActionBarActivity { @Override public void onEvent(int event, String path) { - if (BuildConfig.DEBUG) - Log.d(TAG, "FileObserver received event " + event); - runOnUiThread(new Runnable() { - - @Override - public void run() { - refreshDirectory(); - } - }); + Log.d(TAG, "FileObserver received event " + event); + runOnUiThread(() -> refreshDirectory()); } }; } @@ -292,25 +291,17 @@ public class DirectoryChooserActivity extends ActionBarActivity { builder.setMessage(String.format(getString(R.string.create_folder_msg), CREATE_DIRECTORY_NAME)); builder.setNegativeButton(R.string.cancel_label, - new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - } - }); + (dialog, which) -> { + dialog.dismiss(); + }); builder.setPositiveButton(R.string.confirm_label, - new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - int msg = createFolder(); - Toast t = Toast.makeText(DirectoryChooserActivity.this, - msg, Toast.LENGTH_SHORT); - t.show(); - } - }); + (dialog, which) -> { + dialog.dismiss(); + int msg = createFolder(); + Toast t = Toast.makeText(DirectoryChooserActivity.this, + msg, Toast.LENGTH_SHORT); + t.show(); + }); builder.create().show(); } @@ -340,7 +331,6 @@ public class DirectoryChooserActivity extends ActionBarActivity { /** Returns true if the selected file or directory would be valid selection. */ private boolean isValidFile(File file) { - return (file != null && file.isDirectory() && file.canRead() && file - .canWrite()); + return file != null && file.isDirectory() && file.canRead() && file.canWrite(); } } 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 f729ef807..73d7da0f2 100644 --- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java +++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java @@ -1,5 +1,6 @@ package de.danoeh.antennapod.preferences; +import android.annotation.SuppressLint; import android.app.Activity; import android.app.TimePickerDialog; import android.content.Context; @@ -16,8 +17,10 @@ import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceManager; import android.preference.PreferenceScreen; +import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; import android.text.Editable; +import android.text.Html; import android.text.TextWatcher; import android.text.format.DateFormat; import android.util.Log; @@ -31,7 +34,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import de.danoeh.antennapod.BuildConfig; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.AboutActivity; import de.danoeh.antennapod.activity.DirectoryChooserActivity; @@ -41,6 +43,8 @@ import de.danoeh.antennapod.activity.PreferenceActivityGingerbread; import de.danoeh.antennapod.asynctask.OpmlExportWorker; import de.danoeh.antennapod.core.preferences.GpodnetPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences; +import de.danoeh.antennapod.core.util.Converter; +import de.danoeh.antennapod.core.util.StorageUtils; import de.danoeh.antennapod.core.util.flattr.FlattrUtils; import de.danoeh.antennapod.dialog.AuthenticationDialog; import de.danoeh.antennapod.dialog.AutoFlattrPreferenceDialog; @@ -50,9 +54,11 @@ import de.danoeh.antennapod.dialog.VariableSpeedDialog; /** * Sets up a preference UI that lets the user change user preferences. */ + public class PreferenceController implements SharedPreferences.OnSharedPreferenceChangeListener { private static final String TAG = "PreferenceController"; + public static final String PREF_FLATTR_SETTINGS = "prefFlattrSettings"; public static final String PREF_FLATTR_AUTH = "pref_flattr_authenticate"; public static final String PREF_FLATTR_REVOKE = "prefRevokeAccess"; @@ -158,21 +164,22 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc } } ); - - ui.findPreference(PreferenceController.PREF_CHOOSE_DATA_DIR).setOnPreferenceClickListener( - new Preference.OnPreferenceClickListener() { - - @Override - public boolean onPreferenceClick(Preference preference) { - activity.startActivityForResult( - new Intent(activity, - DirectoryChooserActivity.class), - DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED - ); - return true; - } - } - ); + ui.findPreference(PreferenceController.PREF_CHOOSE_DATA_DIR) + .setOnPreferenceClickListener( + new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + if(Build.VERSION.SDK_INT >= 19) { + showChooseDataFolderDialog(); + } else { + Intent intent = new Intent(activity, DirectoryChooserActivity.class); + activity.startActivityForResult(intent, + DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED); + } + return true; + } + } + ); ui.findPreference(UserPreferences.PREF_THEME) .setOnPreferenceChangeListener( new Preference.OnPreferenceChangeListener() { @@ -394,16 +401,37 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc updateGpodnetPreferenceScreen(); } + @SuppressLint("NewApi") public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (resultCode == DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED) { - String dir = data - .getStringExtra(DirectoryChooserActivity.RESULT_SELECTED_DIR); - if (BuildConfig.DEBUG) - Log.d(TAG, "Setting data folder"); - UserPreferences.setDataFolder(dir); + if (resultCode == Activity.RESULT_OK && + requestCode == DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED) { + String dir = data.getStringExtra(DirectoryChooserActivity.RESULT_SELECTED_DIR); + + File path = new File(dir); + String message = null; + final Context context= ui.getActivity().getApplicationContext(); + if(!path.exists()) { + message = String.format(context.getString(R.string.folder_does_not_exist_error), dir); + } else if(!path.canRead()) { + message = String.format(context.getString(R.string.folder_not_readable_error), dir); + } else if(!path.canWrite()) { + message = String.format(context.getString(R.string.folder_not_writable_error), dir); + } + + if(message == null) { + Log.d(TAG, "Setting data folder: " + dir); + UserPreferences.setDataFolder(dir); + setDataFolderText(); + } else { + AlertDialog.Builder ab = new AlertDialog.Builder(ui.getActivity()); + ab.setMessage(message); + ab.setPositiveButton(android.R.string.ok, null); + ab.show(); + } } } + private void updateGpodnetPreferenceScreen() { final boolean loggedIn = GpodnetPreferences.loggedIn(); ui.findPreference(PreferenceController.PREF_GPODNET_LOGIN).setEnabled(!loggedIn); @@ -564,9 +592,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc ); boolean newValue = ((CheckBoxPreference) preference) .isChecked(); - if (BuildConfig.DEBUG) - Log.d(TAG, "Selected network " + key - + ". New state: " + newValue); + Log.d(TAG, "Selected network " + key + ". New state: " + newValue); int index = prefValuesList.indexOf(key); if (index >= 0 && newValue == false) { @@ -649,6 +675,47 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc builder.create().show(); } + private void showChooseDataFolderDialog() { + Context context = ui.getActivity(); + String dataFolder = UserPreferences.getDataFolder(context, null).getAbsolutePath(); + int selectedIndex = -1; + File[] mediaDirs = ContextCompat.getExternalFilesDirs(context, null); + String[] folders = new String[mediaDirs.length]; + CharSequence[] choices = new CharSequence[mediaDirs.length]; + for(int i=0; i < mediaDirs.length; i++) { + String path = folders[i] = mediaDirs[i].getAbsolutePath(); + if(dataFolder.equals(path)) { + selectedIndex = i; + } + int index = path.indexOf("Android"); + if(index >= 0) { + choices[i] = path.substring(0, index); + } else { + choices[i] = path; + } + long bytes = StorageUtils.getFreeSpaceAvailable(); + String freeSpace = String.format(context.getString(R.string.free_space_label), + Converter.byteToString(bytes)); + choices[i] = Html.fromHtml("" + choices[i] + + " [" + freeSpace + "]" + ""); + } + MaterialDialog dialog = new MaterialDialog.Builder(ui.getActivity()) + .title(R.string.choose_data_directory) + .content(R.string.choose_data_directory_message) + .items(choices) + .itemsCallbackSingleChoice(selectedIndex, (dialog1, itemView, which, text) -> { + String folder = folders[which]; + Log.d(TAG, "data folder: " + folder); + UserPreferences.setDataFolder(folder); + setDataFolderText(); + return true; + }) + .negativeText(R.string.cancel_label) + .cancelable(true) + .build(); + dialog.show(); + } + private void showUpdateIntervalTimePreferencesDialog() { final Context context = ui.getActivity(); diff --git a/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java b/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java index d3c4d3ffd..6de546d3b 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java +++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java @@ -565,7 +565,7 @@ public class UserPreferences { } public static void setDataFolder(String dir) { - Log.d(TAG, "Result from DirectoryChooser: " + dir); + Log.d(TAG, "setDataFolder(dir: " + dir + ")"); prefs.edit() .putString(PREF_DATA_FOLDER, dir) .apply(); diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 0c56e1d3e..6cbc5579d 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -25,6 +25,7 @@ Playback History gpodder.net gpodder.net Login + "%1$s free Recently published @@ -464,11 +465,15 @@ Selected folder: Create folder Choose Data Folder + Please choose the base of your data folder. AntennaPod will create the appropriate sub-directories. Create new folder with name "%1$s"? Created new folder Cannot write to this folder Folder already exists Could not create folder + "%1$s" does not exist + "%1$s" is not readable + "%1$s" is not writable Folder is not empty The folder you have selected is not empty. Media downloads and other files will be placed directly in this folder. Continue anyway? Choose default folder @@ -478,6 +483,7 @@ Resume after Call AntennaPod has to be restarted for this change to take effect. + Subscribe Subscribed