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();//启动扫描器}
});