Merge pull request #1507 from mfietz/issue/1506-preferencecontroller-npe

PreferenceController: Prevent NPE in Data Folder Chooser
This commit is contained in:
Martin Fietz 2016-01-05 13:59:41 +01:00
commit 15e68d53ba
2 changed files with 47 additions and 14 deletions

View File

@ -695,34 +695,56 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
private void showChooseDataFolderDialog() { private void showChooseDataFolderDialog() {
Context context = ui.getActivity(); Context context = ui.getActivity();
String dataFolder = UserPreferences.getDataFolder(null).getAbsolutePath(); File dataFolder = UserPreferences.getDataFolder(null);
if(dataFolder == null) {
new MaterialDialog.Builder(ui.getActivity())
.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; int selectedIndex = -1;
File[] mediaDirs = ContextCompat.getExternalFilesDirs(context, null); File[] mediaDirs = ContextCompat.getExternalFilesDirs(context, null);
String[] folders = new String[mediaDirs.length]; List<String> folders = new ArrayList<>(mediaDirs.length);
CharSequence[] choices = new CharSequence[mediaDirs.length]; List<CharSequence> choices = new ArrayList<>(mediaDirs.length);
for(int i=0; i < mediaDirs.length; i++) { for(int i=0; i < mediaDirs.length; i++) {
String path = folders[i] = mediaDirs[i].getAbsolutePath(); if(mediaDirs[i] == null) {
if(dataFolder.equals(path)) { continue;
}
String path = mediaDirs[i].getAbsolutePath();
folders.add(path);
if(dataFolderPath.equals(path)) {
selectedIndex = i; selectedIndex = i;
} }
int index = path.indexOf("Android"); int index = path.indexOf("Android");
String choice;
if(index >= 0) { if(index >= 0) {
choices[i] = path.substring(0, index); choice = path.substring(0, index);
} else { } else {
choices[i] = path; choice = path;
} }
long bytes = StorageUtils.getFreeSpaceAvailable(); long bytes = StorageUtils.getFreeSpaceAvailable(path);
String freeSpace = String.format(context.getString(R.string.free_space_label), String freeSpace = String.format(context.getString(R.string.free_space_label),
Converter.byteToString(bytes)); Converter.byteToString(bytes));
choices[i] = Html.fromHtml("<html><small>" + choices[i] choices.add(Html.fromHtml("<html><small>" + choice
+ " [" + freeSpace + "]" + "</small></html>"); + " [" + freeSpace + "]" + "</small></html>"));
}
if(choices.size() == 0) {
new MaterialDialog.Builder(ui.getActivity())
.title(R.string.error_label)
.content(R.string.external_storage_error_msg)
.neutralText(android.R.string.ok)
.show();
return;
} }
MaterialDialog dialog = new MaterialDialog.Builder(ui.getActivity()) MaterialDialog dialog = new MaterialDialog.Builder(ui.getActivity())
.title(R.string.choose_data_directory) .title(R.string.choose_data_directory)
.content(R.string.choose_data_directory_message) .content(R.string.choose_data_directory_message)
.items(choices) .items(choices.toArray(new CharSequence[choices.size()]))
.itemsCallbackSingleChoice(selectedIndex, (dialog1, itemView, which, text) -> { .itemsCallbackSingleChoice(selectedIndex, (dialog1, itemView, which, text) -> {
String folder = folders[which]; String folder = folders.get(which);
Log.d(TAG, "data folder: " + folder); Log.d(TAG, "data folder: " + folder);
UserPreferences.setDataFolder(folder); UserPreferences.setDataFolder(folder);
setDataFolderText(); setDataFolderText();

View File

@ -51,8 +51,19 @@ public class StorageUtils {
* Get the number of free bytes that are available on the external storage. * Get the number of free bytes that are available on the external storage.
*/ */
public static long getFreeSpaceAvailable() { public static long getFreeSpaceAvailable() {
StatFs stat = new StatFs(UserPreferences.getDataFolder( File dataFolder = UserPreferences.getDataFolder(null);
null).getAbsolutePath()); if (dataFolder != null) {
return getFreeSpaceAvailable(dataFolder.getAbsolutePath());
} else {
return 0;
}
}
/**
* Get the number of free bytes that are available on the external storage.
*/
public static long getFreeSpaceAvailable(String path) {
StatFs stat = new StatFs(path);
long availableBlocks; long availableBlocks;
long blockSize; long blockSize;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {