I want to list folders and files inside Resources folder from android and ios. I've been able to do so by 'opendir' and 'readdir' from 'dirent.h' but only in ios emulator. It doesn't work in android.
Did anyone face such problem?
Thanks.
AFAIK, this can't be done on Android using only C++. Since you already have the iOS part figured out, you shuould wrap the iOS specific code (#includes too) in
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
...
#endif
The same will aply for Android only code (`CC_PLATFORM_ANDROID') - to achieve what you want you have to write a JNI call in order to call a Java function from C++. Assuming that you want to just dump this data to a log, everything should be pretty straightforward. I don't have a link at hand, but there was an extensive topic about opening URLs which coverd the JNI tutorial and it shouldn't be hard to find.
One way could be to mantain a file containing a list of all the files in the resource directory along with their hierarchy.
For example, say you have a directory hirearchy as:
Resources/
folder1/
file1.jpeg
file2.jpeg
folder2/
file1.jpeg
file2.jpeg
Then you can mantain a file containing the paths as:
in resource_paths.txt
folder1/file1.jpeg
folder1/file2.jpeg
folder2/file1.jpeg
folder2/file2.jpeg
Then search in the file for list of directories/files :)
Related
I'm trying to get image format plugins working on Android.
My plan is to build this APNG image format plugin, which closely follows the style of the official Qt extra image format plugins. The answer to my problem will be the same for these too.
On desktop (windows) it works. So long as you put the plugin DLL into a imageformats subdirectory like this:
myapp/<all my binaries>
imageformats/qapng.dll
But on Android, it's another story;
First idea was to put libqapng.so into libs so that qtcreator bundles it up with all the others as part of an APK build. It goes in, but is not loaded by Qt at runtime.
So i look into how the existing qt image formats work;
turns out, rather than being in a subdirectory, they are named according to this pattern;
libplugins_imageformats_libqapng.so
So i rename libqapng.so to the above and put that into libs. Nice try, but it didn't work.
After a lot of head scratching, i discover there's a secret resource array that connects the logical location of plugins to the physical file names;
This lives in;
res/values/libs.xml
and looks like this:
<array name="bundled_in_lib">
...
<item>libplugins_imageformats_libqgif.so:plugins/imageformats/libqgif.so</item>
<item>libplugins_imageformats_libqicns.so:plugins/imageformats/libqicns.so</item>
<item>libplugins_imageformats_libqico.so:plugins/imageformats/libqico.so</item>
<item>libplugins_imageformats_libqjpeg.so:plugins/imageformats/libqjpeg.so</item>
<item>libplugins_imageformats_libqsvg.so:plugins/imageformats/libqsvg.so</item>
<item>libplugins_imageformats_libqtga.so:plugins/imageformats/libqtga.so</item>
<item>libplugins_imageformats_libqtiff.so:plugins/imageformats/libqtiff.so</item>
<item>libplugins_imageformats_libqwbmp.so:plugins/imageformats/libqwbmp.so</item>
<item>libplugins_imageformats_libqwebp.so:plugins/imageformats/libqwebp.so</item>
....
So, i just need to get my new plugin into that list.
Sure enough, if i HACK it in, it works! but how to add my plugin to this list properly as part of the build?
this page on Qt Android deployment mentions a thing called bundled_in_lib, which is indeed what i need. But it unfortunately does not explain how to change this or to add to it.
I'm thinking there might be a secret magic spell i can add to my qmake .pro file to affect this bundled_in_lib resource.
How to do it? or is there a better way that I've not yet seen. There doesn't seem to be much about explaining these details for Android.
On a final note, an alternative might be to manually load the plugin in main.cpp. I've tried this and it doesn't work. Perhaps, they need to be loaded by the Qt image format plugin loader rather than just loaded at all. Maybe there's a way to do this. not sure?
using Qt5.9.1
Thanks for any help.
Following #Felix answer, ANDROID_EXTRA_PLUGINS is correct, but how it works is a bit strange.
Following a discussion on the lack of doc for this feature here, and some trial and error, i found that;
ANDROID_EXTRA_PLUGINS must specify a directory, not a file. So you point to a plugins directory of your own. Things below this directory (including subdirectories) get mangled as in my original question and explained below.
So, for my plugin libqapng.so, i have:
ANDROID_EXTRA_PLUGINS += <some path>/plugins
and my android plugin building .pro puts the output in;
<some path again>/plugins/imageformats/libqapng.so
The .so lib, then winds up mangled in (eg. for arm);
android-build/libs/armeabi-v7a/libplugins_imageformats_libqapng.so
and the resources get the entry;
android-build/res/values/libs.xml
<array name="bundled_in_lib">
...
<item>libplugins_imageformats_libqapng.so:plugins/imageformats/libqapng.so</item>
</array>
as required.
Thanks to #Felix for almost the answer, but i thought I'd write up the extra details here for the benefit of others.
The answer is on the same site, a little lower on the page: Android-specific qmake Variables
The one you are looking for is most likely ANDROID_EXTRA_PLUGINS. There is no usage example, so you will have to try out in wich format to add the plugin here.
My suggestions would be:
ANDROID_EXTRA_PLUGINS += imageformats/qapng
or
ANDROID_EXTRA_PLUGINS += plugins/imageformats/libqapng.so
... something like that. This should take care of all the renaming stuff etc. as well.
EDIT:
Its also very possible you need to enter the absolute path, i.e.
ANDROID_EXTRA_PLUGINS += $$[QT_INSTALL_PLUGINS]/imageformats/libqapng.so
or in whichever path you keep the plugin
I want to remove an empty folder using remove() in C++ on Windows 7 but I can't. I tried rmdir() instead of remove() then the folder got removed!
Nevertheless, the reason why I don't use rmdir() is due to Android. In a library project for Android, I can't include "direct.h" header so can't use rmdir(), either. Unlike on Windows, the function remove() works well on Android. I don't understand why.
Anybody knows why this is happening?
Or any other functions which will work on both Windows and Android?
This is a pretty common problem when writing cross-platform programs.
Sometimes, a library can provide the abstraction you need. For example, Boost has a filesystem library that can enumerate files, manipulate directories, etc., on multiple platforms using the exact same code.
Also, there are usually symbols defined that allow you to detect which compiler is currently building your code. Even if there isn't one that does what you want, you can define your own.
Let's say you need to build your software for two different fictitional operating systems named FooOS and for BarOS. I'm going to invent two symbols, FOO_OS and BAR_OS. In my code, I can do something like this:
#ifdef FOO_OS
#include <foo_stuff.h>
#elseif BAR_OS
#include <bar_stuff.h>
#endif
void do_something()
{
#ifdef FOO_OS
do_it_this_way();
#elseif BAR_OS
do_it_that_way();
#endif
}
Now, we just need to either define FOO_OS or BAR_OS. This can be done through an IDE's project configuration or on the command line of the compiler. Use Google to find out about your particular situation, since you didn't include those details in your post.
There is a preprocessing step when you compile your code that makes a pass through the source, and applies these conditional statements. A following pass actually compiles the code. Here is some documentation about Visual Studio's preprocessor, for example.
How can I get reach to the native methods called from Java side in Android? My problem is specifically related to AudioRecord class in Android Media package. I read the source code of AudioRecord.java. I found out that most of the jobs is performed by native methods, such as:
native_setup(...), native_start(...), native_stop(...), native_read_in_byte_array(...), native_read_in_direct_buffer(...)
I downloaded Android source code but I could not reach these methods. And I don't actually know the way to reach them. I seek for these methods in libraries I found in source code directories, but I couldn't success. If anybody may have an idea, I would be appreciative to hear. Thanks...
I think I found them. After using the Linux command
grep -r "native_read_in_direct_buffer" ./ANDROID_SOURCE/.*
I found the corresponding cpp files.
AudioRecord.cpp is located in: ~/ANDROID_SOURCE/frameworks/av/media/libmedia/ directory,
android_media_AudioRecord.cpp is located in ~/ANDROID_SOURCE/frameworks/base/core/jni directory.
I wanted to share it as a reference to other possible programmers willing to reach the same/similar source files.
I'm completly new to qt so question that i'm going to ask can be funny (but for me it really is not).
In normal C++ code I used this line to generate background:
view.setBackgroundBrush(QPixmap("starstexture.jpg"));
But as I try to port my application on android, I don't know where I should put jpg file. Looking Forward your Answer -
Kamil
If you only need a limited set of images (that means, you know the images at compile time rather than let the user add his own images in the application's folder) you could use Qt's resource system.
If you're using QtCreator, you could simply add a new resource file to your project, in which you create a new prefix named /, then add your file. It is put into your application during compile time and available under the path ":/starstexture.jpg". Note the prefix ":/", which stands for Qt's resource system. Also note that such file names only work in Qt classes, of course.
I would like to use the facedetection in opencv cpp to use it in an android app. I have compiled jni successfully. But I wonder how would i use the haarcascades. I can store in sdcard and read it from there. Is there any other way i can use the xml files directly from the project?
There is a c++ example called facedetect coming with the opencv superpack. I'm running OpenCV-2.3.1 myself and it's located in this folder: ../opencv-2.3.1/samples/c/
The sample uses haarcascades and this might be your best bet for facedetection. If you can use the Android NDK with proper JNI calls from a .cpp file then you shouldn't have any problems to use this sample.
I'm working on a similar thing myself but haven't tried it myself yet. Should be implementing the thing somewhere next week but can't guarantee it. Let me know if this works out for you