1、在项目local.properties文件中配置NDK版本:
2、配置编译目录
cpp 目录为编译脚本,源代码和头文件目录
jniLibs 为第三方so库目录,
3、添加第三方so库
注意子目录名称按照so库编译模式命名;
编译模式:“armeabi”,“armeabi-v7a” ,“arm64-v8a”,“x86”,“x86_64” ,“mips”, “mips64”
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/48c40c09aff9abdaed6f0c1b86eb829a.png)
4、添加jni的native的java调用类;
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/9fd12c9e401592462833557c326ebcb1.png)
5、编辑JNI接口调用native的java文件
package com.signature.sdk;
public class SkfNative {
private static SkfNative mNative = null;
static {
System.loadLibrary(“c++_shared”);
System.loadLibrary(“JKLX_UKEY_GMAPI_TF”);
System.loadLibrary(“JKLX_UKEY_GMAPI_TF.bak”);
System.loadLibrary(“skf”);
}
public static SkfNative getInstance() {
if (mNative == null) {
mNative = new SkfNative();
}
return mNative;
}
/**
* 初始化连接设备
* @return 返回初始化连接结果
*/
public native int InitDevice();
/**
* 反初始化断开设备
* @return 返回反初始化断开设备结果
*/
public native int DeInitDevice();
}
6、编辑JNI接口调用native的cpp文件
7、添加第三方库的接口.h头文件
8、编辑JNI调用接口Native的cpp文件源码
#include <jni.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <android/log.h>
#include “include/SKF.h”
#include “include/SKF_define.h”
/* Header for class com_signature_sdk_SkfNative */
#ifndef _Included_com_signature_sdk_SkfNative
#define _Included_com_signature_sdk_SkfNative
#ifdef __cplusplus
extern “C” {
#endif
static const char *D_TAG=“LibSkfSignEncryLib”;
#define LOGD(fmt, args…) __android_log_print(ANDROID_LOG_DEBUG, D_TAG, fmt, ##args)
#define LOGW(fmt, args…) __android_log_print(ANDROID_LOG_WARN, D_TAG, fmt, ##args)
#define LOGE(fmt, args…) __android_log_print(ANDROID_LOG_ERROR, D_TAG, fmt, ##args)
static int MAX_LEN = 32;
static int INVALID_LEN = 8;
char pName[] = “Wosign-SmartClient-App-01”;
char pPin[] = “123456”;
HAPPLICATION* pApp = NULL;
DEVHANDLE* pDev = NULL;
HCONTAINER* pContainer = NULL;
HANDLE* pAgreeHandle = NULL;
HANDLE* pKeyHandle = NULL;
HANDLE* pEnHandle = NULL;
HANDLE* pDeHandle = NULL;
HANDLE* pDigestHandle = NULL;
HANDLE* pMacHandle = NULL;
/*
-
Class: com_signature_sdk_SkfNative
-
Method: InitDevice
-
Signature: ()I
/
JNIEXPORT jint JNICALL Java_com_signature_sdk_SkfNative_InitDevice(JNIEnv env, jobject obj)
{
ULONG ret = 0;
BOOL bPresent = TRUE;
int pSize = 256 * 160;ret = SKF_EnumDev(bPresent, NULL, (ULONG*)&pSize);
if(ret != 0) {
LOGD(“SKF_EnumDev(pSize) fail.”);
return ret;
}
char nameList[pSize];
ret = SKF_EnumDev(bPresent, nameList, (ULONG*)&pSize);
if(pSize == 0) {
LOGD(“SKF_EnumDev() none device.”);
ret = -1001;
return ret;
}
ret = SKF_ConnectDev(nameList, pDev);
if(ret != 0) {
LOGD(“SKF_ConnectDev() fail.”);
return ret;
}
return ret;
}
/*
- Class: com_signature_sdk_SkfNative
- Method: DeInitDevice
- Signature: ()I
/
JNIEXPORT jint JNICALL Java_com_signature_sdk_SkfNative_DeInitDevice(JNIEnv env, jobject obj)
{
ULONG ret = 1;
if(pDev == NULL) {
LOGD(“DeInitDevice() pDev is null.”);
return -1001;
}
ret = SKF_DisConnectDev(*pDev);
return ret;
}
#ifdef __cplusplus
}
#endif
#endif
9、添加Cmake的打包脚本文件CMakeLists.txt文件
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/c8712272b5337a03518aaf8af60e4033.png)
10、编辑添加CMakeList.txt打包脚本
#设置cmake的最小版本
cmake_minimum_required(VERSION 3.10.2)
#设置编译输出类型
set(CMAKE_BUILD_TYPE Debug)
#set(CMAKE_BUILD_TYPE Release)
set(CMAKE_CXX_FLAGS_DEBUG “
E
N
V
C
X
X
F
L
A
G
S
−
O
0
−
W
a
l
l
−
g
−
g
g
d
b
−
W
l
,
−
r
p
a
t
h
=
.
/
l
i
b
s
"
)
s
e
t
(
C
M
A
K
E
C
X
X
F
L
A
G
S
R
E
L
E
A
S
E
"
ENV{CXXFLAGS} -O0 -Wall -g -ggdb -Wl,-rpath=./libs") set(CMAKE_CXX_FLAGS_RELEASE "
ENVCXXFLAGS−O0−Wall−g−ggdb−Wl,−rpath=./libs")set(CMAKECXXFLAGSRELEASE"ENV{CXXFLAGS} -O3 -Wl,-rpath=./libs”)
#设置第三方库头文件所在位置
include_directories(${CMAKE_SOURCE_DIR}/include)
#设置自定义封装的生成的so库
add_library( # Sets the name of the library.
skf
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
SkfSignEncryLib.cpp
)
#添加自定义封装so库调用的第三方so库的头文件include目录
target_include_directories( # Specifies the target library.
skf
PRIVATE
# included in the NDK.
${CMAKE_SOURCE_DIR}/include
)
#依赖的第三方.so/ .a库 (Android6.0和之后的版本添加.so/ .a库方式)
set(CMAKE_CXX_FLAGS “
C
M
A
K
E
C
X
X
F
L
A
G
S
−
L
{CMAKE_CXX_FLAGS} -L
CMAKECXXFLAGS−L{CMAKE_SOURCE_DIR}/…/jniLibs/${ANDROID_ABI}”)
#依赖的第三方so库 (Android6.0之前的版本才支持该添加动态库方式)
#add_library(JKLX_UKEY_GMAPI_TF SHARED IMPORTED)
#set_target_properties( # Specifies the target library.
JKLX_UKEY_GMAPI_TF
# Specifies the parameter you want to define.
PROPERTIES IMPORTED_LOCATION
# Provides the path to the library you want to import.
${CMAKE_SOURCE_DIR}/…/jniLibs/armeabi-v7a/libJKLX_UKEY_GMAPI_TF.so
)
#add_library(JKLX_UKEY_GMAPI_TF.bak SHARED IMPORTED)
#set_target_properties( # Specifies the target library.
JKLX_UKEY_GMAPI_TF.bak
# Specifies the parameter you want to define.
PROPERTIES IMPORTED_LOCATION
# Provides the path to the library you want to import.
${CMAKE_SOURCE_DIR}/…/jniLibs/armeabi-v7a/libJKLX_UKEY_GMAPI_TF.bak.so
)
#add_library(c++_shared SHARED IMPORTED)
#set_target_properties( # Specifies the target library.
c++_shared
# Specifies the parameter you want to define.
PROPERTIES IMPORTED_LOCATION
# Provides the path to the library you want to import.
${CMAKE_SOURCE_DIR}/…/jniLibs/armeabi-v7a/libc++_shared.so
)
添加android系统库
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
#配置链接库,需要注意的是链接的顺序应该符合gcc链接的顺序规则,即被链接的库放在依赖它的库的后面,比如lib1依赖于lib2,lib2依赖于lib3,那么target_link_libraries(name lib1 lib2 lib3)。
target_link_libraries( # Specifies the target library.
skf
# Links the target library to the log library
JKLX_UKEY_GMAPI_TF
JKLX_UKEY_GMAPI_TF.bak
c++_shared
# included in the NDK.
${log-lib}
${android-lib}
)
=======================================================================================================
11、在Build.grade中添加编译配置
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/7741c708253457ccf38f6b797dae0aeb.png)
12、配置gradle编译设置
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/57148d385b699dc02ee220df043227be.png)
plugins {
id ‘com.android.application’
id ‘kotlin-android’
}
android {
compileSdkVersion 28
buildToolsVersion ‘28.0.3’
defaultConfig {
applicationId "com.eloam.skfsignaturesdktest"
minSdkVersion 21
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions"
abiFilters "armeabi-v7a"
}
}
ndk{
abiFilters "armeabi-v7a" /*, "arm64-v8a", "x86", "x86_64"*/
}
}
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
packagingOptions {
pickFirst 'lib/armeabi-v7a/libc++_shared.so'
pickFirst 'lib/armeabi-v7a/libJKLX_UKEY_GMAPI_TF.bak.so'
pickFirst 'lib/armeabi-v7a/libJKLX_UKEY_GMAPI_TF.so'
}
//ndkVersion '21.1.6352462'
}
dependencies {
implementation fileTree(dir: ‘libs’, include: [‘.jar’,'.aar’])
implementation “org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version”
implementation ‘androidx.core:core-ktx:1.3.2’
implementation ‘androidx.appcompat:appcompat:1.2.0’
implementation ‘com.google.android.material:material:1.2.1’
implementation ‘androidx.constraintlayout:constraintlayout:2.0.4’
testImplementation ‘junit:junit:4.+’
androidTestImplementation ‘androidx.test.ext:junit:1.1.2’
androidTestImplementation ‘androidx.test.espresso:espresso-core:3.3.0’
//动态权限
implementation 'com.hjq:xxpermissions:6.2'
}
13、编译程序