mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-26 15:55:31 +01:00
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.BuildConfig;
|
||||||
import org.dolphinemu.dolphinemu.NativeLibrary;
|
import org.dolphinemu.dolphinemu.NativeLibrary;
|
||||||
import org.dolphinemu.dolphinemu.R;
|
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.features.settings.ui.MenuTag;
|
||||||
import org.dolphinemu.dolphinemu.model.GameFileCache;
|
import org.dolphinemu.dolphinemu.model.GameFileCache;
|
||||||
import org.dolphinemu.dolphinemu.services.GameFileCacheService;
|
import org.dolphinemu.dolphinemu.services.GameFileCacheService;
|
||||||
import org.dolphinemu.dolphinemu.utils.AfterDirectoryInitializationRunner;
|
import org.dolphinemu.dolphinemu.utils.AfterDirectoryInitializationRunner;
|
||||||
|
import org.dolphinemu.dolphinemu.utils.ContentHandler;
|
||||||
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper;
|
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public final class MainPresenter
|
public final class MainPresenter
|
||||||
@ -123,9 +126,21 @@ public final class MainPresenter
|
|||||||
|
|
||||||
public void onDirectorySelected(Intent result)
|
public void onDirectorySelected(Intent result)
|
||||||
{
|
{
|
||||||
ContentResolver contentResolver = mContext.getContentResolver();
|
|
||||||
Uri uri = result.getData();
|
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);
|
Uri canonicalizedUri = contentResolver.canonicalize(uri);
|
||||||
if (canonicalizedUri != null)
|
if (canonicalizedUri != null)
|
||||||
uri = canonicalizedUri;
|
uri = canonicalizedUri;
|
||||||
|
@ -14,6 +14,7 @@ import androidx.annotation.Keep;
|
|||||||
import org.dolphinemu.dolphinemu.DolphinApplication;
|
import org.dolphinemu.dolphinemu.DolphinApplication;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -166,26 +167,52 @@ public class ContentHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NonNull @Keep
|
@NonNull @Keep
|
||||||
public static String[] getChildNames(@NonNull String uri)
|
public static String[] getChildNames(@NonNull String uri, boolean recursive)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Uri unmangledUri = unmangle(uri);
|
return getChildNames(unmangle(uri), recursive);
|
||||||
String documentId = DocumentsContract.getDocumentId(treeToDocument(unmangledUri));
|
}
|
||||||
Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(unmangledUri, documentId);
|
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))
|
try (Cursor cursor = getContentResolver().query(childrenUri, projection, null, null, null))
|
||||||
{
|
{
|
||||||
if (cursor != null)
|
if (cursor != null)
|
||||||
{
|
{
|
||||||
String[] result = new String[cursor.getCount()];
|
while (cursor.moveToNext())
|
||||||
for (int i = 0; i < result.length; i++)
|
|
||||||
{
|
{
|
||||||
cursor.moveToNext();
|
if (recursive && Document.MIME_TYPE_DIR.equals(cursor.getString(1)))
|
||||||
result[i] = cursor.getString(0);
|
{
|
||||||
|
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)
|
catch (Exception ignored)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
return new String[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
@ -102,10 +102,8 @@ public final class FileBrowserHelper
|
|||||||
int messageId = validExtensions.size() == 1 ?
|
int messageId = validExtensions.size() == 1 ?
|
||||||
R.string.wrong_file_extension_single : R.string.wrong_file_extension_multiple;
|
R.string.wrong_file_extension_single : R.string.wrong_file_extension_multiple;
|
||||||
|
|
||||||
ArrayList<String> extensionsList = new ArrayList<>(validExtensions);
|
message = context.getString(messageId, extension,
|
||||||
Collections.sort(extensionsList);
|
setToSortedDelimitedString(validExtensions));
|
||||||
|
|
||||||
message = context.getString(messageId, extension, join(", ", extensionsList));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
new AlertDialog.Builder(context, R.style.DolphinDialogBase)
|
new AlertDialog.Builder(context, R.style.DolphinDialogBase)
|
||||||
@ -117,7 +115,7 @@ public final class FileBrowserHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static String getExtension(@Nullable String fileName)
|
public static String getExtension(@Nullable String fileName)
|
||||||
{
|
{
|
||||||
if (fileName == null)
|
if (fileName == null)
|
||||||
return null;
|
return null;
|
||||||
@ -126,6 +124,13 @@ public final class FileBrowserHelper
|
|||||||
return dotIndex != -1 ? fileName.substring(dotIndex + 1) : null;
|
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
|
// TODO: Replace this with String.join once we can use Java 8
|
||||||
private static String join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
|
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="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_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_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>
|
<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 -->
|
<!-- Misc -->
|
||||||
|
@ -124,9 +124,9 @@ std::string GetAndroidContentDisplayName(const std::string& uri)
|
|||||||
std::vector<std::string> GetAndroidContentChildNames(const std::string& uri)
|
std::vector<std::string> GetAndroidContentChildNames(const std::string& uri)
|
||||||
{
|
{
|
||||||
JNIEnv* env = IDCache::GetEnvForThread();
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
jobject children =
|
jobject children = env->CallStaticObjectMethod(IDCache::GetContentHandlerClass(),
|
||||||
env->CallStaticObjectMethod(IDCache::GetContentHandlerClass(),
|
IDCache::GetContentHandlerGetChildNames(),
|
||||||
IDCache::GetContentHandlerGetChildNames(), ToJString(env, uri));
|
ToJString(env, uri), false);
|
||||||
return JStringArrayToVector(env, reinterpret_cast<jobjectArray>(children));
|
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.
|
// An empty string will be returned for files which do not exist.
|
||||||
std::string GetAndroidContentDisplayName(const std::string& uri);
|
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);
|
std::vector<std::string> GetAndroidContentChildNames(const std::string& uri);
|
||||||
|
|
||||||
int GetNetworkIpAddress();
|
int GetNetworkIpAddress();
|
||||||
|
@ -330,7 +330,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
|||||||
s_content_handler_get_display_name = env->GetStaticMethodID(
|
s_content_handler_get_display_name = env->GetStaticMethodID(
|
||||||
s_content_handler_class, "getDisplayName", "(Ljava/lang/String;)Ljava/lang/String;");
|
s_content_handler_class, "getDisplayName", "(Ljava/lang/String;)Ljava/lang/String;");
|
||||||
s_content_handler_get_child_names = env->GetStaticMethodID(
|
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 =
|
const jclass network_helper_class =
|
||||||
env->FindClass("org/dolphinemu/dolphinemu/utils/NetworkHelper");
|
env->FindClass("org/dolphinemu/dolphinemu/utils/NetworkHelper");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user