mirror of
https://github.com/libretro/Play-.git
synced 2025-01-30 05:01:53 +00:00
Android: backend support for a file locator
Automatically lists all files that fit the extension and sets the root game folder when one of the items is selected. Clicking the Reset Folder preference will remove the stored base folder and return to the complete list. TODO: Add a method to refresh the list when clearing the preference or returning from the emulator. Conflicts: Source/ui_android/java/com/virtualapplications/play/MainActivity.java
This commit is contained in:
parent
5a9714eb90
commit
0b0b198501
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,6 +1,6 @@
|
||||
libPlay.so
|
||||
build_android/bin
|
||||
build_android/gen
|
||||
build_android/libs
|
||||
build_android/obj
|
||||
build_android/jni/ExternalDependencies.mk
|
||||
build_android/local.properties
|
||||
@ -17,5 +17,6 @@ ReleaseAot
|
||||
*.suo
|
||||
*.user
|
||||
*.userprops
|
||||
*.orig
|
||||
xcuserdata
|
||||
|
||||
|
73
Source/ui_android/java/com/android/util/FileUtils.java
Executable file
73
Source/ui_android/java/com/android/util/FileUtils.java
Executable file
@ -0,0 +1,73 @@
|
||||
package com.android.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.nio.IntBuffer;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
public class FileUtils {
|
||||
|
||||
public void saveArray(String filename, List<String> output_field) {
|
||||
try {
|
||||
FileOutputStream fos = new FileOutputStream(filename);
|
||||
GZIPOutputStream gzos = new GZIPOutputStream(fos);
|
||||
ObjectOutputStream out = new ObjectOutputStream(gzos);
|
||||
out.writeObject(output_field);
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
e.getStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<String> loadArray(String filename) {
|
||||
try {
|
||||
FileInputStream fis = new FileInputStream(filename);
|
||||
GZIPInputStream gzis = new GZIPInputStream(fis);
|
||||
ObjectInputStream in = new ObjectInputStream(gzis);
|
||||
List<String> read_field = (List<String>) in.readObject();
|
||||
in.close();
|
||||
return read_field;
|
||||
} catch (Exception e) {
|
||||
e.getStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Collection<File> listFiles(File directory, FilenameFilter[] filter,
|
||||
int recurse) {
|
||||
|
||||
Vector<File> files = new Vector<File>();
|
||||
|
||||
File[] entries = directory.listFiles();
|
||||
|
||||
if (entries != null) {
|
||||
for (File entry : entries) {
|
||||
for (FilenameFilter filefilter : filter) {
|
||||
if (filter == null
|
||||
|| filefilter.accept(directory, entry.getName())) {
|
||||
files.add(entry);
|
||||
}
|
||||
}
|
||||
if ((recurse <= -1) || (recurse > 0 && entry.isDirectory())) {
|
||||
recurse--;
|
||||
files.addAll(listFiles(entry, filter, recurse));
|
||||
recurse++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
}
|
@ -12,6 +12,8 @@ import java.io.*;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import com.android.util.FileUtils;
|
||||
|
||||
public class MainActivity extends Activity
|
||||
{
|
||||
@ -21,6 +23,8 @@ public class MainActivity extends Activity
|
||||
private FileListItem[] _fileListItems;
|
||||
private ListView _fileListView;
|
||||
private TextView _fileListViewHeader;
|
||||
private ArrayList<FileListItem> fileListItems;
|
||||
private static Activity mActivity;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
@ -30,6 +34,8 @@ public class MainActivity extends Activity
|
||||
|
||||
setContentView(R.layout.main);
|
||||
|
||||
mActivity = MainActivity.this;
|
||||
|
||||
File filesDir = getFilesDir();
|
||||
NativeInterop.setFilesDirPath(Environment.getExternalStorageDirectory().getAbsolutePath());
|
||||
|
||||
@ -42,22 +48,40 @@ public class MainActivity extends Activity
|
||||
}
|
||||
|
||||
prepareFileListView();
|
||||
updateFileListView();
|
||||
// updateFileListView();
|
||||
|
||||
String sdcard = getCurrentDirectory();
|
||||
|
||||
new ImageFinder(R.array.disks).execute(sdcard);
|
||||
new ImageFinder(R.array.elves).execute(sdcard);
|
||||
|
||||
if (sdcard.equals(Environment.getExternalStorageDirectory().getAbsolutePath())) {
|
||||
HashSet<String> extStorage = MainActivity.getExternalMounts();
|
||||
if (extStorage != null && !extStorage.isEmpty()) {
|
||||
for (Iterator<String> sd = extStorage.iterator(); sd.hasNext();) {
|
||||
String sdCardPath = sd.next().replace("mnt/media_rw", "storage");
|
||||
if (!sdCardPath.equals(sdcard)) {
|
||||
if (new File(sdCardPath).canRead()) {
|
||||
new ImageFinder(R.array.disks).execute(sdCardPath);
|
||||
new ImageFinder(R.array.elves).execute(sdCardPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed()
|
||||
{
|
||||
File currentDirectoryFile = new File(getCurrentDirectory());
|
||||
File parentDirectoryFile = currentDirectoryFile.getParentFile();
|
||||
if(parentDirectoryFile == null) {
|
||||
finish();
|
||||
} else {
|
||||
setCurrentDirectory(currentDirectoryFile.getParentFile().getAbsolutePath());
|
||||
updateFileListView();
|
||||
}
|
||||
|
||||
}
|
||||
// @Override
|
||||
// public void onBackPressed()
|
||||
// {
|
||||
// File currentDirectoryFile = new File(getCurrentDirectory());
|
||||
// File parentDirectoryFile = currentDirectoryFile.getParentFile();
|
||||
// if(parentDirectoryFile == null) {
|
||||
// finish();
|
||||
// }
|
||||
// setCurrentDirectory(currentDirectoryFile.getParentFile().getAbsolutePath());
|
||||
// updateFileListView();
|
||||
// }
|
||||
|
||||
private static long getBuildDate(Context context)
|
||||
{
|
||||
@ -144,6 +168,42 @@ public class MainActivity extends Activity
|
||||
return _preferences.getString(PREFERENCE_CURRENT_DIRECTORY, Environment.getExternalStorageDirectory().getAbsolutePath());
|
||||
}
|
||||
|
||||
public static HashSet<String> getExternalMounts() {
|
||||
final HashSet<String> out = new HashSet<String>();
|
||||
String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4|fuse).*rw.*";
|
||||
String s = "";
|
||||
try {
|
||||
final java.lang.Process process = new ProcessBuilder().command("mount")
|
||||
.redirectErrorStream(true).start();
|
||||
process.waitFor();
|
||||
final InputStream is = process.getInputStream();
|
||||
final byte[] buffer = new byte[1024];
|
||||
while (is.read(buffer) != -1) {
|
||||
s = s + new String(buffer);
|
||||
}
|
||||
is.close();
|
||||
} catch (final Exception e) {
|
||||
|
||||
}
|
||||
|
||||
final String[] lines = s.split("\n");
|
||||
for (String line : lines) {
|
||||
if (StringUtils.containsIgnoreCase(line, "secure"))
|
||||
continue;
|
||||
if (StringUtils.containsIgnoreCase(line, "asec"))
|
||||
continue;
|
||||
if (line.matches(reg)) {
|
||||
String[] parts = line.split(" ");
|
||||
for (String part : parts) {
|
||||
if (part.startsWith("/"))
|
||||
if (!StringUtils.containsIgnoreCase(part, "vold"))
|
||||
out.add(part);
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
private void setCurrentDirectory(String currentDirectory)
|
||||
{
|
||||
SharedPreferences.Editor preferencesEditor = _preferences.edit();
|
||||
@ -151,6 +211,17 @@ public class MainActivity extends Activity
|
||||
preferencesEditor.commit();
|
||||
}
|
||||
|
||||
private void clearCurrentDirectory()
|
||||
{
|
||||
SharedPreferences.Editor preferencesEditor = _preferences.edit();
|
||||
preferencesEditor.remove(PREFERENCE_CURRENT_DIRECTORY);
|
||||
preferencesEditor.commit();
|
||||
}
|
||||
|
||||
public static void resetDirectory() {
|
||||
((MainActivity) mActivity).clearCurrentDirectory();
|
||||
}
|
||||
|
||||
private static boolean IsLoadableExecutableFileName(String fileName)
|
||||
{
|
||||
return fileName.toLowerCase().endsWith(".elf");
|
||||
@ -166,6 +237,100 @@ public class MainActivity extends Activity
|
||||
fileName.toLowerCase().endsWith(".isz");
|
||||
}
|
||||
|
||||
private final class ImageFinder extends AsyncTask<String, Integer, List<File>> {
|
||||
|
||||
private int array;
|
||||
|
||||
public ImageFinder(int arrayType) {
|
||||
this.array = arrayType;
|
||||
}
|
||||
|
||||
protected void onPreExecute() {
|
||||
_fileListView.setOnItemClickListener(
|
||||
new OnItemClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
|
||||
{
|
||||
//Remove one to compensate for header
|
||||
position = position - 1;
|
||||
|
||||
FileListItem fileListItem = _fileListItems[position];
|
||||
try
|
||||
{
|
||||
if(IsLoadableExecutableFileName(fileListItem.getPath()))
|
||||
{
|
||||
NativeInterop.loadElf(fileListItem.getPath());
|
||||
}
|
||||
else
|
||||
{
|
||||
NativeInterop.bootDiskImage(fileListItem.getPath());
|
||||
}
|
||||
setCurrentDirectory(fileListItem.getPath().substring(0, fileListItem.getPath().lastIndexOf(File.separator)));
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
displaySimpleMessage("Error", ex.getMessage());
|
||||
return;
|
||||
}
|
||||
//TODO: Catch errors that might happen while loading files
|
||||
Intent intent = new Intent(getApplicationContext(), EmulatorActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<File> doInBackground(String... paths) {
|
||||
File storage = new File(paths[0]);
|
||||
|
||||
String[] mediaTypes = MainActivity.this.getResources().getStringArray(array);
|
||||
FilenameFilter[] filter = new FilenameFilter[mediaTypes.length];
|
||||
|
||||
int i = 0;
|
||||
for (final String type : mediaTypes) {
|
||||
filter[i] = new FilenameFilter() {
|
||||
|
||||
public boolean accept(File dir, String name) {
|
||||
if (dir.getName().startsWith(".") || name.startsWith(".")) {
|
||||
return false;
|
||||
} else {
|
||||
return StringUtils.endsWithIgnoreCase(name, "." + type);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
i++;
|
||||
}
|
||||
|
||||
FileUtils fileUtils = new FileUtils();
|
||||
Collection<File> files = fileUtils.listFiles(storage, filter, -1);
|
||||
return (List<File>) files;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<File> images) {
|
||||
if (images != null && !images.isEmpty()) {
|
||||
// Create the list of acceptable images
|
||||
for(File file : images)
|
||||
{
|
||||
fileListItems.add(new FileListItem(file.getAbsolutePath()));
|
||||
}
|
||||
|
||||
Collections.sort(fileListItems);
|
||||
|
||||
_fileListItems = fileListItems.toArray(new FileListItem[images.size()]);
|
||||
|
||||
ArrayAdapter<FileListItem> adapter = new ArrayAdapter<FileListItem>(MainActivity.this,
|
||||
android.R.layout.simple_list_item_1, android.R.id.text1, _fileListItems);
|
||||
_fileListView.setAdapter(adapter);
|
||||
} else {
|
||||
// Display warning that no disks exist
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static FileListItem[] getFileList(String directoryPath)
|
||||
{
|
||||
ArrayList<FileListItem> fileListItems = new ArrayList<FileListItem>();
|
||||
@ -203,54 +368,56 @@ public class MainActivity extends Activity
|
||||
|
||||
_fileListView.addHeaderView(header, null, false);
|
||||
|
||||
_fileListView.setOnItemClickListener(
|
||||
new OnItemClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
|
||||
{
|
||||
//Remove one to compensate for header
|
||||
position = position - 1;
|
||||
|
||||
FileListItem fileListItem = _fileListItems[position];
|
||||
if(fileListItem.isParentDirectory())
|
||||
{
|
||||
File currentDirectoryFile = new File(getCurrentDirectory());
|
||||
File parentDirectoryFile = currentDirectoryFile.getParentFile();
|
||||
if(parentDirectoryFile == null) return;
|
||||
setCurrentDirectory(currentDirectoryFile.getParentFile().getAbsolutePath());
|
||||
updateFileListView();
|
||||
}
|
||||
else if(fileListItem.isDirectory())
|
||||
{
|
||||
setCurrentDirectory(fileListItem.getPath());
|
||||
updateFileListView();
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
if(IsLoadableExecutableFileName(fileListItem.getPath()))
|
||||
{
|
||||
NativeInterop.loadElf(fileListItem.getPath());
|
||||
}
|
||||
else
|
||||
{
|
||||
NativeInterop.bootDiskImage(fileListItem.getPath());
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
displaySimpleMessage("Error", ex.getMessage());
|
||||
return;
|
||||
}
|
||||
//TODO: Catch errors that might happen while loading files
|
||||
Intent intent = new Intent(getApplicationContext(), EmulatorActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
// _fileListView.setOnItemClickListener(
|
||||
// new OnItemClickListener()
|
||||
// {
|
||||
// @Override
|
||||
// public void onItemClick(AdapterView<?> parent, View view, int position, long id)
|
||||
// {
|
||||
// //Remove one to compensate for header
|
||||
// position = position - 1;
|
||||
//
|
||||
// FileListItem fileListItem = _fileListItems[position];
|
||||
// if(fileListItem.isParentDirectory())
|
||||
// {
|
||||
// File currentDirectoryFile = new File(getCurrentDirectory());
|
||||
// File parentDirectoryFile = currentDirectoryFile.getParentFile();
|
||||
// if(parentDirectoryFile == null) return;
|
||||
// setCurrentDirectory(currentDirectoryFile.getParentFile().getAbsolutePath());
|
||||
// updateFileListView();
|
||||
// }
|
||||
// else if(fileListItem.isDirectory())
|
||||
// {
|
||||
// setCurrentDirectory(fileListItem.getPath());
|
||||
// updateFileListView();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// if(IsLoadableExecutableFileName(fileListItem.getPath()))
|
||||
// {
|
||||
// NativeInterop.loadElf(fileListItem.getPath());
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// NativeInterop.bootDiskImage(fileListItem.getPath());
|
||||
// }
|
||||
// }
|
||||
// catch(Exception ex)
|
||||
// {
|
||||
// displaySimpleMessage("Error", ex.getMessage());
|
||||
// return;
|
||||
// }
|
||||
// //TODO: Catch errors that might happen while loading files
|
||||
// Intent intent = new Intent(getApplicationContext(), EmulatorActivity.class);
|
||||
// startActivity(intent);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
|
||||
fileListItems = new ArrayList<FileListItem>();
|
||||
}
|
||||
|
||||
private void updateFileListView()
|
||||
|
@ -45,6 +45,17 @@ public class SettingsActivity extends PreferenceActivity
|
||||
checkBoxPref.setChecked(SettingsManager.getPreferenceBoolean(checkBoxPref.getKey()));
|
||||
}
|
||||
}
|
||||
|
||||
Preference button = (Preference)getPreferenceManager().findPreference("ui.clearfolder");
|
||||
if (button != null) {
|
||||
button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference arg0) {
|
||||
MainActivity.resetDirectory();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
BIN
build_android/libs/commons-io-2.4.jar
Normal file
BIN
build_android/libs/commons-io-2.4.jar
Normal file
Binary file not shown.
BIN
build_android/libs/commons-lang3-3.1.jar
Normal file
BIN
build_android/libs/commons-lang3-3.1.jar
Normal file
Binary file not shown.
@ -3,5 +3,16 @@
|
||||
<string name="app_name">Play!</string>
|
||||
<string name="main_menu_settings">Settings</string>
|
||||
<string name="main_menu_about">About</string>
|
||||
<string name="main_menu_exit">Exit</string>
|
||||
<string name="main_menu_exit">Exit</string>
|
||||
|
||||
<string-array name="disks">
|
||||
<item>iso</item>
|
||||
<item>bin</item>
|
||||
<item>cso</item>
|
||||
<item>isz</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="elves">
|
||||
<item>elf</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
|
@ -11,4 +11,10 @@
|
||||
android:summary="Show virtual pad on screen."
|
||||
android:persistent="false"
|
||||
/>
|
||||
<Preference
|
||||
android:key="ui.clearfolder"
|
||||
android:title="Reset Folder"
|
||||
android:summary="Clear stored default folder."
|
||||
android:persistent="false"
|
||||
/>
|
||||
</PreferenceScreen>
|
Loading…
x
Reference in New Issue
Block a user