Hello,
--- Problem ---
I am trying to access a text file under my $projectPath/assets
directory through the native interface without touching Java code. I
am using the Android SDK r09, the NDK r5b, Cygwin 1.7.7 und Windows 7
64 bit, ADT 9.0.0 Plugin for Eclipse.
Why? I want to provide cross platform (Android, Windows, IPhone)
compatible means for loading (and writing) to xml and image files.
Therefore, I do only want to employ C / C++ and no Java code.
According to [1] "Applications can now access a native Asset Manager
API to retrieve application assets directly from native code without
needing to go through JNI"
After some investigation (see below) the question to getting access to
asset files boiled down to
"How do I get access to a valid AAssetManager pointer without passing
it down from Java via JNI?"
--- What I have tried ---
- I am aware of discussions for prior versions of the NDK: [2] and
[3].
--> According to [1] these workarounds of
* renaming files to e.g., .png do not prevent the files from getting
compressed and added to the .apk in ndk r5b and
* manually unzipping the .apk is to elaborate for me (for now) AND
should not be necessary anymore [1].
- I had a look at android-ndk-r5b/platforms/android-9/arch-arm/usr/
include/android/asset_manager.h
It provides methods for accessing assets once you have a valid
AAssetManager*
Unfortunately, it seems to provide NO methods for getting a valid
AAssetManager pointer.
There is no method like getAssets() in Java which returns an
AssetManager instance.
- I had a look at the android-ndk-r5b/samples/native-audio example
Here "asset_manager_jni.h" is used to get a valid AAssetManager*
through JNI
According to [1] this should not be necessary.
- In despair and similar to the native-audio example I modified the
android-ndk-r5b/samples/native-activity example (without getting an
AAssetManager* from Java!) to:
...
#include <android/asset_manager.h>
...
void android_main(struct android_app* state) {
...
AAssetManager* assetManager;
AAsset* asset = AAssetManager_open(assetManager, "test.txt",
AASSET_MODE_UNKNOWN);
if (asset == NULL) {
LOGW("COULD NOT OPEN ASSET");
}
// open asset as file descriptor
off_t start, length;
int fd = AAsset_openFileDescriptor(asset, &start, &length);
if(fd < 0)
{
LOGW("COULD NOT OPEN FILE DESCRIPTOR");
}
AAsset_close(asset);
...
As expected the application crashed presumably due to the invlaid
AAssetManager pointer:
...
02-09 20:53:12.505: INFO/native-activity(778): android_main called
02-09 20:53:12.625: INFO/DEBUG(31): *** *** *** *** *** *** *** ***
*** *** *** *** *** *** *** ***
02-09 20:53:12.635: INFO/DEBUG(31): Build fingerprint: 'generic/sdk/
generic:2.3.1/GSI11/93351:eng/test-keys'
02-09 20:53:12.635: INFO/DEBUG(31): pid: 778, tid: 787 >>>
com.example.native_activity <<<
02-09 20:53:12.635: INFO/DEBUG(31): signal 11 (SIGSEGV), code 1
(SEGV_MAPERR), fault addr 00000004
...
I have no idea where to go from here.
Any useful comments (other than "use Java to get a valid AssetManager
instance") are welcomed.
Many thanks in advance,
Jens
--- References ---
[1]
http://developer.android.com/sdk/android-2.3-highlights.html
[2]
http://groups.google.com/group/android-ndk/browse_thread/thread/842ca9d7d82995b0
[3]
http://groups.google.com/group/android-ndk/browse_thread/thread/4e25a5dfd46f8fea/1269bcd10bdb066d?lnk=gst&q=apk+compressed#1269bcd10bdb066d