本次实现二维码的扫描是基于ZXing Android Embedded这个库,该库对Google官方ZXing进行了封装,使用很方便。
1,添加库
首先添加库的集成,在app/build.gradle中添加如下:
implementation 'com.journeyapps:zxing-android-embedded:3.6.0'
implementation 'com.google.zxing:core:3.3.0'
2,布局
布局文件主要有三个:
activity_main.xml:主活动
activity_scan.xml:扫描活动
content_scan.xml:扫描布局
主活动里就简单放了一个按键和Textview:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:id="@+id/text_result"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始"
android:id="@+id/button1"/>
</LinearLayout>
content_scan.xml如下:
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.journeyapps.barcodescanner.BarcodeView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/zxing_barcode_surface"
app:zxing_framing_rect_width="250dp"
app:zxing_framing_rect_height="250dp"/>
<com.journeyapps.barcodescanner.ViewfinderView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/zxing_viewfinder_view"
app:zxing_possible_result_points="@color/zxing_custom_possible_result_points"
app:zxing_result_view="@color/zxing_custom_result_view"
app:zxing_viewfinder_laser="@color/zxing_custom_viewfinder_laser"
app:zxing_viewfinder_mask="@color/zxing_custom_viewfinder_mask"/>
<TextView
android:id="@+id/zxing_status_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:background="@color/zxing_transparent"
android:text="@string/zxing_msg_default_status"
android:textColor="@color/zxing_status_text"/>
</merge>
在activity_scan.xml中添加com.journeyapps.barcodescanner.DecoratedBarcodeView,该DecoratedBarcodeView引用上述content_scan布局。另外还增加了一个用于开关闪光灯的ImageButton。如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.journeyapps.barcodescanner.DecoratedBarcodeView
android:id="@+id/dbv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
app:zxing_scanner_layout="@layout/content_scan">
</com.journeyapps.barcodescanner.DecoratedBarcodeView>
<ImageButton
android:id="@+id/button_led"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="60dp"
android:background="@drawable/image_bg_off"
/>
</RelativeLayout>
3,权限
在AndroidManifest.xml中添加如下:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.FLASHLIGHT" />
对于Android6.0以后的版本还需动态申请权限,在MainActivity中添加申请权限代码:
private void requsetPermission(){
if (Build.VERSION.SDK_INT>22){
if (ContextCompat.checkSelfPermission(MainActivity.this,
android.Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED){
//先判断有没有权限 ,没有就在这里进行权限的申请
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{android.Manifest.permission.CAMERA},1);
}else {
}
}else {
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case 1:
if (grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
//这里已经获取到了摄像头的权限,想干嘛干嘛了可以
}else {
//这里是拒绝给APP摄像头权限,给个提示什么的说明一下都可以。
Toast.makeText(MainActivity.this,"请手动打开相机权限",Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
}
4,启动扫描活动
这里我们通过按键来启动扫描功能,当点击按键后启动扫描活动,开始扫描二维码。
public void onClick(View v) {
switch (v.getId()){
case R.id.button1:
/*以下是启动我们自定义的扫描活动*/
IntentIntegrator intentIntegrator = new IntentIntegrator(MainActivity.this);
intentIntegrator.setBeepEnabled(true);
/*设置启动我们自定义的扫描活动,若不设置,将启动默认活动*/
intentIntegrator.setCaptureActivity(ScanActivity.class);
intentIntegrator.initiateScan();
break;
}
}
以下是是获取扫描结果,并显示:
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
if(result != null) {
if(result.getContents() == null) {
Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();
testResult.setText(result.getContents());
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
5,扫描活动ScanActivity
主要内容如下:
public class ScanActivity extends AppCompatActivity {
private CaptureManager capture;
private ImageButton buttonLed;
private DecoratedBarcodeView barcodeScannerView;
private boolean bTorch = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
barcodeScannerView = initializeContent();
buttonLed = findViewById(R.id.button_led);
/*根据闪光灯状态设置imagebutton*/
barcodeScannerView.setTorchListener(new DecoratedBarcodeView.TorchListener() {
@Override
public void onTorchOn() {
buttonLed.setBackground(getResources().getDrawable(R.drawable.image_bg_on));
bTorch = true;
}
@Override
public void onTorchOff() {
buttonLed.setBackground(getResources().getDrawable(R.drawable.image_bg_off));
bTorch = false;
}
});
/*开关闪光灯*/
buttonLed.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(bTorch){
barcodeScannerView.setTorchOff();
} else {
barcodeScannerView.setTorchOn();
}
}
});
capture = new CaptureManager(this, barcodeScannerView);
capture.initializeFromIntent(getIntent(), savedInstanceState);
capture.decode();
}
/**
* Override to use a different layout.
*
* @return the DecoratedBarcodeView
*/
protected DecoratedBarcodeView initializeContent() {
setContentView(R.layout.activity_scan);
return (DecoratedBarcodeView)findViewById(R.id.dbv);
}
@Override
protected void onResume() {
super.onResume();
capture.onResume();
}
@Override
protected void onPause() {
super.onPause();
capture.onPause();
barcodeScannerView.setTorchOff();
}
@Override
protected void onDestroy() {
super.onDestroy();
capture.onDestroy();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
capture.onSaveInstanceState(outState);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
capture.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return barcodeScannerView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
}
}