Android: Show warning after picking file with wrong extension

This commit is contained in:
JosJuice 2020-11-04 23:09:00 +01:00
parent 73f013e3cc
commit 62e6bedd25
6 changed files with 119 additions and 9 deletions

View File

@ -175,12 +175,14 @@ public final class SettingsActivity extends AppCompatActivity implements Setting
if (requestCode == MainPresenter.REQUEST_SD_FILE)
{
Uri uri = canonicalizeIfPossible(result.getData());
int takeFlags = result.getFlags() &
(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
getContentResolver().takePersistableUriPermission(uri, takeFlags);
getFragment().getAdapter().onFilePickerConfirmation(uri.toString());
FileBrowserHelper.runAfterExtensionCheck(this, uri, FileBrowserHelper.RAW_EXTENSION, () ->
{
getContentResolver().takePersistableUriPermission(uri, takeFlags);
getFragment().getAdapter().onFilePickerConfirmation(uri.toString());
});
}
else
{

View File

@ -205,7 +205,9 @@ public final class MainActivity extends AppCompatActivity implements MainView
break;
case MainPresenter.REQUEST_WAD_FILE:
mPresenter.installWAD(result.getData().toString());
FileBrowserHelper.runAfterExtensionCheck(this, result.getData(),
FileBrowserHelper.WAD_EXTENSION,
() -> mPresenter.installWAD(result.getData().toString()));
break;
}
}

View File

@ -229,7 +229,9 @@ public final class TvMainActivity extends FragmentActivity implements MainView
break;
case MainPresenter.REQUEST_WAD_FILE:
mPresenter.installWAD(result.getData().toString());
FileBrowserHelper.runAfterExtensionCheck(this, result.getData(),
FileBrowserHelper.WAD_EXTENSION,
() -> mPresenter.installWAD(result.getData().toString()));
break;
}
}

View File

@ -1,8 +1,13 @@
package org.dolphinemu.dolphinemu.utils;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.dolphinemu.dolphinemu.DolphinApplication;
@ -14,8 +19,7 @@ public class ContentHandler
{
try
{
return DolphinApplication.getAppContext().getContentResolver()
.openFileDescriptor(Uri.parse(uri), mode).detachFd();
return getContentResolver().openFileDescriptor(Uri.parse(uri), mode).detachFd();
}
// Some content providers throw IllegalArgumentException for invalid modes,
// despite the documentation saying that invalid modes result in a FileNotFoundException
@ -29,8 +33,7 @@ public class ContentHandler
{
try
{
ContentResolver resolver = DolphinApplication.getAppContext().getContentResolver();
return DocumentsContract.deleteDocument(resolver, Uri.parse(uri));
return DocumentsContract.deleteDocument(getContentResolver(), Uri.parse(uri));
}
catch (FileNotFoundException e)
{
@ -38,4 +41,24 @@ public class ContentHandler
return true;
}
}
@Nullable
public static String getDisplayName(@NonNull Uri uri)
{
final String[] projection = new String[]{Document.COLUMN_DISPLAY_NAME};
try (Cursor cursor = getContentResolver().query(uri, projection, null, null, null))
{
if (cursor != null && cursor.moveToFirst())
{
return cursor.getString(0);
}
}
return null;
}
private static ContentResolver getContentResolver()
{
return DolphinApplication.getAppContext().getContentResolver();
}
}

View File

@ -1,23 +1,28 @@
package org.dolphinemu.dolphinemu.utils;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentActivity;
import com.nononsenseapps.filepicker.FilePickerActivity;
import com.nononsenseapps.filepicker.Utils;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.activities.CustomFilePickerActivity;
import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public final class FileBrowserHelper
{
@ -27,6 +32,9 @@ public final class FileBrowserHelper
public static final HashSet<String> RAW_EXTENSION = new HashSet<>(Collections.singletonList(
"raw"));
public static final HashSet<String> WAD_EXTENSION = new HashSet<>(Collections.singletonList(
"wad"));
public static void openDirectoryPicker(FragmentActivity activity, HashSet<String> extensions)
{
Intent i = new Intent(activity, CustomFilePickerActivity.class);
@ -85,4 +93,72 @@ public final class FileBrowserHelper
return null;
}
public static void runAfterExtensionCheck(Context context, Uri uri, Set<String> validExtensions,
Runnable runnable)
{
String extension = null;
String path = uri.getLastPathSegment();
if (path != null)
extension = getExtension(new File(path).getName());
if (extension == null)
extension = getExtension(ContentHandler.getDisplayName(uri));
if (extension != null && validExtensions.contains(extension))
{
runnable.run();
return;
}
String message;
if (extension == null)
{
message = context.getString(R.string.no_file_extension);
}
else
{
int messageId = validExtensions.size() == 1 ?
R.string.wrong_file_extension_single : R.string.wrong_file_extension_multiple;
ArrayList<String> extensionsList = new ArrayList<>(validExtensions);
Collections.sort(extensionsList);
message = context.getString(messageId, extension, join(", ", extensionsList));
}
new AlertDialog.Builder(context, R.style.DolphinDialogBase)
.setMessage(message)
.setPositiveButton(R.string.yes, (dialogInterface, i) -> runnable.run())
.setNegativeButton(R.string.no, null)
.show();
}
@Nullable
private static String getExtension(@Nullable String fileName)
{
if (fileName == null)
return null;
int dotIndex = fileName.lastIndexOf(".");
return dotIndex != -1 ? fileName.substring(dotIndex + 1) : null;
}
// TODO: Replace this with String.join once we can use Java 8
private static String join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
{
StringBuilder sb = new StringBuilder();
boolean first = true;
for (CharSequence element : elements)
{
if (!first)
sb.append(delimiter);
first = false;
sb.append(element);
}
return sb.toString();
}
}

View File

@ -427,6 +427,11 @@ It can efficiently compress both junk data and encrypted Wii data.
<string name="select_dir">Select This Directory</string>
<!-- File Pickers -->
<string name="no_file_extension">The selected file does not appear to have a file name extension.\n\nContinue anyway?</string>
<string name="wrong_file_extension_single">The selected file has the file name extension \"%1$s\", but \"%2$s\" was expected.\n\nContinue anyway?</string>
<string name="wrong_file_extension_multiple">The selected file has the file name extension \"%1$s\", but one of these extensions was expected: %2$s\n\nContinue anyway?</string>
<!-- Misc -->
<string name="pitch">Total Pitch</string>
<string name="yaw">Total Yaw</string>