I have an Android app (targeting Android R - API lvl 30) which has bulk of its logic in c++.
App reads a file in res folder and we can access it like - R.raw.dev, where dev is the config file.
My intention is to get the full path to this file and open it in C++ layer using fopen method. But I'm not able to get the full path to the file.
I have seen some suggestions of the following kind,
Uri resRawUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + getPackageName() + R.raw.dev);
But this is an Uri....not a file path.
I've heard of an alternative to the res folder, called assets, which gives more freedom than the res folder. The methods of AssetManager, the class used to query the assets folder, return InputStream and others, but not the file path.
Is there a way to get the absolute file path to files in res or assets folder? If its not possible in these two folders, how about external storage? Is there a way to get the absolute file path, so that I can pass this path to C++ and open it using fopen?
My intention is to get the full path to this file
Resources are not files on the device. They are files on your development machine. They are entries in an APK file on the device.
Is there a way to get the absolute file path to files in res or assets folder?
No, sorry.
If its not possible in these two folders, how about external storage?
I would use internal storage, such as getFilesDir() or getCacheDir() on Context.
Related
I am using a method that require a full path for a file as a String, I have the data stored in the assets folder of my project and I cannot seem to get to it via file:///android-assets/my-file, I think it because the method wants a FULL path. is there a solution to this or should I try a different storage option?
For URI
Its file:///android_assets/{Relative Path}. Note the 'underscore' between the words android and assets, not 'hyphen'.
However there's no absolute path for asset files, but you can get an Input Stream of the file like this
getResources().getAssets().open("fileName")
Is there any way to load application assets from external storage ("DCIM") folder rather than its ("apk") builtin ("assets") folder. Please tell me how to do it?
I have given read write permissions too and I have tried giving path by
String pathToAssetFolder = "file://"+Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + "/assets/";
Please let me know how can i load these assets contents from external directory?
I have kept some files in assets folder of android application.
Now i compile that application and get apk. [when i extract that apk my files are there in assets folder]
Now i install that apk in mobile device
and in That application has some code in c programing with JNI interface.
Now my fopen() call in c programming for that file get failed.
fopen("myfile","r");
I know while installing apk android copy assets file to /data/data/com.packagename/something
So does anyone knows that path so i can give it in fopen()
or is there any other method to open that file in C programming.
If i keep those files in sdcard folder and access like fopen("/sdcard/myfile","r"); then it works file. But i want to keep those files in assets folder only
You can use the asset manager to access assets in JNI code. It's part of NDK.
http://developer.android.com/ndk/reference/group___asset.html
Something like:
EXPORT_API void LoadAsset(char* filename, jobject assetManager){
AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);
AAsset* asset = AAssetManager_open(mgr, filename, AASSET_MODE_BUFFER);
AAsset_read(asset, ...);
}
And then in Java something like:
LoadAsset("myfile", getContext().getAssetManager());
One way I've found is to write a test line in the code, something like:
System.out.println("Working Directory = " +
System.getProperty("user.dir"));
Now, if you know where your assets are stored by Android, /data/data/com.packagename/assets/file.png, for example, then you will know the reletive or absolute path to the assets. I hope this works for you, it helped me!
I am trying to programmatically load a .png file but I am not sure what is the exact path I should be giving. I tried different paths that I think would get me to the resource but all return null:
InputStream is = getClass().getClassLoader().getResourceAsStream("playstore.png");
Bitmap bmp = BitmapFactory.decodeStream(is);
mStoreImage.setImageBitmap(bmp);
If I understand correctly I cannot use resources as I am building a .jar. This is my project package structure displayed with Android Studio:
You should use Resources.openRawResource()
e.g. if your Activity
getResources().openRawResource(R.raw.playstore.png);
remember to put the file under res/raw
Edit:
In addition, android has it own method to get drawable (e.g. a png file) into Bitmap
Android Studio Gradle projects read files from a separate resources directory in the same way as Maven does it.
Create a "resources" folder in Windows Explorer (Android Studio don't allow you to do that) and then recreate the package path and place files there, e.g.:
A class located at this path:
C:\...\app\src\main\java\com\adscendmedia\videosdk\AdscnedAPI.java
Read resource files from this path:
C:\...\app\src\main\resources\com\adscendmedia\videosdk\playstore.png
Using JNI I can't get access to files like this:
ifstream file("file.txt");
file.txt is in folder jni, which is the same folder as the native code files
I can only access absolute path ("/sdcard/file.txt"), but this trick is not what I'm looking for.
Tried "data/data/com.example.SomeExample/jni/file.txt" but no luck.
How should I refer to a file as reletive path when working in native code?
The jni folder is not added to your APK. If you want files to be bundled with your application, I'd suggest putting them in the assets folder. If the assets folder doesn't already exist, place it at the same level as the jni folder (so they are siblings).
If you take this approach you will have to use the Asset Manager. This has a native interface, found in android/asset_manager.h. To open your file use:
AAsset *a = AAssetManager_open(pAssetManager, "file.txt", AASSET_MODE_BUFFER);
if (a)
{
const void *res = AAsset_getBuffer(a);
//do something with the file!
AAsset_close(a);
}
There are different flags you can pass in instead of AASSET_MODE_BUFFER.