Context
I work on an app for Android which should analyse in real time the camera input.
I chose Qt to develop the user interface, for portability reasons (the app may evolve to support other platforms than Android).
For image processing, my colleague is working on it using TensorFlow.
So I want to know how could I use TensorFlow for Android in Qt ?
What I've done :
Downloaded tensorflow the nightly precompiled version (#453) from http://ci.tensorflow.org/view/Nightly/job/nightly-android/lastSuccessfulBuild as suggered at https://www.tensorflow.org/versions/master/mobile/linking_libs#android (option 2)
Put the files in my qt project android/libs folder
Modified my *.pro file to add :
the given *.jar file with : DISTFILES += android_v453/libandroid_tensorflow_inference_java.jar
the given *.so file with : ANDROID_EXTRA_LIBS = $$PWD/android/libs/armeabi-v7a/libtensorflow_inference.so
But for now I'm confused. How should I call it in my Qt App ?
Note : I just noticed that TensorFlow Android interface is aimed only at inference, so no training would be available. (source)
Well, I think I figured it out !
The QAndroidJniEnvironment & QAndroidJniObject classes from Qt AndroidExtras seems to do all the big work.
Sample instanciation code:
QAndroidJniObject graph ("org/tensorflow/Graph");
QAndroidJniObject inferenceInterface("org/tensorflow/contrib/android/TensorFlowInferenceInterface", "(Lorg/tensorflow/Graph;)V", graph.object());
I know this works because tensorflow now logs data to the Qt console.
Related
I'm trying to run a simple example of Mapbox using the QT SDK.
On my mac it's ok but when the example run on my Android phone, I saw a blank map and if I call the function errorString on the Map object, I got this error message:
The geoservices provider is not supported.
Can anyone help me?
My Mapbox key is valid, I did the test as they suggest on the MapBox web site.
I am using QT 5.12 and my LG5 phone is on Android 8.0.
What I don't understand?
According to this GitHub ticket this is appears to be an issue with the Qt Location plugin and not with Mapbox GL. A quick sweep of existing tickets to see if this has already been reported comes up empty, so I'd recommend flagging it for the Qt engineering team here: https://bugreports.qt.io/
Apparently there is some kind of a dependency resolution bug and QT APK bundler does not add several shared libraries like
libplugins_geoservices_qtgeoservices_mapboxgl_armeabi-v7a.so
libQt5OpenGL_armeabi-v7a.so
libQt5Sql_armeabi-v7a.so
This is what fixes it (found it in mapviewer QT example). Add to your .pro file:
# Workaround for QTBUG-38735
QT_FOR_CONFIG += location-private
qtConfig(geoservices_mapboxgl): QT += sql opengl
qtConfig(geoservices_osm): QT += concurrent
In case you are using CMake builds adding Qt5::Sql and Qt5::OpenGL along with Qt5::Location also fixes the issue:
find_package(Qt5 REQUIRED Positioning Location Sql OpenGL)
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE
Qt5::Location
Qt5::Positioning
Qt5::Sql
Qt5::OpenGL
)
I have an Android native library (C++ code base) called:
libserverapp.so
And I cannot get the Android build to find it:
"DllNotFoundException: serverapp"
I am using an internal build system, but when I parse the output of the build process, I can see many calls of the form:
android-ndk/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/arm-linux-androideabi-g++.exe -march=armv7-a
After building my Android app, I inspect the resulting APK (renaming to .zip and extracting), and can see my library file here:
lib/armeabi-v7a/libserverapp.so
I can confirm that "ARMv7" is the target architecture in the Android Player settings, and I access the library, in C#, via:
[DllImport("serverapp", CallingConvention = CallingConvention.Cdecl)]
private static extern void run_sim(StringBuilder matchInput, StringBuilder results, int randomSeed);
I have built a Windows DLL of the C++ code, to use in the Editor, and everything works great. However, when I move to Android, the .so cannot be found. The import settings for libserverapp.so are:
Platform: Android; CPU: ARMv7; Path: Assets/Plugins/Android/libserverapp.so; Type: Native
Given that the final APK includes the .so where I expect it to be (lib/armeabi-v7a/), I assume my Unity settings are correct? Also, I am not using IL2CPP for the Android build.
Finally, when I do an object dump of the library file (using arm-linux-androideabi-objdump.exe), the file format of the library file is "elf32-littlearm".
I feel that the issue here is simply finding the .so, not the functionality within it. Any ideas on what's going on here?
Thanks!
I ended up solving the problem. I mentioned that was using an internal build system. Well, there seems to be a bug in it. I ported things over to official Android NDK makefiles, and then it "just worked". So in this case, the library could be found, but its contents weren't valid.
I want to create small command interpreter for android (shell). It should perform only few features : 'scanf','printf','cd', 'pwd', 'echo','set', 'unset', 'exit' and should support internal path variables : 'path', 'home', 'status'.
Is it possible to fulfil this using Native Android Kit and bionic library.
I would be grateful for any help.
Thanks in advance.
Yes, you should just create an executable program binary with the NDK (e.g. use 'include $(BUILD_EXECUTABLE)' instead of 'include $(BUILD_SHARED_LIBRARY)')
I currently developing app for Android that provides various audio settings. I use android system prepared by someone else, and it provides (I see in source and compiled files) some methods that could be useful for me. For example there are (kernel/drivers/audio/audio.c) some methods to change bands (for equalizer). In compiled system there is audio_setting.so file in some audio dir on kernel. Is there a possibility to use this methods (library) in my application NDK? I don't want to compile my app with whole system, rather to dynamically add this lib.
edit:
It was simplier than I thought. I used:
void *some_lib;
bundlewrapper = dlopen("some/path/some_lib.so", RTLD_LAZY);
if ( some_lib!= NULL ) {
LOGV("Loaded lib\n");
// use methods from lib
}
Sure, you can use any code on the system.
Obviously if it is non-JNI code you'll have to call it from your own JNI code or wrapper.
In your Android.mk file you will need to add the extra lib in LOCAL_LDLIBS
Getting "system.entrypointnotfoundexception: loadlibrary" While trying to use SevenZipLib.dll to uncompress the .7z file containing media contents/file in the Android evn.
Context:
-The whole program is written in c# as a MONO Android Project. No Build/Deployment Error/warnings.
While running the apk, its throwing "system.entrypointnotfoundexception: loadlibrary".
-Also tested the same code as windows project (not mono) - uncompressing in the windows evn.
Assumptions for the issue:
7zip internally might be using COM components & Mono frame work is not supporting.
Question:
Has anyone come across similar issue? Please suggest some alternative dll/framework which can be used by my apk for uncompressing the .7z file.
Assuming that SevenZipLib.dll is the SevenZipLib Library on CodePlex, the problem is SevenZipLib\SevelZipLib\SevenZipArchive.cs:
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern SafeLibraryHandle LoadLibrary(
[MarshalAs(UnmanagedType.LPTStr)] string lpFileName);
The project contains numerous P/Invokes into kernel32.dll (LoadLibrary(), GetProcAddress(), FreeLibrary()), ole32.dll (PropVariantClear()), oleaut32.dll (SafeArrayCreateVector()), and more.
In short, this library is intimately tied to Windows, and isn't going to work on a non-Windows platform in any meaningful fashion, not without a lot of work.
If you need 7z support in a Mono for Android application, you'll need to look into a different library. It looks like the 7-zip SDK includes C# source for reading LZMA files that doesn't rely on P/Invoke, so perhaps that would work?