在React Native模块项目中如何使用AAR文件?官网没有相关信息。只能通过Google,StackOverflow和GitHub去寻找答案。这里分享下如何使用Dynamsoft提供的barcode AAR文件创建一个React Native barcode组件,以及如何在React Native项目中使用这个组件。
为Android创建React Native桥接组件
要调用AAR文件,肯定要写Java代码。使用Android Studio来辅助完成React Native模块并不是一帆风顺的。
错误:Plugin with id ‘com.android.library’ not found
之前我编写了一个'hello world'组件,build.gradle是这样的:
apply plugin: 'com.android.library'
android {
compileSdkVersion 23
buildToolsVersion "25.0.0"
defaultConfig {
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
}
dependencies {
compile "com.facebook.react:react-native:+"
}
通过React Native命令行去编译运行完全没有问题,可是导入到Android Studio的时候会报错。
要解决这个问题,需要加一点东西:
apply plugin: 'com.android.library'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.0'
}
}
allprojects {
repositories {
mavenLocal()
jcenter()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
flatDir{
dirs "$rootDir/lib"
}
}
}
android {
compileSdkVersion 23
buildToolsVersion '25.0.0'
defaultConfig {
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
}
dependencies {
compile 'com.facebook.react:react-native:+'
compile(name:'DynamsoftBarcodeReader', ext:'aar')
}
通常情况下在Android项目中要使用AAR文件可以通过菜单,把AAR文件当作module导入进来,然后在项目设置中关联。这样比较麻烦。另一种比较干净的方法就是设置库的路径,然后在build.gradle中添加:
compile(name:'DynamsoftBarcodeReader', ext:'aar')
找不到AAR文件
Android Studio顺利编译模块工程之后,在React Native工程中使用下面的命令导入组件,构建工程:
npm install
react-native link
react-native run-android
这个时候会碰到下面的错误:
找不到模块中使用的AAR文件。解决方法是在React Native工程的build.gradle中加入模块路径:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
}
}
allprojects {
repositories {
mavenLocal()
jcenter()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
flatDir{
dirs "$rootDir/../node_modules/react-native-dbr/android/lib"
}
}
}
重新执行“react-native run-android”就可以了。
使用React Native创建barcode app
UI元素
UI比较简单,一个按钮和一个文本。点击按钮触发barcode扫描,然后把结果显示在文本上。
constructor(props) {
super(props);
this.state = {
result: 'N/A'
};
this.onButtonPress = this
.onButtonPress
.bind(this);
}
onButtonPress() {
BarcodeReaderManager.readBarcode('C6154D1B6B9BD0CBFB12D32099F20B35', (msg) => {
this.setState({result: msg});
}, (err) => {
console.log(err);
});
};
render() {
return (
<View style={styles.container}>
<Button title='Read Barcode' onPress={this.onButtonPress}/>
<Text style={styles.display}>
Barcode Result: {this.state.result}
</Text>
</View>
);
}
}
如何识别barcode
这里的实现逻辑是把barcode识别放在一个独立的Activity中。通过桥接的代码去启动这个Activity。检测完之后在onActivityResult中返回结果:
private final ActivityEventListener mActivityEventListener = new BaseActivityEventListener() {
@Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent intent) {
if (requestCode == REQUEST_CODE) {
if (mResultCallback != null) {
if (resultCode == Activity.RESULT_OK) {
JSONObject obj = new JSONObject();
try {
obj.put(TEXT, intent.getStringExtra("SCAN_RESULT"));
obj.put(FORMAT, intent.getStringExtra("SCAN_RESULT_FORMAT"));
} catch (JSONException e) {
Log.d(LOG_TAG, "This should never happen");
}
mResultCallback.invoke(obj.toString());
} else if (resultCode == Activity.RESULT_CANCELED) {
Toast.makeText(getReactApplicationContext(), "Cancelled", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getReactApplicationContext(), "Unexpected error", Toast.LENGTH_LONG).show();
}
}
}
}
};
@ReactMethod
public void readBarcode(String license, Callback resultCallback, Callback errorCallback) {
mResultCallback = resultCallback;
Activity currentActivity = getCurrentActivity();
if (currentActivity == null) {
errorCallback.invoke("Activity doesn't exist");
return;
}
Intent cameraIntent = new Intent(currentActivity.getBaseContext(), DBR.class);
cameraIntent.setAction("com.dynamsoft.dbr");
cameraIntent.putExtra("license", license);
cameraIntent.setPackage(currentActivity.getApplicationContext().getPackageName());
currentActivity.startActivityForResult(cameraIntent, REQUEST_CODE);
}
记得在AndroidManifest.xml中加入需要使用的权限:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dynamsoft.barcodescanner"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-feature
android:name="android.hardware.camera"
android:required="false"/>
<uses-feature
android:name="android.hardware.camera.front"
android:required="false"/>
<uses-sdk android:minSdkVersion="15" tools:overrideLibrary="com.dynamsoft.barcode"/>
<application android:allowBackup="true"
android:label="@string/app_name">
<activity
android:name="com.dynamsoft.camera.DBR"
android:clearTaskOnLaunch="true"
android:configChanges="orientation|keyboardHidden|screenSize"
android:exported="false"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:windowSoftInputMode="stateAlwaysHidden"/>
</application>
</manifest>
导入模块的基本步骤
创建一个新工程:
react-native init NewProject
在package.json中添加依赖模块:
"dependencies": {
"react": "16.0.0-alpha.6",
"react-native": "0.43.3",
"react-native-dbr":"file:../"
},
然后通过“npm install”安装。也可以通过网络安装:
npm i react-native-dbr --save
关联依赖:
react-native link
在android/build.gradle中添加AAR的路径:
flatDir {
dirs "$rootDir/../node_modules/react-native-dbr/android/lib"
}
在index.android.js中使用JS接口:
import BarcodeReaderManager from 'react-native-dbr';
BarcodeReaderManager.readBarcode('C6154D1B6B9BD0CBFB12D32099F20B35', (msg) => {
this.setState({result: msg});
},
(err) => {
console.log(err);
});
App使用
运行程序:
点击按钮:
获得结果: