Does Android Wear support C++ (JNI) in Android Studio? - android

I cannot get an Android Wear project to use C++. I am able to get a "Phone and Tablet" project to use C++. Here is what I have done.
Here is an image of the SDK Tools I have installed. I also have SDK API Levels 24-27 installed.
I create a new project. I check "Include C++ support". I check "Wear" (API 26: Android 8.0 (Oreo)). I select "Next" a bunch.
For C++ Standard I have tried all three (Toolchain Default, C++11, c++14).
I do not check -fexceptions or -frtti.
In the project that is created under the "mobile" Module, I have a "cpp" folder, but I do not have one under the "wear" Module.
If I create a project without "Phone and Tablet" support ("mobile" Module), then I still do not get a "cpp" folder under the "wear" Module.
I tried forcing the project to use C++ under the "wear" Module. Here is what I did.
I modified build.gradle (Module: wear) to look like this
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.example.xorgaming.watchtestcpp"
minSdkVersion 25
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags "-std=c++11"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.google.android.support:wearable:2.2.0'
implementation 'com.google.android.gms:play-services-wearable:11.8.0'
implementation 'com.android.support:percent:26.1.0'
implementation 'com.android.support:support-v4:26.1.0'
implementation 'com.android.support:recyclerview-v7:26.1.0'
implementation 'com.android.support:wear:26.1.0'
compileOnly 'com.google.android.wearable:wearable:2.2.0'
}
I restart the project which makes a "cpp" folder under the "wear" module.
I create a native-lib.cpp file in the "cpp" folder. It looks like this:
extern "C"
JNIEXPORT jstring JNICALL Java_com_example_xorgaming_watchtestcpp_MainActivity_stringFromJNIWatch(
JNIEnv *env, jobject /* this */)
{
std::string hello = "Hello from C++ WATCH!";
return env->NewStringUTF(hello.c_str());
}
In my java onCreate() function, I call: stringFromJNIWatch().
Everything builds without error (green hammer)
When I run the project (as a wearable device) I get this error:
No implementation found for java.lang.String com.example.xorgaming.watchtestcpp.MainActivity.stringFromJNIWatch()
Any idea what I'm doing wrong? Does Android Wear support C++?

Things have changed quite a bit since this question was posted. But half of the answer is: Yes, you can use C++ and Java together with Wear OS. You can follow the same instructions for Android applications.
As for why this failed, my suggestion would be double-check the paths. If you follow the instructions here you will note that the cpp directory goes in the same directory with the java directory. Typically something like MyApplication/app/src/main will have a java directory and a cpp directory. That helps everything get wrapped up into the eventual .apk

Related

How do I include a C++ AAR-Library with CMake and Gradle in Android Studio

I wish to include yctung's AndroidLibSVM into my project, so i followed his instructions to import the .AAR and set the dependencies.
Install
Install is easy, you just import our AAR library into your Android project >by the following steps:
Right-click your module -> new -> module -> Import .JAR/.AAR Package -> >select our Release/androidlibsvm-release.aar
After this, you should add the app dependency by:
Right-click your app module -> open module setting -> clieck your app -> >dependencies -> + -> module dependency -> androidlibsvm
Now I could import and work with his library as expected and Android Studio would compile the code and build without any errors. The app runs fine on an emulated device, however, it crashes on my physical device as soon as it tries to run the part of code referring to yctung's library with the following error:
java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__aeabi_memcpy" referenced by "/data/app/com.krautkremer.nils.mymirror-1/lib/arm/libjnilibsvm.so"
Referring to this SO-question, the error might be caused by incorrect Cmake/Gradle settings. If I get it right, Tung used ndk-build for his project, while I am building with Cmake. Therefor, his instructions on how to install his library may not be sufficient in my case. In fact, i haven't made any changes to the default CMakeLists.txt which i unterstand to be crucial for Cmake.
I tried to add a few lines in the build.gradle and/or the CmakeLists file as they are commonly suggested in SO-solutions with no success, but i have to admit, i really don't understand what i am doing, even after reading the official guide.
I am kind of lost here, since i hardly know the difference between ndk-build and Cmake, not to mention how to set them up correctly or if this is even necessary in this case.
I'd be most grateful if someone could explain to me, how i can integrate AndroidLibSVM into my project correctly, what changes i have to make to my gradle/cmake files and how i have to set up my directories (in case this is part of the answer).
All i've downloaded so far is the .aar which indeed does contain a few .so files but i don't understand where to put them.
Now,
this is my build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.krautkremer.nils.mymirror"
minSdkVersion 23
targetSdkVersion 23
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags ""
arguments "-DANDROID_PLATFORM=android-23"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
packagingOptions {
//exclude 'META-INF/proguard/androidx-annotations.pro'
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.1.0-alpha01'
implementation 'androidx.media:media:1.1.0-alpha01'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha2'
implementation 'com.google.android.material:material:1.1.0-alpha01'
implementation 'androidx.annotation:annotation:1.0.1'
implementation 'com.google.firebase:firebase-core:16.0.6'
implementation 'com.google.firebase:firebase-ml-vision:18.0.2'
implementation 'com.google.firebase:firebase-ml-common:16.1.6'
implementation 'com.google.firebase:firebase-ml-vision-face-model:17.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1-alpha01'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1-alpha01'
implementation project(':androidlibsvm-release')
}
apply plugin: 'com.google.gms.google-services'
and this is my CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1)
add_library(
native-lib
SHARED
src/main/cpp/native-lib.cpp)
find_library(
log-lib
log)
target_link_libraries(
native-lib
${log-lib})
This is my directory structure.
Thank you in advance. If you need more to help me, i'd be happy to help you help me;)

Debugging C++/native library modules not working with Android Studio (Cmake used)

