I need to develop an audio app in NDK using Android Studio. I have added
the ndk path to local.properties -
ndk.dir=/opt/android-ndk-r10
sdk.dir=/opt/adt-bundle-linux-x86_64-20140702/sdk
In build.gradle I added an entry for OpenSLES -
apply plugin: 'com.android.application'
android {
compileSdkVersion 20
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.example.hellojni"
minSdkVersion 8
targetSdkVersion 21
ndk {
moduleName "HelloJNI"
ldLibs "OpenSLES" // Link with these libraries!
stl "stlport_shared"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
compile 'com.android.support:support-v4:20.0.0'
compile 'com.android.support:appcompat-v7:20.0.0'
}
Next I tried to add #includes for opensl -
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
but the IDE is not recognising the headers saying it cannot find the include files. I also tried importing the native-audio project into android studio but that too did not compile or run. I am aware that the official support is still not there for using NDK with Android Studio. But I have seen some videos that show how to integrate ndk with android studio.
Is there a way to do it.
Thanks in advance
OpenSL library is available for android platforms with API 9+, so you may want to change the mininimum required sdk.
Not sure how NDK chooses for which platform to compile, but you may need to compile yourself also using a custom Application.mk file like this:
APP_ABI := armeabi
APP_PLATFORM := android-9
TARGET_PLATFORM := android-9
Also, you should always target and compile with the highest available sdk.
Here's an example of what your build file should look like:
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.example.hellojni"
minSdkVersion 9
targetSdkVersion 22
ndk {
moduleName "HelloJNI"
ldLibs "OpenSLES" // Link with these libraries!
stl "stlport_shared"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.1.1'
}
Note: With the above configuration, the libraries are found for me (with the built-in ndk configurations).
Related
Is there a way to get an Android Instant App working with a native C++ library?
I'm attempting to publish an Android Instant App to a device/simulator, but ran into problems with my native C++ library. It publishes fine as an installable app, but fails to find the library when published as an Instant App.
To eliminate any other issues, I started a new project in Android Studio 3.0 (Canary 1 171.4010489) with the new project wizard and selected the following settings:
First Page:
Include C++ support checked
Second Page:
Phone and Tablet selected
Include Android Instant App support checked
Sixth Page:
C++ Standard set to 'C++11'
Exceptions Support (-fexceptions) checked
Runtime Type Information Support (-frtti) checked
The resulting project will publish as an installable app (showing the 'Hello from C++' screen), but not an instant app... it gives the following error that it can't find the library, which is the same error I get in my actual app's project:
couldn't find "libnative-lib.so"
Full error:
05-24 17:48:30.316 7519-7519/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mycompany.instantapp, PID: 7519
java.lang.UnsatisfiedLinkError: byc[DexPathList[[zip file "/data/user/0/com.google.android.instantapps.supervisor/files/atom-cache/com.mycompany.instantapp/atom-download--feature-1495662507463/feature.jar"],nativeLibraryDirectories=[/data/user/0/com.google.android.instantapps.supervisor/files/native-lib/com.mycompany.instantapp, /system/lib, /vendor/lib]]] couldn't find "libnative-lib.so"
...
I'm pasting the relevant gradle files below (all generated by Android Studio):
app/build.gradle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "26.0.0 rc2"
defaultConfig {
applicationId "com.mycompany.instantapp"
minSdkVersion 23
targetSdkVersion 25
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation project(':feature')
implementation project(':base')
}
base/build.gradle:
apply plugin: 'com.android.feature'
android {
compileSdkVersion 25
buildToolsVersion "26.0.0 rc2"
baseFeature true
defaultConfig {
minSdkVersion 23
targetSdkVersion 25
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
feature project(':feature')
compile 'com.android.support:appcompat-v7:25.+'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
}
feature/build.gradle:
apply plugin: 'com.android.feature'
android {
compileSdkVersion 25
buildToolsVersion "26.0.0 rc2"
defaultConfig {
minSdkVersion 23
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags "-std=c++11 -frtti -fexceptions"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
implementation project(':base')
testCompile 'junit:junit:4.12'
}
instantapp/build.gradle:
apply plugin: 'com.android.instantapp'
dependencies {
implementation project(':feature')
implementation project(':base')
}
Updates:
I've filed an issue with Google:
Link: Google Issue Tracker
Though I feel like the tools to make this happen are already available (Gradle, CMake, NDK, etc)
Also thanks #Anirudh for letting me know that this is a known issue on Android N.
Does publishing an Instant App with no C++ library work on my device?
Yes... if I create a new Android Studio project with only Include Android Instant App support it publishes to my Samsung Galaxy 7S and shows the 'Hello World!' screen.
Does publishing a signed APK work?
Generating a signed APK works, and upon inspection the native C++ library is bundled with the feature-debug.apk but not the base-debug.apk. This is what I would expect given the gradle configuration, but doesn't explain why it won't publish to a device/simulator.
I haven't tried sideloading these APKs... but I'm skeptical if that is even possible given that the Instant App is never installed... ex: how would you even launch it after sideloading it (click a url?)
Does adding the C++ library to both APKs work?
I've tried adding the externalNativeBuild gradle properties to both the base/build.gradle and the feature/build.gradle files, but the same error still occurs. I verified that the native C++ library is then included in both APKs by inspecting both the feature-debug.apk and the base-debug.apk after generating a signed APK.
modified base/build.gradle:
apply plugin: 'com.android.feature'
android {
compileSdkVersion 25
buildToolsVersion "26.0.0 rc2"
baseFeature true
defaultConfig {
minSdkVersion 23
targetSdkVersion 25
versionCode 1
versionName "1.0"
externalNativeBuild {
cmake {
cppFlags "-std=c++11 -frtti -fexceptions"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "../feature/CMakeLists.txt"
}
}
}
dependencies {
feature project(':feature')
compile 'com.android.support:appcompat-v7:25.+'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
}
Does publishing a signed APK work?
Android Studio 3.0 preview Generate Signed APK feature has a bug currently where the final zip doesn't include all feature apks. Use Gradle SigningConfig in each feature module's gradle file to sign your feature apks
Does adding the C++ library to both APKs work?
Not required. Adding to base feature apk should be enough
The actual crash is known issue with NDK support for Android Instant Apps on Android M/N. The app works on Android O emulator
I am very new to NDK debugging and I am trying to build the cpp code for debugging.
This is how my Application.mk file looks :
APP_STL := stlport_static
APP_MODULES := abc xyz
APP_CFLAGS += -fno-rtti -fexceptions
APP_ABI := armeabi armeabi-v7a
NDK_TOOLCHAIN := arm-linux-androideabi-4.9
and I an getting the following error , I have tried all the toolchains in ndk tools , what am I missing ?
update:
I realized that NDK_PROJECT_PATH is set to null , when built is run from Android studio. I am able to run
ndk-build -C from the terminal.
Actually my ultimate aim is to be able to debug native c++ files , by setting break points.
So current scenario:
I have native code in xyz folder with has jni folder containing android.mk and application.mk
I can run ndk-build in this folder and get the .so files, which I manually copy paste in jnilibs folder of the my android app (say appB):
This is the gradle of the appB :
apply plugin: 'com.android.library'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
minSdkVersion 13
targetSdkVersion 13
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
//compile 'junit:junit:4.12'
// compile 'com.android.support:appcompat-v7:24.1.1'
}
Later I use this app as dependency in another app say appA.
This is the gradle of appA:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.0'
}
}
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "24.0.0"
defaultConfig {
applicationId "*****"
minSdkVersion 14
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
repositories{
mavenCentral()
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:24.0.0'
compile 'com.android.support:design:24.0.0'
compile 'com.android.support:support-v4:24.0.0'
compile 'com.android.support:recyclerview-v7:24.0.0'
compile 'com.android.support:cardview-v7:24.0.0'
compile 'com.android.support:preference-v14:24.1.0'
compile project(':appB')
}
I need to be able to debug,
appA (which I can)
appB (which I can)
native code included as .so in appB (which I dont know yet how to)
aap
You can update the Android Studio to 2.2.2, and use the menu File-> Link C ++ Project with Gradle.
The official ndk samples can be found here!
There will be a local.properties files in your project folder from where the sdk & ndk paths can be configured. Normally the file has sdk directory path, you can configure your ndk path using keywork ndk.dir. For example
sdk.dir=YOUR_PATH_TO_SDK ( sdk.dir= /home/Android/Sdk)
ndk.dir=YOUR_PATH_TO_SDK ( ndk.dir= /home/Android/Sdk/ndk-bundle)
We're trying to publish our Android wearable app via mobile apk, so the wearable app gets synced automatically to the watch. This works fine if the app does not contain the NDK part.
However if we include the NDK/jni to our sources, the app will not install via the mobile.apk. The app installs via building in android studio and adb (adb -e install wearable.apk).
This is our build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.0"
defaultConfig {
applicationId "com.high_mobility.digitalkey"
minSdkVersion 21
targetSdkVersion 23
versionCode 1
versionName "1.0"
ndk {
moduleName = "hmbtcore"
ldLibs "log"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
splits {
abi {
enable true
reset()
include 'x86', 'armeabi-v7a'
universalApk true
}
}
sourceSets.main {
jni.srcDirs = [] // This prevents the auto generation of Android.mk
jniLibs.srcDir 'src/main/libs' // This is not necessary unless you have precompiled libraries in your project.
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.google.android.support:wearable:1.4.0'
compile 'com.google.android.gms:play-services-wearable:8.4.0'
}
Here is the adb from the mobile side when installing com.high_mobility.digitalkey
What might be the issue here that we cannot publish our app via the mobile apk?
Android Studio 1.1 generated apk file (located # app/build/outputs/apk folder) contains the lib directory, and for every cpu type there exists a non-empty folder, like /x86. Each of these folder contain a libapp.so shared library that is around 5Kb in size per cpu.
I've searched the net and the only thing I found so far is this link from Intel https://software.intel.com/en-us/articles/building-native-android-apps-using-intelr-c-compiler-in-android-studio that shows how to change the default libapp.so to user-provided library.
So, I guess that this library (libapp.so) is somehow built by gradle.
In fact I do my own native library building, using ndk-build command line tool, and my libs are placed alongside that libapp.so. It's not causing any issues btw, but I feel that I'm losing the control over what is built and why.
Here's my humble build.gradle file:
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
/**
* Path to *.so files
*/
sourceSets {
main {
jniLibs.srcDirs = ['src/main/libs']
jni.srcDirs = [] //disable automatic ndk-build
}
}
defaultConfig {
applicationId "com.sample.android"
minSdkVersion 9
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.0.0'
}
How can I disable this libapp.so being built?
defaultConfig {
ndk {
moduleName "yourSelfLib"
}
}
I want to use c++ STL in android, but when I include STL (ex: hash_map), then run that occur error.
I use android studio 1.0.2 and android ndk r10d
This is my build.gradle file:
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.example.ndktest"
minSdkVersion 15
targetSdkVersion 21
versionCode 1
versionName "1.0"
ndk {
moduleName 'JNI'
stl 'stlport_shared'
}
}
productFlavors {
arm {
ndk {
abiFilters "armeabi", "armeabi-v7a"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
}
Error Message:
WARNING [Project: :app] Current NDK support is deprecated. Alternative will be provided in the future.
WARNING [Project: :app] Current NDK support is deprecated. Alternative will be provided in the future.
:app:preBuild
:app:compileArmDebugNdk
In file included from C:/Users/Sheng/Developer/android/SDK_Libs/android-ndk/sources/cxx-stl/stlport/stlport/stl/_algobase.h:46:0,
from C:/Users/Sheng/Developer/android/SDK_Libs/android-ndk/sources/cxx-stl/stlport/stlport/stl/_vector.h:34,
from C:/Users/Sheng/Developer/android/SDK_Libs/android-ndk/sources/cxx-stl/stlport/stlport/stl/_hashtable.h:34,
from C:/Users/Sheng/Developer/android/SDK_Libs/android-ndk/sources/cxx-stl/stlport/stlport/stl/_hash_map.h:34,
from C:/Users/Sheng/Developer/android/SDK_Libs/android-ndk/sources/cxx-stl/stlport/stlport/hash_map:38,
from C:\Users\Sheng\tmp\NDKTEST\app\src\main\jni\maps.h:5,
from C:\Users\Sheng\tmp\NDKTEST\app\src\main\jni\maps.cpp:1:
C:/Users/Sheng/Developer/android/SDK_Libs/android-ndk/sources/cxx-stl/stlport/stlport/stl/_cstdlib.h: In function 'long int abs(long int)':
C:/Users/Sheng/Developer/android/SDK_Libs/android-ndk/sources/cxx-stl/stlport/stlport/stl/_cstdlib.h:131:25: error: declaration of C function 'long int abs(long int)' conflicts with
inline long abs(long __x) { return _STLP_VENDOR_CSTD::labs(__x); }
^
more...
How can I solve?
Thanks.