本次實現(xiàn)二維碼的掃描是基于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布局。另外還增加了一個用于開關(guān)閃光燈的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,權(quán)限
在AndroidManifest.xml中添加如下:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.FLASHLIGHT" />
對于Android6.0以后的版本還需動態(tài)申請權(quán)限,在MainActivity中添加申請權(quán)限代碼:
private void requsetPermission(){
if (Build.VERSION.SDK_INT>22){
if (ContextCompat.checkSelfPermission(MainActivity.this,
android.Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED){
//先判斷有沒有權(quán)限 ,沒有就在這里進行權(quán)限的申請
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){
//這里已經(jīng)獲取到了攝像頭的權(quán)限,想干嘛干嘛了可以
}else {
//這里是拒絕給APP攝像頭權(quán)限,給個提示什么的說明一下都可以。
Toast.makeText(MainActivity.this,"請手動打開相機權(quán)限",Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
}
4,啟動掃描活動
這里我們通過按鍵來啟動掃描功能,當(dāng)點擊按鍵后啟動掃描活動,開始掃描二維碼。
public void onClick(View v) {
switch (v.getId()){
case R.id.button1:
/*以下是啟動我們自定義的掃描活動*/
IntentIntegrator intentIntegrator = new IntentIntegrator(MainActivity.this);
intentIntegrator.setBeepEnabled(true);
/*設(shè)置啟動我們自定義的掃描活動,若不設(shè)置,將啟動默認(rèn)活動*/
intentIntegrator.setCaptureActivity(ScanActivity.class);
intentIntegrator.initiateScan();
break;
}
}
以下是是獲取掃描結(jié)果,并顯示:
@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
主要內(nèi)容如下:
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);
/*根據(jù)閃光燈狀態(tài)設(shè)置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;
}
});
/*開關(guān)閃光燈*/
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);
}
}
效果圖:

image.png

image.png

image.png