After few weeks of pain, I succed. Here is my correct code for Android studio 1.3.1, OpenCv 2.4.11. First you should do this OpenCV in Android Studio
(don't use paths which contains white space, both for project and opencv extraction folder) then, for opencv to be native:
gradle-wrapper.properties:
distributionUrl=https://services.gradle.org/distributions/gradle-2.5-all.zip
build.gradle(application):
classpath 'com.android.tools.build:gradle-experimental:0.2.0'
build.gradle(module):
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.0"
defaultConfig.with {
applicationId = "android.overloaded.nativetestv4"
minSdkVersion.apiLevel = 18
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = "1.0"
}
}
android.ndk{
moduleName = "mymodule"
ldLibs += ['log']
cppFlags += "-std=c++11"
cppFlags += "-fexceptions"
cppFlags += "-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include")}".toString()
cppFlags += "-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include/opencv")}".toString()
// ldFlags += linkOpt
ldLibs += ["android", "EGL", "GLESv2", "dl", "log", "z"]// , "ibopencv_core"
stl = "gnustl_shared"//"gnustl_static"//"gnustl_shared"//"stlport_static"
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles += file('proguard-rules.pro')
}
}
android.productFlavors {
create("arm") {
ndk.with {
abiFilters += "armeabi"
File curDir = file('./')
curDir = file(curDir.absolutePath)
String libsDir = curDir.absolutePath+"\src\main\jniLibs\armeabi" //"-L" +
ldLibs += libsDir + "libnative_camera_r4.3.0.so"
ldLibs += libsDir + "libopencv_contrib.a"
ldLibs += libsDir + "libopencv_core.a"
ldLibs += libsDir + "libopencv_highgui.a"
ldLibs += libsDir + "libopencv_imgproc.a"
ldLibs += libsDir + "libopencv_info.so"
ldLibs += libsDir + "libopencv_java.so"
ldLibs += libsDir + "libopencv_legacy.a"
ldLibs += libsDir + "libopencv_ml.a"
ldLibs += libsDir + "libopencv_ts.a"
}
}
create("armv7") {
ndk.with {
abiFilters += "armeabi-v7a"
File curDir = file('./')
curDir = file(curDir.absolutePath)
String libsDir = curDir.absolutePath+"\src\main\jniLibs\armeabi-v7a" //"-L" +
ldLibs += libsDir + "libnative_camera_r4.3.0.so"
ldLibs += libsDir + "libopencv_contrib.a"
ldLibs += libsDir + "libopencv_core.a"
ldLibs += libsDir + "libopencv_highgui.a"
ldLibs += libsDir + "libopencv_imgproc.a"
ldLibs += libsDir + "libopencv_info.so"
ldLibs += libsDir + "libopencv_java.so"
ldLibs += libsDir + "libopencv_legacy.a"
ldLibs += libsDir + "libopencv_ml.a"
ldLibs += libsDir + "libopencv_ts.a"
}
}
create("x86") {
ndk.with {
abiFilters += "x86"
}
}
create("mips") {
ndk.with {
abiFilters += "mips"
}
}
create("fat") {
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:23.0.0'
compile project(':openCVLibrary2411')
}
.cpp
#include <jni.h>
#include <vector>
#include <string>
#include "helpers.h"
#include <opencv2/core/core.hpp>
using namespace std;
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jstring JNICALL
Java_android_overloaded_nativetestv4_MainActivity_FuncV1(JNIEnv *env, jclass type) {
cv::Mat mat(33,22, 1);
string s = "Cpp v1 - succ, rows#:" + Helpers::ToStringNum(mat.rows);
Helpers::Log(s);
return env->NewStringUTF(s.data());
}
}
.java
package android.overloaded.nativetestv4;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity
{
static {
System.loadLibrary("mymodule");
}
public static native String FuncV1();
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(this, FuncV1(), Toast.LENGTH_LONG).show();
((TextView)findViewById(R.id.txtInfo)).setText(FuncV1());
}
Update for Android Studio 1.5.1, OpenCV 3.1
1. First you should do this OpenCV in Android Studio (don't use paths which contains white space, both for project and opencv extraction folder), after that you should have normal working Java app
2. Change build.gradle in project root:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle-experimental:0.4.0"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
- Change gradle-wrapper.properties:
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https://services.gradle.org/distributions/gradle-2.8-all.zip
Change build.gradle in opencv module:
apply plugin: 'com.android.model.library'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.2"
defaultConfig.with {
minSdkVersion.apiLevel = 11
targetSdkVersion.apiLevel = 23
}
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file("proguard-rules.txt"))
}
}
}
Change build.gradle in app module:
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.2"
defaultConfig.with {
applicationId = "android.overloaded.opencv31v1" //Name of package
minSdkVersion.apiLevel = 11
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = "1.0"
}
}
android.ndk {
moduleName = "native" // Name of C++ module, for System.loadLibrary("native")
cppFlags.add("-std=c++11") // Add provisions to allow C++11 functionality
cppFlags.add("-fexceptions")
// YOUR OPENCV DIRECTORY!!!
cppFlags.add("-I${file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include")}".toString())
ldLibs.addAll(["android", "EGL", "GLESv2", "dl", "log", "z"])
stl = "gnustl_shared"
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file("proguard-rules.txt"))
}
}
android.productFlavors {
create("arm") {
ndk.with{
abiFilters.add("armeabi")
File curDir = file('./')
curDir = file(curDir.absolutePath)
String libsDir = curDir.absolutePath + "\src\main\jniLibs\armeabi"
ldLibs.add(libsDir + "libopencv_core.a")
ldLibs.add(libsDir + "libopencv_highgui.a")
ldLibs.add(libsDir + "libopencv_imgproc.a")
ldLibs.add(libsDir + "libopencv_java3.so")
ldLibs.add(libsDir + "libopencv_ml.a")
}
}
create("armv7") {
ndk.with {
abiFilters.add("armeabi-v7a")
File curDir = file('./')
curDir = file(curDir.absolutePath)
String libsDir = curDir.absolutePath + "\src\main\jniLibs\armeabi-v7a"
ldLibs.add(libsDir + "libopencv_core.a")
ldLibs.add(libsDir + "libopencv_highgui.a")
ldLibs.add(libsDir + "libopencv_imgproc.a")
ldLibs.add(libsDir + "libopencv_java3.so")
ldLibs.add(libsDir + "libopencv_ml.a")
ldLibs.add(libsDir + "libopencv_ts.a")
}
}
}
android.sources{
main{
jni{
source{
srcDirs += ['src/main/jniMy']
}
}
}
}
}
dependencies {
compile fileTree(dir: "libs", include: [$/*.jar/$])
compile "com.android.support:appcompat-v7:23.1.1" //Do not use 23.2.0
compile project(":openCVLibrary310")
}
Create dir app/src/main/jniMy, this is place for yours .cpp files
Optionally create file chelper.c in jniMy, with this code:
#ifndef OPENCV31V1_CHELPER_H
#define OPENCV31V1_CHELPER_H
#include <jni.h>
#include <vector>
#include <string>
#include <sstream>
#include <android/log.h>
using namespace std;
class Helpers{
public:
template <typename T>
static string ToStringNum(T tNumber){
ostringstream ostrStream;
ostrStream << tNumber;
return ostrStream.str();
}
static void Log(string s){
__android_log_print(ANDROID_LOG_INFO, "My", s.data());
}
static void Log(std::exception ee){
string s = "Exception: " + string(ee.what()) ;
__android_log_print(ANDROID_LOG_INFO, "My", s.data());
}
static long Time(){
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
return (long)((int64_t)now.tv_sec * 1000LL + now.tv_nsec /1000000LL);
}
static string Time(long iTime){
return ToStringNum(Time() - iTime) + "ms";
}
};
#endif //OPENCV31V1_CHELPER_H
Create file native_exporter.cpp in jniMy, with this code:
#include <jni.h>
#include <string>
#include <opencv2/core/core.hpp>
#include "chelper.h"
extern "C"{
JNIEXPORT jstring JNICALLJava_android_overloaded_opencv31v1_MainActivity_FuncV1(JNIEnv *env,
jclass type) {
cv::Mat mat(33,22, CV_32FC2);
string s = "Cpp v1 - succ, rows#:" +Helpers::ToStringNum(mat.rows);
Helpers::Log(s);
auto i = 5;
for (int i2 : {1,3,5}){
Helpers::Log(Helpers::ToStringNum(i2));
}
return env->NewStringUTF(s.data());
}
}
Code in MainActivity.java:
<pr