I've created an Application that works perfectly in Android Studio. If I generate an AAR and APK and use these files they again work fine. I can install the APK on several devices and it works flawlessly. Now when I install the APK inside of an AOSP build I keep getting an java.lang.UnsatisfiedLinkError: which points to the very first line of code that's calling my native method. I used this link as a reference Add .apk files in aosp. When I run the emulator and click my application it crashes and produces that UnsatisfiedLinkError. The same thing happens if I generate an APK using my AAR file. Just to clarify again this only happens in AOSP it does not happen when using the AAR inside Android Studio doing other builds and the APK always works regardless of the device I install it on. Any advice as to why this is happening would be great!
which points to the very first line of code that's calling my native method.
Sounds like you are building your application with native libraries included and the .APK you created has only bundled some architecture types into it. If you have native libraries, make sure to include all architecture types (usually x86 and armv7 does the job, but always consult your compatibility checklist first) and make sure if you do ABI splitting that you are using the right APK.
Please consule the following guide to make sure you have the NDK integration set up correctly.
AOSP was trying to find the .so that my APK uses from either the system/lib or vendor/lib folders and since it wasn't there it was causing the UnsatisfiedLinkError. So by adding the .so object file directory to those locations the APK started up fine inside the emulator after that. This could also be accomplished by modifying the Android.mk as well by adding these lines to the file.
include $(CLEAR_VARS)
LOCAL_MODULE := myfile
LOCAL_SRC_FILES := lib/myfile.so # or wherever your .so is located
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
include $(BUILD_PREBUILT)
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'm building a version of the AOSP for custom hardware and I'd like to use some root permissions (INJECT_EVENTS, UPDATE_DEVICE_STATS, CONNECTIVITY_INTERNAL).
For rev control, it would be ideal to use an APK-based distribution. As such, I'd like to include the APK in the build instead of building the source every time. The program gets successfully included, but the system privileges are ignored.
Is there a way to include this program such that it receives the necessary privileges? I'm hoping there is some connection that either LOCAL_CERTIFICATE, LOCAL_MODULE_CLASS or BUILD_PREBUILT in Android.mk can achieve.
EDIT:
The solution was to first determine the signatures that were being used to build the Android system. They existed in /build/target/product/security/platform inside the AOSP. Once I had these signatures, I could then create a new keystore. I then imported the keys into the new keystore using the tool keytool-importkeypair found here.
https://github.com/getfatday/keytool-importkeypair
Once that was done, I could select the keystore inside Android Studio and correctly install and debug the program that had the necessary permissions.
Here is what I have: my application is a system application which I develop using Android Studio. When I want to include it in my ROM, here are the steps:
Export the app as an unsigned apk from Android Studio
Place the apk in packages/apps/your_app folder
Use the Android.mk like this:
.
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := your_app
LOCAL_CERTIFICATE := platform
LOCAL_PRIVILEGED_MODULE := true // if required
LOCAL_MODULE_CLASS := APPS
LOCAL_SRC_FILES := app-release-unsigned.apk
include $(BUILD_PREBUILT)
In addition to this, you can also generate keystore file from the platform certificates. You can google that, it involves several shell commands (I use the same approach) and then you can run your app on your device from Android Studio with appropriate signing configuration.
So you are making a custom Android build, just need to put your app source in the same directory level with other system apps, such as Phone, Messages, Calendar ... then it will eventually be built and generated as a system app, which will stay in /system/app after burning the image to the hardware.
I just fetched all the source code from AOSP and have recursively copied external/openssl/* to myproject/jni/libopenssl/. Next, I added the following lines in Android.mk:
#build libcrypto.a
include $(CLEAR_VARS)
include $(LOCAL_PATH)/libopenssl/Crypto.mk
...
LOCAL_STATIC_LIBRARIES := libcrypto_static
However, this creates a bunch of errors.
I am wondering if anyone has clear steps to build libcrypto_static from AOSP. I noticed that there are many forks on github for openssl. However, I would prefer to use the one from AOSP as it seems to have optimizations for arm as well as x86. Regards.
I have an android project with a libs folder structure like this:
/libs
/armeabi
libfoo.so
libbar.so
libmystuff.so
libgnustl_shared.so
/armeabi-v7a
libfoo.so
libbar.so
foo and bar are third party libraries, mystuff is my own library from a separate android JNI project which requires gnustl_shared, which is from the same JNI project.
When I build my project in Eclipse, I can view the contents of the generated APK using unzip -l, and it indeed shows that all of these library files have been included.
However, after installing the APK, the /data/data/com.myproject/lib folder contains no libgnustl_shared.so, even though the other libraries are present.
This inevitably leads to the following error:
UnsatisfiedLinkError: Couldn't load gnustl_shared: findLibrary returned null
As a sanity check, I ran adb push ./libs/armeabi/libgnustl_shared.so /data/data/com.myproject/lib and sure enough, the application starts as expected.
I don't see anything in the build log or Eclipse console that suggests there were any issues building or installing the app.
What could be preventing libgnustl_shared.so from being installed with my application?
Where can I go to learn about what happens when an APK is installed?
Please let me know in a comment if there's any specific information I can provide that might help.
I think that, in your JNI project's Android.mk file, most probably, when you build libmystuff.so, you're referencing libgnustl_shared.so like:
LOCAL_LDLIBS += -lgnustl_shared
Maybe you can try to add it as a module (NDK works really focused on modules), something like:
include $(CLEAR_VARS)
LOCAL_MODULE := gnustl_shared
LOCAL_SRC_FILES := libgnustl_shared.so
include $(PREBUILT_SHARED_LIBRARY)
and (in the section you're building libmystuff.so):
LOCAL_SHARED_LIBRARIES := gnustl_shared
And check if it's finally copied
I think your libgnustl_shared.so need under /armeabi-v7a not under /armeabi
Please try copy libgnustl_shared.so to /armeabi-v7a
Look at the answer here: How to link any library in ndk application
The problem is most likely in your Android.mk file. You should have a line like the one on the bottom:
include $(BUILD_SHARED_LIBRARY)
If not, then you're not including your shared library.