I'm writing an app that should use functions from tinyalsa through ndk, I just want to call functions defined by tinyalsa like pcm_open() from my native functions implementations.
I have tried following the documentation about using prebuilt libraries in Android/ndk/docs/PREBUILTS.html but I can't get it working.
Could you please tell how could I do it?
Thanks
I could do it, the process is the next:
Copy tinyalsa.so to ~/Android/ndk/platforms/android-18/arch-arm/usr/lib
Copy asoundlib.h to ~/Android/ndk/platforms/android-18/arch-arm/usr/include
Platform-18 is the one I'm using. It can be specified in Application.mk with the line
APP_PLATFORM := android-18
After adding it to the ndk platform include it in the file where the native functions are implemented
#include <asoundlib.h>
Tell the compiler that we are going to need this library. In Android.mk
LOCAL_LDLIBS := -ltinyalsa
This worked for me :)
Related
I am getting this error: unable to lookup library path for, native render plugin support disabled when I run my app on android. I think I am building the shared libraries incorrectly.
I am looking to build the source files from this repo. I'll say my build process and perhaps someone can spot a step I'm missing or doing incorrect.
Following this guide, I came up with this:
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libhydrogen
LOCAL_SRC_FILES := ..\hydrogen.c
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_PLATFORM := android-16
APP_OPTIM := release
APP_MODULES := libhydrogen
Next I:
Placed these files in the jni folder.
Called ndk-build.
Copied the .so files from the \libs folder and placed them in their respective folders in Unity (i.e. Hydrogen\Plugins\Android\arm64-v8a).
Made sure their platforms and CPU architectures were correct.
Built my app.
Here is the c# wrapper I am using.
Calling Hydrogen.Library.Initialize(); is then giving me this error.
Here is the full logcat related to this error.
And in the case my build process manages to be correct, and the .so files are fine; what else might cause this to happen?
Edit: I am trying to build for armeabi-v7a and `x86. Here are the .so file details, maybe there is something there that is not right? I am unfamiliar with c and since I haven't heard of anyone building this library for android, I wonder: could there be anything within the c source file that is incompatible with the NDK build process?
Native libraries are loaded by the native linker of the system, in your case, the linux dynamic linker: ld.so (it changes names sometimes, so I used that name, as you can check the man page in the documentation with that name).
For that to happen, in general, you need to provide a LD_LIBRARY_PATH environment variable to the java virtual machine, so it can effectively dlopen(3) it.
Think how different can be your development system to your target one.... and you'll easily get to that.
It was a bug with Unity! For some reason when switching the project's target platform some of my files would get corrupted. Strangely, it only seems to happen in this one project, but in any case the (temporary) solution is to re-import the plugin folder whenever I switch platforms.
I'm struggling with this for several days now. At the moment i'm just testing it with a simple C++ project (1 .h & 1 .cpp file) and a minimalistic App including the ndk helloJNI sample code (which worked perfect easily):
Target
Import existing C/C++ files (project) to Android Studio
Approach
After trying out some of the (dozens) of different possibilities, i think/thought the following steps would be the best solution for my purpose:
Create the shared library (Calculator.so) from Visual Studios 2015 "Create shared library for Android" (or something) [successful]
Create jniLibs folder in src/main/ with its subfolders (x86 the relevant one in my case)
Add the Android.mk file in src/main/jniLibs which has to be placed there (?)
Include statement: System.loadLibrary("Calculator") without "lib" and ".so" in MainActivity
The library is listed in Android Studio in its folder jniLibs as like the Android.mk. Moreover if i build the apk, the library is successfully packed (verified by unzipping) and i dont get any errors.
BUT: how can i call the methods in the library? I tried the different solutions offered in other threads, but i think i missed something in my .mk or my steps described above.
Tried
Different #include <myLib> statements in native-lib.cpp, like s
Different Android.mk settings (but i'm new to make files so not even tutorials helped me much with my specific problem ::) )
Other locations for the libCalculator.so like in the subfolder x86
and many others - simply not reminding atm (wasntme)
Your help is highly appreciated!
Android.mk
LOCAL_PATH := $(call my-dir)
APP_ABI := x86
# library info
include $(CLEAR_VARS)
LOCAL_MODULE := Calculator
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/Calculator.so
LOCAL_EXPORT_C_INCLUDES := ..../Visual Studio 2015/Projects/SO_Library/SO_Library
include $(BUILD_SHARED_LIBRARY)
There are lots of things, you can do in Android NDK. For example, Camera hardware is one of the heaviest hardware in Android OS. Detecting faces, things, giving effects and for thousands of features NDK is the best.
Some helps for your steps:
You can built and prebuilt shared(.so) and static(.a) libraries in Android Studio also. Not need Visual Studio.
Don't create jniLibs folder in main folder. When you build your project via gradle, it already creates this folder and put your target libraries. If you want prebuilt any libraries, put these libraries in main/jni/libs folder and prebuilt then with Android.mk.
Don't add the Android.mk file in jnilibs folder. Create this file in main/jni folder. Also Application.mk file.
Call your libraries, in any activity, where you need, in static method. Like this:
static { System.loadLibrary("my_library") }
Without "lib" and ".so" extensions.
When you want to call your native methods, just use "native" keyword. For example:
private native int nGetNumberFromNativeSide();
Just call this method, where you want, and get result. But for ndk building in gradle side, look at this answer. For building library in Android.mk, these sample lines maybe help you:
include $(CLEAR_VARS)
ifneq (,$(filter $(TARGET_ARCH_ABI), armeabi-v7a x86 arm64-v8a x86_64))
LOCAL_MODULE := my_library
LOCAL_SRC_FILES := $(LOCAL_SRC_LOCATION)/native1.cpp native2.cpp
include $(BUILD_SHARED_LIBRARY)
You can put name anything you want, but dont add lib and .so extensions. Ndk is already doing it.
I have already gave Android.mk example.
When you build Android.mk file, it locates your libraries appropriate folder. Like main/libs/x86/libmy_library.so.
I guess this answer will help you. If you have more questions, add to comment, i'll edit my answer and add answers.
I have namespace error building with ndk-build for native code in my Android app. The error sample is
C:/adt-bundle-windows-x86/ndk/sources/cxx-stl/gnu-libstdc++/4.6/include/bits
/allocator.h:54:1: error: unknown type name 'namespace'
C:/adt-bundle-windows-x86/ndk/sources/cxx-stl/gnu-libstdc++/4.6/include/bits
/allocator.h:55:1: error: expected ',' or ';' before '{' token
For OpenCV settings, my Application.mk file is
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi
APP_PLATFORM := android-10
That means I am using gnu-libstdc++ in compiling the native code.
My jni.c has c extension. That is I receive from my third party and they prefer in .c extension as if they have to change to .cpp extension, they have to change a lot in their other libraries.
So far is OK, I did all project settings for OpenCV for native development and if I do ndk-build, I can make .so libraries.
The problem of those namespace error happened when I include OpenCV's header file #include <opencv2/contrib/detection_based_tracker.hpp> into jni.c and I got a lot of name space error. If I include that #include <opencv2/contrib/detection_based_tracker.hpp> into cpp file, no error.
My questions are
(1)Is the error is because of using .hpp file in .c file?
(2)If I have no choice and have to use that .c file, is there way around to remove that error?
Thanks
My assumption would be that the file is compiled as a "C" file instead of a "C++" file because of the extension ".c". That means you cannot use any "C++" Code in your jni.c, wike classes or namespaces. These are obviously used however in your file "detection_based_tracker.hpp" that you are using.
So the problem is not that you include a file named ".hpp", but that this file contains "C++" code wich the "C" compiler cannot handle.
One solution to this problem is to only use the "C" functions in opencv (for example "opencv2/imgproc/imgproc_c.h" instead of "opencv2/imgproc/imgproc.hpp"). However, your function "detection_based_tracker.hpp" might not have a "C" version, as far as I can see.
The other option is to add a second file "function.cpp" with the "C++" functions that use opencv. The functions from "function.cpp" can be declared in a file "functions.h" and included in your "jni.c", so you can still use opencv c++ functions. Be careful to only use C style functions then, though (no classes, namespaces, ...) in your "function.h" file, otherwise you will have the same problems as before.
I am starting to work with stage fright frame work to implement hardware decoder in android prior to Jelly bean in my video conferencing application.
I have downloaded and built the android source code in Mac system. I am not clear with the whole idea of working with AOSP. And my questions are (with respect to stagefright framework)
Where can I find the libstagefright.so after AOSP build ?.
If I use the OMX codec in my class for decode, how should I link the libstagefright.so to native code of my application ? If I build my native code by copying the libstagefright.so and linking it via make file is that the way ?
How can I use it in my application ? If I load it via System.loadLibrary(" "), will it work ??
UPDATE:
I have tried the suggestion from Ganesh. But when I tried to build the project with NDK it is not taking the headers included as LOCAL_C_INCLUDES.
Here is my android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS := -llog
LOCAL_MODULE := custom_decoder
LOCAL_C_INCLUDES := $(LOCAL_PATH)\includes \
frameworks/av/media/libstagefright/include \
frameworks/native/include/media/openmax \
frameworks/base/include/media/stagefright
LOCAL_SHARED_LIBRARIES := \
libstagefright libstagefright_omx libstagefright_foundation libutils liblog
LOCAL_SRC_FILES := custom_decoder_jni.cpp custom_decoder.cpp
include $(BUILD_SHARED_LIBRARY)
the error is shown from custom_decoder.h when it is reading the includes of AOSP.
fatal error: DataSource.h: No such file or directory.
I haven"t included any AOSP .so in my project(as per Ganesh's suggestion in comment 2). Should I do that?
What else should I do to get it built......
You don't need to rebuild libstagefright.so to use it in your app. You can adb pull the library from your device, or even from an emulator.
Please note that libstagefright communicates with many components in /system/lib, some of which are specific to SoC vendor (e.g. Qualcomm) or ODM (e.g. Samsung). Some uses of Stagefright may require quirks specific to device. This is why OpenMAX IL has not been officially exposed on Android. On the otehr hand, OpneMAX AL has been officially supported since November 2011.
At any rate, libstagefright cannot be directly accessed from Java. If you are looking for a Java solution for video communication, you should first look at the excellent libstreaming library.
The advantage of using libstagefright comes usually when you have you your native (C/C++) library that only has to be connected to an efficient codec.
Here is a nice answer on a related question about Android hardware decoder.
To answer your specific queries,
libstagefright.so is built and installed at /system/lib
I presume you are employing the libstagefright.so in native code. With this assumption, you don't have to copy. I presume you are building your module as a loadable library i.e. .so file. Hence, if you can identify the dependency on libstagefright.so through LOCAL_SHARED_LIBRARIES as well as including the header files, it should be more than sufficient for building your module. Please refer to this example of building a FLAC encoder where similar dependencies have been handled.
By application, if you are referring to a Java application which interacts with a JNI layer, then point 2 should be more than sufficient. However, if you are creating a native layer application, I would recommend you to follow stagefright command line utility's makefile.
I want to create a Player which uses Android system/lib/libmedia.so.
Directly use JNI to play a video.
In Android.mk, i add "-lmedia" for including the library, but i can't link this directly.
This is my process.
write a Cpp file which includes some header file in libmedia.so
add "-lmedia" in Android.mk of LOCAL_LDLIBS
such as..
LOCAL_LDLIBS -lmedia -lstagefright
use ndk-build to build .so
error occured!!
Does anybody have some answer to help???
libmedia.so and libsinstructionght.so are not part of the public API. This means that in theory, you should not rely on them. In practice, though, these libraries are present on all devices, but they are different.
You can extract this binary file from your device, or even from an emulator using command
adb pull /system/lib/libmedia.so C:/android-ndk/platforms/android-14/arch-arm/usr/lib
This will put ths file together with the public API so that using it with ndk-build is easier. On the other hand, you should be aware of fragmentation not lnly between different levels of Android, but also chipsets, manufacturers, and even models.
To handle this, I pull .so files from different devices into separate directories, and add one of them to the linker path, e.g.
LOCAL_LDLIBS += -Lc:/android/galaxys.4.1.2.system.lib
This instruction above can not resolve the big problem you are facing with your approach. libmedia.so is not intended to be linked to user apps. It assumes the context of a privileged user with access to protected devices, such as camera, codecs, and screen.
You can make full use of this library if you target a rooted device, or prepare a custom ROM. And know what you are doing, and how to avoid stealing essential resources from the system.
Otherwise there is very little gain in linking the media lib.
PREBUILT_SHARED_LIBRARY
Points to a build script used to specify a prebuilt shared library.
Unlike BUILD_SHARED_LIBRARY and BUILD_STATIC_LIBRARY, the value
of LOCAL_SRC_FILES must be a single path to a prebuilt shared
library (e.g. foo/libfoo.so), instead of a source file.
You can reference the prebuilt library in another module using
the LOCAL_PREBUILTS variable (see docs/PREBUILTS.html for more
information).
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := foo-prebuilt
LOCAL_SRC_FILES := libfoo.so
include $(PREBUILT_SHARED_LIBRARY)
Refrenced from NDK documentation.
PREBUILT_STATIC_LIBRARY
This is the same as PREBUILT_SHARED_LIBRARY, but for a static library
file instead. See docs/PREBUILTS.html for more.
Please read the NDK documentation for more details.