I'm having trouble debugging C++ files of my library module.
Is this possible in general?
The debugging works fine if the application project contains the c++ code.
But I want to move the C++ Code to a library module.
The Error Message while starting the session:
Now Launching Native Debug Session
Attention! No symbol directories found - please check your native debug configuration
gradle file of my lib:
apply plugin: 'com.android.library'
android {
compileSdkVersion 24
buildToolsVersion "25.0.2"
defaultConfig {
minSdkVersion 16
targetSdkVersion 21
versionCode 1
versionName "1.0"
externalNativeBuild {
cmake {
arguments "-DANDROID_PLATFORM_LEVEL=${11}",
'-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=gnustl_static'
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:support-annotations:24.2.0'
}
In the run configuration the debugger is set to auto
Additions:
Im using:
Gradle : 2.2.3
Android Studio : 2.2.3
in the LLLB Console, i checked the breakpoint List with:
breakpoint list -v
all my checkpoints are listed there.
Not Working Breakpoint
1: file = 'C:\android-dev\...\test.cpp', line = 19, exact_match = 0
..thats all
Working Breakpoint
1: file = 'C:\android-dev\...\test.cpp', line = 19, exact_match = 0
1.1:
module = C:\android-dev\...\test.so
compile unit = gl_code.cpp
function = testFunc(..)
location = C:\android-dev\...\test.cpp:16
address = 0x0000007f871d068c
resolved = true
hit count = 1
The reason seems to be, that a release version of the lib is created,
which does not support debugging, even if the app is built with debug options.
Solution:
To solve this issue, do the following workaround. It ensures that a debug version is built.
In your apps build.gradle change:
compile project(':nativelib')
to
compile project(path: ':nativelib' , configuration: 'debug')
In the libs build.gradle add:
android {
publishNonDefault true //this line
compileSdkVersion 24
buildToolsVersion "25.0.2"
defaultConfig {
...
}
...
}
Updates:
See the google issue for updates:
https://code.google.com/p/android/issues/detail?id=222276
I had the same error ("Attention! No symbol directories found - please check your native debug configuration."). My solution was (Android Studio 3.2):
Run → Edit Configuration → "Debugger" tab → add your working path to Symbol Directories.
I had the similar issue with my own libraries some months ago because I thought that if I added the -g (gcc) flag it would generate the debug symbols, as the desktop (linux, unix kernel) apps.
But, actually it does not work to generate debug symbols.
I see that you use Cmake as a external build tool and clang compiler.
So in my case I configure my cmake script with gcc but out of gradle scripting, but I think it will be the same, I add -mapcs-frame in the CMAKE_CXX_FLAGS.
externalNativeBuild {
cmake {
arguments "-DANDROID_PLATFORM_LEVEL=${11}",
'-DANDROID_TOOLCHAIN=gcc',
'-DANDROID_STL=gnustl_static',
'DCMAKE_CXX_FLAGS=-mapcs-frame'
}
}
I know that if you use clang compile may be this flag could not work. But my idea was to share my experience with android native debugging.
I Hope this clues could help you.
Cheers.
Unai.
In my case, it was because of co-worker who changed the visibility of symbols.
set(CMAKE_CXX_FLAGS -fvisibility=hidden)
After changing the above code to be applied only in release build, debugger(including breakpoints) works fine.

android studio experimental ndk c library

I built some test c and c++ programs using gradle following these examples
I was also able to setup android studio with the experimental features to build a android project calling native functions with the help of this answer
I know that I can build this project using the android.useDeprecatedNdk=true
and provide my android.mk file for android studio to compile and build the app.
Is it possible with the experimental feature to build this same program? This project is built with CMAKE and there are some compilation steps that output files that needs to link. ndk-build creates these files but I can't find a way to do it with with android experimental features.
I am attempting for testing purposes and to build a non trivial example of building a more complex project. I decided to try to build the zlib library.
Here is my build.gradle
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.1"
defaultConfig.with {
applicationId = "me.test.testnative_exp"
minSdkVersion.apiLevel = 10
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = "1.0"
buildConfigFields.with {
create() {
type = "int"
name = "VALUE"
value = "1"
}
}
}
}
compileOptions.with {
sourceCompatibility=JavaVersion.VERSION_1_7
targetCompatibility=JavaVersion.VERSION_1_7
}
android.ndk {
moduleName = "hello-jni"
cppFlags += "-I${file("src/main/jni/zlib")}".toString()
stl = "stlport_static"
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles += file('proguard-rules.pro')
}
}
android.sources {
main {
java {
source {
srcDir 'src'
}
}
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:design:23.0.1'
}
my project structure is
app/
build/
libs/
src/
src/main/testActivity.java
jni/zlib <- the zlib folder is the one that I downloaded from the zlib website.
jni/hello-jni.c
After syncing the build.gradle I get a link error on the header in file:
infbak9.c cannot find #include "zutil.h"
but both files are in the zlib directory under jni.
Is it possible to use the android studio experimental ndk build to compile this project?
there is good project in github that i use its structure in mine, it is nice example for start on "how use experimental(v_0.4.0) plugin in complex project?" :
https://github.com/frogermcs/FlatBuffs
*there are zlib in android NDK, just add appropriate cflag and ldLibs.add("z") in gradle. and in your native code include <zlib.h>
and a good experimental gradle config from google :
https://github.com/googlesamples/android-ndk/blob/229cbe86238d401bb06166b8dfadec8198532589/native-codec/app/build.gradle
you might check this repo for a group of samples:
https://github.com/googlesamples/android-ndk
your issue might be able to fixed by adding something as[from Teapot sample there]:
cppFlags.addAll(['-I' + "${ndkDir}/sources/android/cpufeatures",'-I' + file('src/main/jni/ndk_helper')])
just replace the directory with your own path "zutil.h" etc. you may also use the latest gradle-experimental version to simplify your script -- like removing ".with" for defaultConfig.with, delete java 7 version section( the latest android studio could handle java 8 ), those ".toString()" thing is also wordy so the samples have changed style to use "+" [those is not problem for your build error though]

build native openCV sources with Android Studio and NDK

I am trying to include some native cpp sources in my android app. I'm using Android Studio 1.0 with the gradle build system. I have three modules: my android app, the android opencv libs, the cpp sources (in the jni folder)
The build process gives me the following error:
D:\NVPACK\android-ndk-r10c\sources\cxx-stl\gnu-libstdc++\4.9\include\bits\stl_pair.h
Error:(96, 12) error: redefinition of 'struct std::pair<_T1, _T2>'
Error:(214, 5) error: redefinition of 'template<class _T1, class _T2> bool std::operator==(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)'
... and some other redefinitions with some other errors in other files.
It seems that the include paths are partially wrong or that there are duplicated headers (stl_pair.h) in the NDK This is my build.gradle file:
apply plugin: 'com.android.library'
android {
compileSdkVersion 21
buildToolsVersion "21.1.1"
defaultConfig {
minSdkVersion 15
targetSdkVersion 21
versionCode 1
versionName "1.0"
ndk{
moduleName "Native"
cFlags "-I'D:\\OpenCV-2.4.10-android-sdk\\sdk\\native\\jni\\include' " +
"-I'D:\\NVPACK\\android-ndk-r10c\\sources\\cxx-stl\\gnu-libstdc++\\4.9\\include' " +
"-I'D:\\NVPACK\\android-ndk-r10c\\sources\\cxx-stl\\gnu-libstdc++\\4.9\\libs\\armeabi-v7a\\include'"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
}
In cFlags I point to the openCV sources and to the c++ standard sources as described here. This works all fine until the above error.
I have only a very basic understanding of the whole build process when dealing with cpp sources as I normally work with c# .net or android (without native sources).
From my understanding the ndk-build should give me some .so files that I can use in my app. But the build of the natives failes. Am I missing something in the process?
edit: I switched to eclipse and could build and run the code. Maybe I try to switch back to android studio in the future, but this is not so important.

NDK in Android Studio not working

I am doing every single step from video:
https://www.youtube.com/watch?v=kFtxo7rr2HQ
but no shared libraries are generated.
Here is a version, where android-studio should generate shared libraries on his own. However when I create apropraite Makefiles and execute ndk-build, shared libraries are not generated as well.
MainActivity.java:
public native String HelloJNI();
static
{
System.loadLibrary("HelloJNI");
}
Build->Make Project
[*#* main]$ javah -d jni -classpath {sdk_dir}/platforms/android-14/android.jar:../../build/intermediates/classes/debug com.example.ndker.ndkapp.MainActivity
Creating HelloJNI.c:
#include "com_example_ndker_ndkapp_MainActivity.h"
JNIEXPORT jstring JNICALL Java_com_example_ndker_ndkapp_MainActivity_HelloJNI
(JNIEnv *, jobject) {
return (*env)->NewStringUTF(env, "Hello from jni");
}
local.properties:
sdk.dir={sdk_dir}
ndk.dir={ndk_dir}
build.grandle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.example.ndker.ndkapp"
minSdkVersion 14
targetSdkVersion 21
versionCode 1
versionName "1.0"
ndk {
moduleName "HelloJNI"
}
}
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'
}
Thank You for replies.
I've created a blog post that documents setting up Android Studio, Gradle, and the NDK here:
http://www.sureshjoshi.com/mobile/android-ndk-in-android-studio-with-swig/
Also, I've created a sample project in BitBucket with everything already set up for you here: https://bitbucket.org/sureshjoshi/android
Perhaps you could give those a try and see if they work for you?
The key thing is that Gradle will now automatically generate Makefiles and compile for you!
Right. If you put the video on HD, you can then realize that to generate the native compilation, you should use ";" instead of ":". Like:
[*#* main]$ javah -d jni -classpath {sdk_dir}/platforms/android-14/android.jar;../../build/intermediates/classes/debug com.example.ndker.ndkapp.MainActivity
Here is an screenshot of the screen (taken from the video you've posted)
Let me know if that did the trick!

Categories

Resources