几乎把网上的方法都试了个遍都不管用,不管是中文的还是stack overflow上的,(包括如在project structure里添加module dependency,修改sourceSets.main.jni.srcDirs = [] 的方法等等),Jni里都无法找到opencv头文件和.so库。 (可能老版本的Android Studio里管用)
最后找到了谷歌官方的例子程序hello-libs,用com.android.tools.build:gradle-experimental实现了opencv库的调用。
不用添加module dependency,不用手动编写***.mk文件,主要只需修改Src/build.gradle里面的配置。 各个版本号的兼容是个蛋疼的问题,列出我这里的版本号:android stuio 2.1.3 gadle version 2.14.1 gradle-experimental 0.7.3。
这里假设你已经配置好了DNK且对如何添加jni比较熟悉,下面只列出关键步骤。
工程的build.gradle如下:
buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle-experimental:0.7.3' // 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 }
在工程下建目录distribution,把opencv库的头文件和库文件拷到这个目录下。
Src/build.gradle如下,注意repositories,binaries,soures里面的写法。
apply plugin: 'com.android.model.application' def lib_distribution_root = '../distribution' // model { repositories { libs(PrebuiltLibraries) { opencv_java3 { headers.srcDir "${lib_distribution_root}/opencv310/include" binaries.withType(SharedLibraryBinary) { sharedLibraryFile = file("${lib_distribution_root}/opencv310/lib/${targetPlatform.getName()}/libopencv_java3.so") } } } } binaries { withType(CUnitTestSuiteBinarySpec) { lib library: "opencv_java3", linkage: "shared" } } } model{ android { compileSdkVersion = 21 buildToolsVersion = '21.1.2' defaultConfig { applicationId = 'com.example.messi520.face_detector' minSdkVersion.apiLevel = 17 targetSdkVersion.apiLevel = 21 versionCode = 1 versionName = '1.0' } ndk { moduleName = 'wsfacedetector' //stl = 'stlport_static' toolchain = 'clang' stl = "gnustl_static" cppFlags.addAll(['-std=c++11']) ldLibs.addAll(['android', 'log']) } sources { main { jni { dependencies { library 'opencv_java3' linkage 'shared' } } jniLibs { source { srcDir "${lib_distribution_root}/opencv310/lib" } } } } buildTypes { release { minifyEnabled false //proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles.add(file('proguard-android.txt')) } } } } dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') compile 'com.android.support:appcompat-v7:21.0.0' }
需要注意的地方:
换成com.android.tools.build:gradle-experimental插件后,com.android.application要换成com.android.model.application,同样下面添加最外层model.注意里面参数的写法有些需要改变如applicationId ='com.example.messi520.face_detector',minSdkVersion.apiLevel= 17等等。
要注意gradle-experimental,com.android.support:appcompat-v7,compileSdkVersion,buildToolsVersion等等的版本兼容。gradle-experimental可以在你安装的Android\Android Studio\gradle里搜索,找版本号。
谷歌的例子,在jni里调用第三方库(hellow-libs):http://download.csdn.net/detail/birdwcp/9634680
另外,读写sdcard里的文件需要在AndroidManifest.xml里加入如下:
<!-- 在SDCard中创建与删除文件权限 -->
<uses-permissionandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 往SDCard写入数据权限 -->
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
最后效果,把C++的人脸检测算法移植到了android上。