Android: Show a message when adding a folder with no games
To catch people who try to use unsupported formats.
This commit is contained in:
parent
399ede37a6
commit
73855168f3
|
@ -15,12 +15,15 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
|||
import org.dolphinemu.dolphinemu.BuildConfig;
|
||||
import org.dolphinemu.dolphinemu.NativeLibrary;
|
||||
import org.dolphinemu.dolphinemu.R;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag;
|
||||
import org.dolphinemu.dolphinemu.model.GameFileCache;
|
||||
import org.dolphinemu.dolphinemu.services.GameFileCacheService;
|
||||
import org.dolphinemu.dolphinemu.utils.AfterDirectoryInitializationRunner;
|
||||
import org.dolphinemu.dolphinemu.utils.ContentHandler;
|
||||
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
|
||||
public final class MainPresenter
|
||||
|
@ -123,9 +126,21 @@ public final class MainPresenter
|
|||
|
||||
public void onDirectorySelected(Intent result)
|
||||
{
|
||||
ContentResolver contentResolver = mContext.getContentResolver();
|
||||
Uri uri = result.getData();
|
||||
|
||||
boolean recursive = BooleanSetting.MAIN_RECURSIVE_ISO_PATHS.getBooleanGlobal();
|
||||
String[] childNames = ContentHandler.getChildNames(uri, recursive);
|
||||
if (Arrays.stream(childNames).noneMatch((name) ->
|
||||
FileBrowserHelper.GAME_EXTENSIONS.contains(FileBrowserHelper.getExtension(name))))
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(mContext, R.style.DolphinDialogBase);
|
||||
builder.setMessage(mContext.getString(R.string.wrong_file_extension_in_directory,
|
||||
FileBrowserHelper.setToSortedDelimitedString(FileBrowserHelper.GAME_EXTENSIONS)));
|
||||
builder.setPositiveButton(R.string.ok, null);
|
||||
builder.show();
|
||||
}
|
||||
|
||||
ContentResolver contentResolver = mContext.getContentResolver();
|
||||
Uri canonicalizedUri = contentResolver.canonicalize(uri);
|
||||
if (canonicalizedUri != null)
|
||||
uri = canonicalizedUri;
|
||||
|
|
|
@ -14,6 +14,7 @@ import androidx.annotation.Keep;
|
|||
import org.dolphinemu.dolphinemu.DolphinApplication;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
|
@ -166,26 +167,52 @@ public class ContentHandler
|
|||
}
|
||||
|
||||
@NonNull @Keep
|
||||
public static String[] getChildNames(@NonNull String uri)
|
||||
public static String[] getChildNames(@NonNull String uri, boolean recursive)
|
||||
{
|
||||
try
|
||||
{
|
||||
Uri unmangledUri = unmangle(uri);
|
||||
String documentId = DocumentsContract.getDocumentId(treeToDocument(unmangledUri));
|
||||
Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(unmangledUri, documentId);
|
||||
return getChildNames(unmangle(uri), recursive);
|
||||
}
|
||||
catch (Exception ignored)
|
||||
{
|
||||
}
|
||||
|
||||
final String[] projection = new String[]{Document.COLUMN_DISPLAY_NAME};
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String[] getChildNames(@NonNull Uri uri, boolean recursive)
|
||||
{
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
getChildNames(uri, DocumentsContract.getDocumentId(treeToDocument(uri)), recursive, result);
|
||||
return result.toArray(new String[0]);
|
||||
}
|
||||
|
||||
private static void getChildNames(@NonNull Uri uri, @NonNull String documentId, boolean recursive,
|
||||
List<String> resultOut)
|
||||
{
|
||||
try
|
||||
{
|
||||
Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(uri, documentId);
|
||||
|
||||
final String[] projection = recursive ? new String[]{Document.COLUMN_DISPLAY_NAME,
|
||||
Document.COLUMN_MIME_TYPE, Document.COLUMN_DOCUMENT_ID} :
|
||||
new String[]{Document.COLUMN_DISPLAY_NAME};
|
||||
try (Cursor cursor = getContentResolver().query(childrenUri, projection, null, null, null))
|
||||
{
|
||||
if (cursor != null)
|
||||
{
|
||||
String[] result = new String[cursor.getCount()];
|
||||
for (int i = 0; i < result.length; i++)
|
||||
while (cursor.moveToNext())
|
||||
{
|
||||
cursor.moveToNext();
|
||||
result[i] = cursor.getString(0);
|
||||
if (recursive && Document.MIME_TYPE_DIR.equals(cursor.getString(1)))
|
||||
{
|
||||
getChildNames(uri, cursor.getString(2), recursive, resultOut);
|
||||
}
|
||||
else
|
||||
{
|
||||
resultOut.add(cursor.getString(0));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -196,8 +223,6 @@ public class ContentHandler
|
|||
catch (Exception ignored)
|
||||
{
|
||||
}
|
||||
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
|
|
@ -102,10 +102,8 @@ public final class FileBrowserHelper
|
|||
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));
|
||||
message = context.getString(messageId, extension,
|
||||
setToSortedDelimitedString(validExtensions));
|
||||
}
|
||||
|
||||
new AlertDialog.Builder(context, R.style.DolphinDialogBase)
|
||||
|
@ -117,7 +115,7 @@ public final class FileBrowserHelper
|
|||
}
|
||||
|
||||
@Nullable
|
||||
private static String getExtension(@Nullable String fileName)
|
||||
public static String getExtension(@Nullable String fileName)
|
||||
{
|
||||
if (fileName == null)
|
||||
return null;
|
||||
|
@ -126,6 +124,13 @@ public final class FileBrowserHelper
|
|||
return dotIndex != -1 ? fileName.substring(dotIndex + 1) : null;
|
||||
}
|
||||
|
||||
public static String setToSortedDelimitedString(Set<String> set)
|
||||
{
|
||||
ArrayList<String> list = new ArrayList<>(set);
|
||||
Collections.sort(list);
|
||||
return join(", ", list);
|
||||
}
|
||||
|
||||
// TODO: Replace this with String.join once we can use Java 8
|
||||
private static String join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
|
||||
{
|
||||
|
|
|
@ -438,6 +438,7 @@ It can efficiently compress both junk data and encrypted Wii data.
|
|||
<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>
|
||||
<string name="wrong_file_extension_in_directory">No compatible files were found in the selected location.\n\nThe supported formats are: %1$s</string>
|
||||
<string name="unavailable_paths">Dolphin does not have permission to access one or more configured paths. Would you like to fix this before starting?</string>
|
||||
|
||||
<!-- Misc -->
|
||||
|
|
|
@ -124,9 +124,9 @@ std::string GetAndroidContentDisplayName(const std::string& uri)
|
|||
std::vector<std::string> GetAndroidContentChildNames(const std::string& uri)
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject children =
|
||||
env->CallStaticObjectMethod(IDCache::GetContentHandlerClass(),
|
||||
IDCache::GetContentHandlerGetChildNames(), ToJString(env, uri));
|
||||
jobject children = env->CallStaticObjectMethod(IDCache::GetContentHandlerClass(),
|
||||
IDCache::GetContentHandlerGetChildNames(),
|
||||
ToJString(env, uri), false);
|
||||
return JStringArrayToVector(env, reinterpret_cast<jobjectArray>(children));
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ jlong GetAndroidContentSizeAndIsDirectory(const std::string& uri);
|
|||
// An empty string will be returned for files which do not exist.
|
||||
std::string GetAndroidContentDisplayName(const std::string& uri);
|
||||
|
||||
// Returns the display names of all children of a directory.
|
||||
// Returns the display names of all children of a directory, non-recursively.
|
||||
std::vector<std::string> GetAndroidContentChildNames(const std::string& uri);
|
||||
|
||||
int GetNetworkIpAddress();
|
||||
|
|
|
@ -330,7 +330,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
|||
s_content_handler_get_display_name = env->GetStaticMethodID(
|
||||
s_content_handler_class, "getDisplayName", "(Ljava/lang/String;)Ljava/lang/String;");
|
||||
s_content_handler_get_child_names = env->GetStaticMethodID(
|
||||
s_content_handler_class, "getChildNames", "(Ljava/lang/String;)[Ljava/lang/String;");
|
||||
s_content_handler_class, "getChildNames", "(Ljava/lang/String;Z)[Ljava/lang/String;");
|
||||
|
||||
const jclass network_helper_class =
|
||||
env->FindClass("org/dolphinemu/dolphinemu/utils/NetworkHelper");
|
||||
|
|
Loading…
Reference in New Issue