For reference, this is what I do…
I extend the SDLActivity class for my app, in Java:
public class TangibleMath extends SDLActivity
{
public String list_assets(String path, boolean get_directories, boolean
get_files) {
List files = new LinkedList();
if(path.length() > 1 && path.charAt(path.length()-1) == ‘/’)
path = path.substring(0, path.length()-1);
try {
String ls = getAssets().list(path);
for(String file : ls) {
// Lame problem… AssetManager::list() is super slow (does it unpack the
whole apk each time?).
// This is a lame workaround, but assumes files have extensions and
directories don’t.
boolean has_dot = file.contains(“.”);
if((get_files && has_dot) || (get_directories && !has_dot))
files.add(file);
}
} catch (IOException e) {
e.printStackTrace();
}
return files.toArray(new String[files.size()]);
}
}
Then in C++, I do this in my directory listing function (fileList is a
std::liststd::string):
if(dirname.size() > 0 && dirname[0] == '/') // Absolute file name, not
an asset
{
fileList = ioListUsingOpendir(dirname, directories, files);
}
else // Look in assets
{
// retrieve the JNI environment.
JNIEnv* env = (JNIEnv*)SDL_AndroidGetJNIEnv();
// retrieve the Java instance of the SDLActivity
jobject activity = (jobject)SDL_AndroidGetActivity();
// find the Java class of the activity. It should be SDLActivity or
a subclass of it.
jclass clazz( env->GetObjectClass(activity) );
// find the identifier of the method to call
jmethodID method_id = env->GetMethodID( clazz, "list_assets",
“(Ljava/lang/String;ZZ)[Ljava/lang/String;” );
// Prepare Java arguments
char* path_str_storage = new char[dirname.size()+1];
strcpy(path_str_storage, dirname.c_str());
jstring path_str = env->NewStringUTF(path_str_storage);
jboolean dirs_j = directories;
jboolean files_j = files;
// call the Java method
jobjectArray stringArrays = (jobjectArray) env->CallObjectMethod(
activity, method_id, path_str, dirs_j, files_j);
delete[] path_str_storage;
int size = env->GetArrayLength(stringArrays);
for(int i = 0; i < size; i++)
{
jstring string = (jstring)
env->GetObjectArrayElement(stringArrays, i);
const char* myarray = env->GetStringUTFChars(string, 0);
fileList.push_back(myarray);
env->ReleaseStringUTFChars(string, myarray);
env->DeleteLocalRef(string);
}
// clean up the local references.
env->DeleteLocalRef(activity);
}
Using JNI with C instead of C++ is very similar, you just have to pass
around the extra self/this object argument if I recall correctly.
Jonny DOn Fri, Jun 3, 2016 at 5:50 PM, SparkyNZ wrote:
I’ve just discovered the SDL_RWops functions for pulling out Android
assets etc. Very cool. The only question I have is “Is it possible to get a
list of folder contents?”.
In the iOS version of my app, I copy files from my iOS ‘bundle’ into the
app’s working folder. I want to be able to do the same thing with my
Android app - ie - copy all files from the .APK’s assets folder into my
app’s working folder. But… I don’t want to have to list each file that I
want to copy. There must be a way of enumerating through these files using
SDL in a cross-platform manner, surely?
If not I’m going to have to find out how to use the Android Asset
Manager… and at the moment I have no idea how to get the JNI ‘env’ value
from within my SDL app. Would I have to purposely modify SDL_Activity.java
in order to pass the JNI environment values back into my SDL C++ app?
How do you get the ‘env’ or ‘assetManager’ parameters below from within an
SDL C++ app?
Code:
AAssetManager_fromJava (JNIEnv *env, jobject assetManager)
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org