From 148b86a3e84a65cade4765c6224918f57109b5b3 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Wed, 1 Jul 2020 10:05:27 +0200 Subject: [PATCH 1/4] Removed DirectoryChooserActivity This lead to problems when removing the sd card and left the app in stuck mode. Selecting a folder freely that way will not work with new Android versions anyway. Now, AntennaPod shows the folder chooser that is displayed on the storage settings screen. --- app/src/main/AndroidManifest.xml | 7 - .../activity/DirectoryChooserActivity.java | 333 ------------------ .../activity/StorageErrorActivity.java | 106 +----- .../StoragePreferencesFragment.java | 86 +---- app/src/main/res/layout/directory_chooser.xml | 122 ------- app/src/main/res/menu/directory_chooser.xml | 16 - 6 files changed, 7 insertions(+), 663 deletions(-) delete mode 100644 app/src/main/java/de/danoeh/antennapod/activity/DirectoryChooserActivity.java delete mode 100644 app/src/main/res/layout/directory_chooser.xml delete mode 100644 app/src/main/res/menu/directory_chooser.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f0572d0ba..b87c8d224 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -192,13 +192,6 @@ - - - listDirectoriesAdapter; - private ArrayList filenames; - /** The directory that is currently being shown. */ - private File selectedDir; - private File[] filesInDir; - - private FileObserver fileObserver; - - @Override - protected void onCreate(Bundle savedInstanceState) { - setTheme(UserPreferences.getTheme()); - super.onCreate(savedInstanceState); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - setContentView(R.layout.directory_chooser); - butConfirm = findViewById(R.id.butConfirm); - butCancel = findViewById(R.id.butCancel); - butNavUp = findViewById(R.id.butNavUp); - txtvSelectedFolder = findViewById(R.id.txtvSelectedFolder); - listDirectories = findViewById(R.id.directory_list); - - butConfirm.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - if (isValidFile(selectedDir)) { - if (selectedDir.list().length == 0) { - returnSelectedFolder(); - } else { - showNonEmptyDirectoryWarning(); - } - } - } - - private void showNonEmptyDirectoryWarning() { - AlertDialog.Builder adb = new AlertDialog.Builder( - DirectoryChooserActivity.this); - adb.setTitle(R.string.folder_not_empty_dialog_title); - adb.setMessage(R.string.folder_not_empty_dialog_msg); - adb.setNegativeButton(R.string.cancel_label, - (dialog, which) -> dialog.dismiss()); - adb.setPositiveButton(R.string.confirm_label, - (dialog, which) -> { - dialog.dismiss(); - returnSelectedFolder(); - }); - adb.create().show(); - } - }); - - butCancel.setOnClickListener(v -> { - setResult(Activity.RESULT_CANCELED); - finish(); - }); - - listDirectories.setOnItemClickListener((adapter, view, position, id) -> { - Log.d(TAG, "Selected index: " + position); - if (filesInDir != null && position >= 0 - && position < filesInDir.length) { - changeDirectory(filesInDir[position]); - } - }); - - butNavUp.setOnClickListener(v -> { - File parent = null; - if (selectedDir != null - && (parent = selectedDir.getParentFile()) != null) { - changeDirectory(parent); - } - }); - - filenames = new ArrayList<>(); - listDirectoriesAdapter = new ArrayAdapter<>(this, - android.R.layout.simple_list_item_1, filenames); - listDirectories.setAdapter(listDirectoriesAdapter); - changeDirectory(Environment.getExternalStorageDirectory()); - } - - /** - * Finishes the activity and returns the selected folder as a result. The - * selected folder can also be null. - */ - private void returnSelectedFolder() { - if (selectedDir != null && BuildConfig.DEBUG) - Log.d(TAG, "Returning " + selectedDir.getAbsolutePath() - + " as result"); - Intent resultData = new Intent(); - if (selectedDir != null) { - resultData.putExtra(RESULT_SELECTED_DIR, - selectedDir.getAbsolutePath()); - } - setResult(Activity.RESULT_OK, resultData); - finish(); - } - - @Override - protected void onPause() { - super.onPause(); - if (fileObserver != null) { - fileObserver.stopWatching(); - } - } - - @Override - protected void onResume() { - super.onResume(); - if (fileObserver != null) { - fileObserver.startWatching(); - } - } - - @Override - public void onStop() { - super.onStop(); - listDirectoriesAdapter = null; - fileObserver = null; - } - - /** - * Change the directory that is currently being displayed. - * - * @param dir - * The file the activity should switch to. This File must be - * non-null and a directory, otherwise the displayed directory - * will not be changed - */ - private void changeDirectory(File dir) { - if (dir != null && dir.isDirectory()) { - File[] contents = dir.listFiles(); - if (contents != null) { - int numDirectories = 0; - for (File f : contents) { - if (f.isDirectory()) { - numDirectories++; - } - } - filesInDir = new File[numDirectories]; - filenames.clear(); - for (int i = 0, counter = 0; i < numDirectories; counter++) { - if (contents[counter].isDirectory()) { - filesInDir[i] = contents[counter]; - filenames.add(contents[counter].getName()); - i++; - } - } - Arrays.sort(filesInDir); - Collections.sort(filenames); - selectedDir = dir; - txtvSelectedFolder.setText(dir.getAbsolutePath()); - listDirectoriesAdapter.notifyDataSetChanged(); - fileObserver = createFileObserver(dir.getAbsolutePath()); - fileObserver.startWatching(); - Log.d(TAG, "Changed directory to " + dir.getAbsolutePath()); - } else { - Log.d(TAG, "Could not change folder: contents of dir were null"); - } - } else { - if (dir == null) { - Log.d(TAG, "Could not change folder: dir was null"); - } else { - Log.d(TAG, "Could not change folder: dir is no directory"); - } - } - refreshButtonState(); - } - - /** - * Changes the state of the buttons depending on the currently selected file - * or folder. - */ - private void refreshButtonState() { - if (selectedDir != null) { - butConfirm.setEnabled(isValidFile(selectedDir)); - supportInvalidateOptionsMenu(); - } - } - - /** Refresh the contents of the directory that is currently shown. */ - private void refreshDirectory() { - if (selectedDir != null) { - changeDirectory(selectedDir); - } - } - - /** Sets up a FileObserver to watch the current directory. */ - private FileObserver createFileObserver(String path) { - return new FileObserver(path, FileObserver.CREATE | FileObserver.DELETE - | FileObserver.MOVED_FROM | FileObserver.MOVED_TO) { - - @Override - public void onEvent(int event, String path) { - Log.d(TAG, "FileObserver received event " + event); - runOnUiThread(DirectoryChooserActivity.this::refreshDirectory); - } - }; - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - menu.findItem(R.id.new_folder_item).setVisible(isValidFile(selectedDir)); - return true; - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - super.onCreateOptionsMenu(menu); - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.directory_chooser, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - NavUtils.navigateUpFromSameTask(this); - return true; - case R.id.new_folder_item: - openNewFolderDialog(); - return true; - case R.id.set_to_default_folder_item: - selectedDir = null; - returnSelectedFolder(); - return true; - default: - return false; - } - } - - /** - * Shows a confirmation dialog that asks the user if he wants to create a - * new folder. - */ - private void openNewFolderDialog() { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.create_folder_label); - builder.setMessage(String.format(getString(R.string.create_folder_msg), - CREATE_DIRECTORY_NAME)); - builder.setNegativeButton(R.string.cancel_label, - (dialog, which) -> dialog.dismiss()); - builder.setPositiveButton(R.string.confirm_label, - (dialog, which) -> { - dialog.dismiss(); - int msg = createFolder(); - Toast t = Toast.makeText(DirectoryChooserActivity.this, - msg, Toast.LENGTH_SHORT); - t.show(); - }); - builder.create().show(); - } - - /** - * Creates a new folder in the current directory with the name - * CREATE_DIRECTORY_NAME. - */ - private int createFolder() { - if (selectedDir == null) { - return R.string.create_folder_error; - } else if (selectedDir.canWrite()) { - File newDir = new File(selectedDir, CREATE_DIRECTORY_NAME); - if (!newDir.exists()) { - boolean result = newDir.mkdir(); - if (result) { - return R.string.create_folder_success; - } else { - return R.string.create_folder_error; - } - } else { - return R.string.create_folder_error_already_exists; - } - } else { - return R.string.create_folder_error_no_write_access; - } - } - - /** 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(); - } - -} 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 d1cd50608..eb8d7ed2f 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/StorageErrorActivity.java @@ -1,38 +1,25 @@ 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 androidx.core.app.ActivityCompat; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.app.AppCompatActivity; import android.text.TextUtils; import android.util.Log; import android.widget.Button; - -import java.io.File; - +import androidx.appcompat.app.AppCompatActivity; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.util.StorageUtils; import de.danoeh.antennapod.dialog.ChooseDataFolderDialog; -/** Is show if there is now external storage available. */ +/** + * Is show if there is now external storage available. + */ 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()); @@ -41,51 +28,7 @@ public class StorageErrorActivity extends AppCompatActivity { setContentView(R.layout.storage_error); Button btnChooseDataFolder = 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 AlertDialog.Builder(this) - .setMessage(R.string.choose_data_directory_permission_rationale) - .setPositiveButton(android.R.string.ok, (dialog, which) -> requestPermission()) - .setNegativeButton(android.R.string.cancel, (dialog, which) -> finish()) - .show(); - } + btnChooseDataFolder.setOnClickListener(v -> showChooseDataFolderDialog()); } @Override @@ -108,7 +51,7 @@ public class StorageErrorActivity extends AppCompatActivity { } } - // see PreferenceController.showChooseDataFolderDialog() + // see StoragePreferencesFragment.showChooseDataFolderDialog() private void showChooseDataFolderDialog() { ChooseDataFolderDialog.showDialog( this, new ChooseDataFolderDialog.RunnableWithString() { @@ -120,43 +63,6 @@ public class StorageErrorActivity extends AppCompatActivity { }); } - public void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, 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); - } - if (path == null) { - return; - } - 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(); - } - } - } - private void leaveErrorState() { finish(); startActivity(new Intent(this, MainActivity.class)); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/StoragePreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/StoragePreferencesFragment.java index 8a0742b7f..a94bb30f1 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/StoragePreferencesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/StoragePreferencesFragment.java @@ -1,18 +1,9 @@ package de.danoeh.antennapod.fragment.preferences; -import android.Manifest; -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.os.Build; import android.os.Bundle; -import android.util.Log; import androidx.appcompat.app.AlertDialog; -import androidx.core.app.ActivityCompat; import androidx.preference.PreferenceFragmentCompat; import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.DirectoryChooserActivity; import de.danoeh.antennapod.activity.PreferenceActivity; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.dialog.ChooseDataFolderDialog; @@ -23,10 +14,6 @@ public class StoragePreferencesFragment extends PreferenceFragmentCompat { private static final String TAG = "StoragePrefFragment"; private static final String PREF_CHOOSE_DATA_DIR = "prefChooseDataDir"; private static final String PREF_IMPORT_EXPORT = "prefImportExport"; - 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; @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { @@ -47,36 +34,9 @@ public class StoragePreferencesFragment extends PreferenceFragmentCompat { } private void setupStorageScreen() { - final Activity activity = getActivity(); findPreference(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; - } - ); - findPreference(PREF_CHOOSE_DATA_DIR).setOnPreferenceClickListener( - preference -> { - if (Build.VERSION.SDK_INT >= 19) { - showChooseDataFolderDialog(); - } else { - Intent intent = new Intent(activity, DirectoryChooserActivity.class); - activity.startActivityForResult(intent, - DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED); - } + showChooseDataFolderDialog(); return true; } ); @@ -104,39 +64,6 @@ public class StoragePreferencesFragment extends PreferenceFragmentCompat { ); } - 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 = getActivity().getExternalFilesDir(null); - } - String message = null; - final Context context = 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(getActivity()); - ab.setMessage(message); - ab.setPositiveButton(android.R.string.ok, null); - ab.show(); - } - } - } - private void setDataFolderText() { File f = UserPreferences.getDataFolder(null); if (f != null) { @@ -144,17 +71,6 @@ public class StoragePreferencesFragment extends PreferenceFragmentCompat { } } - private void requestPermission() { - ActivityCompat.requestPermissions(getActivity(), EXTERNAL_STORAGE_PERMISSIONS, - PERMISSION_REQUEST_EXTERNAL_STORAGE); - } - - private void openDirectoryChooser() { - Activity activity = getActivity(); - Intent intent = new Intent(activity, DirectoryChooserActivity.class); - activity.startActivityForResult(intent, DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED); - } - private void showChooseDataFolderDialog() { ChooseDataFolderDialog.showDialog( getActivity(), new ChooseDataFolderDialog.RunnableWithString() { diff --git a/app/src/main/res/layout/directory_chooser.xml b/app/src/main/res/layout/directory_chooser.xml deleted file mode 100644 index fbe5a3d19..000000000 --- a/app/src/main/res/layout/directory_chooser.xml +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - -