1. 獲取權限
請注意動態申請及重寫申請結果返回方法。
<uses-permission android:name="android.permission.CAMERA"/>
2. 添加依賴
//Gradle Scripts -> build.gradle(Module:app)
implementation 'com.google.zxing:core:3.4.1'
implementation 'com.journeyapps:zxing-android-embedded:4.2.0'
3. 引入
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
4. 簡易掃碼
(1) 啟動掃碼
通常,掃碼是由一個按鈕觸發,跳轉至掃碼Activity(CaptureActivity)。
setDesiredBarcodeFormats()方法用于設置掃碼的類型(不同類型間逗號分隔):
-
Code 39 條形碼:
- 數據容量:通常用于較短的文本字符串,支持數字、大寫字母和一些特殊字符。
- 字符集:包含數字 0-9、大寫字母 A-Z 和一些特殊字符(如空格、破折號等)。
- 用途:廣泛用于工業、物流、標簽等領域,用于標識物品或包裝。
-
Code 93 條形碼:
- 數據容量:比 Code 39 更高,可以編碼更多字符。
- 字符集:支持所有的 ASCII 字符。
- 用途:常用于標簽、物流追蹤、文檔標識等領域,提供了更高的數據密度和安全性。
-
Code 128 條形碼:
- 數據容量:是一種高密度條形碼,具有更高的數據編碼能力。
- 字符集:支持所有的 128 個 ASCII 字符,包括數字、字母、符號等。
- 用途:廣泛應用于零售、物流、運輸等領域,用于編碼大量字符和數據。
-
UPC-A 條形碼:
- 數據容量:用于編碼商品標識符,可以編碼 12 個數字。
- 字符集:僅限數字。
- 用途:主要用于零售業,標識商品,常見于北美地區。
-
UPC-E 條形碼:
- 數據容量:壓縮版本的 UPC-A,可以編碼 6 個數字。
- 字符集:僅限數字。
- 用途:通常用于小型商品包裝,空間有限的情況下采用。
-
EAN-8 條形碼:
- 數據容量:編碼 8 個數字。
- 字符集:僅限數字。
- 用途:類似 UPC-E,用于小型商品包裝,空間有限的情況下采用。
-
EAN-13 條形碼:
- 數據容量:編碼 13 個數字。
- 字符集:僅限數字。
- 用途:在全球范圍內用于標識商品,常見于歐洲和其他地區
-
QR碼(Quick Response Code): 如前所述,這是一種由Denso Wave開發的二維碼,最初設計用于跟蹤汽車零部件。它被廣泛應用于各種領域,尤其是移動支付和信息快速傳遞。
-
Data Matrix: 這是另一種常見的二維碼類型,它是由美國公司International Data Matrix(ID Matrix)于1989年創建的。Data Matrix常用于工業標識和物流管理。
-
PDF417: 這是一種二維碼,其名稱源自它的編碼規范,即PDF(Portable Data File)417。它常用于存儲大量數據,如駕駛執照、護照和車輛注冊證明等。
-
Aztec Code: 這是一種用于存儲數據的二維碼,通常被用于票務和航空領域。
-
MaxiCode: 這是由美國郵政服務用于自動識別包裹的一種二維碼。
在中國常用的條碼格式為:EAN-13 和 UPC-A 。?
button.setOnClickListener(new View.OnClickListener() {public void onClick(View view) {IntentIntegrator intentIntegrator=new IntentIntegrator(MainActivity.this);//設置所需掃描的條碼格式----可有多種,且可同時有條碼和二維碼intentIntegrator.setDesiredBarcodeFormats(IntentIntegrator.CODE_39,IntentIntegrator.CODE_93,IntentIntegrator.CODE_128,IntentIntegrator.UPC_A,IntentIntegrator.UPC_E,IntentIntegrator.EAN_8,IntentIntegrator.EAN_13);intentIntegrator.setBeepEnabled(true);//掃描成功是否有提示音intentIntegrator.setPrompt("掃描");//提示字符串intentIntegrator.setCameraId(0);//設置攝像頭,0為背攝,1為正攝intentIntegrator.setOrientationLocked(false);//是否方向鎖定intentIntegrator.setBarcodeImageEnabled(true);//是否保存掃描成功的圖片intentIntegrator.initiateScan();//啟動掃描器}
});
(2) 獲取掃描結果
掃碼界面本身也是Activity,所以想要獲取掃碼結果可重寫onActivityResult()方法。
//本碼中TextView用于顯示掃碼結果
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {IntentResult intentResult=IntentIntegrator.parseActivityResult(requestCode, resultCode, data);//判斷是否為掃碼返回的if(intentResult!=null){//判斷是否掃描成功if(intentResult.getContents()!=null){textView.setText(intentResult.getContents());}else {textView.setText("掃描無結果");}}super.onActivityResult(requestCode, resultCode, data);
}
5. 自定義掃碼界面
掃碼頁面是由initiateScan()方法啟動,不斷查看源碼可知,該方法本質是啟動了一個名為CaptureActivity的頁面。
我們可以創建一個新的Activity并用setCaptureActivity()方法取代CaptureActivity。
為了使自定義的Activity具有CaptureActivity的能力,我們首先在Activity中設置一個com.journeyapps.barcodescanner.DecoratedBarcodeView控件,然后將CaptureActivity的Java代碼復制到Activity的Java文件中并修改部分id即可。還可以在Activity添加更多的控件以滿足我們的自定義需求。
(1) 自定義Activity的XML文件
app:zxing_preview_scaling_strategy="centerCrop"
:這個屬性指定了預覽圖像的縮放策略。在這里,設置為?centerCrop
,表示預覽圖像將按比例縮放并截取中間部分以適應。
app:zxing_use_texture_view="false"
:這個屬性指定是否使用?TextureView
?來顯示相機預覽。在這里,設置為?false
,表示不使用?TextureView
。不使用時為四周透明。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"tools:context=".MyCaptureActivity"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"><com.journeyapps.barcodescanner.DecoratedBarcodeViewandroid:id="@+id/decoratedBarcodeView"android:layout_height="150dp"android:layout_width="150dp"android:layout_centerInParent="true"app:zxing_preview_scaling_strategy="centerCrop"app:zxing_use_texture_view="false" /></RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
(2) 自定義Activity的Java文件
將CaptureActivity的Java代碼復制并修改部分。
public class MyCaptureActivity extends AppCompatActivity {private CaptureManager capture;private DecoratedBarcodeView barcodeScannerView;protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);barcodeScannerView = initializeContent();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.zxing_capture);//修改前return (DecoratedBarcodeView)findViewById(R.id.zxing_barcode_scanner);setContentView(R.layout.activity_my_capture);return (DecoratedBarcodeView)findViewById(R.id.decoratedBarcodeView);}@Overrideprotected void onResume() {super.onResume();capture.onResume();}@Overrideprotected void onPause() {super.onPause();capture.onPause();}@Overrideprotected void onDestroy() {super.onDestroy();capture.onDestroy();}@Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);capture.onSaveInstanceState(outState);}@SuppressLint("MissingSuperCall")@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {capture.onRequestPermissionsResult(requestCode, permissions, grantResults);}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {return barcodeScannerView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);}
}
(3) 使用setCaptureActivity()方法取代CaptureActivity
button.setOnClickListener(new View.OnClickListener() {public void onClick(View view) {IntentIntegrator intentIntegrator=new IntentIntegrator(MainActivity.this);//設置所需掃描的條碼格式----可有多種,且可同時有條碼和二維碼intentIntegrator.setDesiredBarcodeFormats(IntentIntegrator.EAN_13,IntentIntegrator.UPC_A);intentIntegrator.setBeepEnabled(true);//掃描成功是否有提示音intentIntegrator.setPrompt("掃描");//提示字符串intentIntegrator.setCameraId(0);//設置攝像頭,0為背攝,1為正攝intentIntegrator.setOrientationLocked(false);//是否方向鎖定intentIntegrator.setBarcodeImageEnabled(true);//是否保存掃描成功的圖片//使用自定義的Activity intentIntegrator.setCaptureActivity(MyCaptureActivity.class);intentIntegrator.initiateScan();//啟動掃描器}
});