QR 码扫描器 - 适用于 Android 的条码扫描器

在本教程中,我们将讨论和实施在谷歌移动视觉API中存在的条码API. 要了解使用视觉API的面部检测的实施,请参阅Vision API( / 社区 / 教程 / Android - 面部检测)。

适用于 Android 的条形码扫描器

QR Code Scanner for Android, Bar code scanner for android tutorial With the introduction of Google Vision API, implementing Barcodes in an application has got a lot easier for developers. Following are the major formats that the Vision API supports.

  • 1D条形码:EAN-13,EAN-8,UPC-A,UPC-E,代码-39,代码-93,代码-128,ITF,Codabar
  • 2D条形码:QR代码,数据矩阵,PDF-417,AZTEC

条形码可以扫描东西从URL,联系信息到地理位置,WIFI,司机许可证ID。QR代码是最流行的格式,通常在许多应用中看到。下面,我们将开发一个应用程序,从位图像扫描QR代码值,以及通过相机检测QR代码并执行相关操作。

用于 Android 项目结构的 QR 代码扫描器

QR Code Scanner for Android, Barcode scanner for anroid

配置 Android Studio for Barcode 图书馆

将以下内容添加到 build.gradle文件中。

1implementation 'com.google.android.gms:play-services-vision:11.8.0'

将下列内容添加到AndroidManifest.xml文件应用程序标签中,以便在应用程序中启用条形码检测。

1<meta-data
2            android:name="com.google.android.gms.vision.DEPENDENCIES"
3            android:value="barcode" />

QR代码扫描器从图像

activity_main.xml布局文件的代码在下面。

 1<?xml version="1.0" encoding="utf-8"?>
 2<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
 3    android:layout_width="match_parent"
 4    android:layout_height="match_parent"
 5    android:paddingBottom="@dimen/activity_vertical_margin"
 6    android:paddingLeft="@dimen/activity_horizontal_margin"
 7    android:paddingRight="@dimen/activity_horizontal_margin"
 8    android:paddingTop="@dimen/activity_vertical_margin">
 9
10    <Button
11        android:id="@+id/btnTakePicture"
12        android:layout_width="wrap_content"
13        android:layout_height="wrap_content"
14        android:layout_centerHorizontal="true"
15        android:layout_centerVertical="true"
16        android:text="@string/take_barcode_picture" />
17
18    <Button
19        android:id="@+id/btnScanBarcode"
20        android:layout_width="wrap_content"
21        android:layout_height="wrap_content"
22        android:layout_below="@+id/btnTakePicture"
23        android:layout_centerHorizontal="true"
24        android:layout_marginTop="@dimen/activity_horizontal_margin"
25        android:text="@string/scan_barcode" />
26</RelativeLayout>

MainActivity.java 的代码在下面。

 1package com.journaldev.barcodevisionapi;
 2
 3import android.content.Intent;
 4import android.support.v7.app.AppCompatActivity;
 5import android.os.Bundle;
 6import android.view.View;
 7import android.widget.Button;
 8
 9public class MainActivity extends AppCompatActivity implements View.OnClickListener {
10
11    Button btnTakePicture, btnScanBarcode;
12
13    @Override
14    protected void onCreate(Bundle savedInstanceState) {
15        super.onCreate(savedInstanceState);
16        setContentView(R.layout.activity_main);
17        initViews();
18    }
19
20    private void initViews() {
21        btnTakePicture = findViewById(R.id.btnTakePicture);
22        btnScanBarcode = findViewById(R.id.btnScanBarcode);
23        btnTakePicture.setOnClickListener(this);
24        btnScanBarcode.setOnClickListener(this);
25    }
26
27    @Override
28    public void onClick(View v) {
29
30        switch (v.getId()) {
31            case R.id.btnTakePicture:
32                startActivity(new Intent(MainActivity.this, PictureBarcodeActivity.class));
33                break;
34            case R.id.btnScanBarcode:
35                startActivity(new Intent(MainActivity.this, ScannedBarcodeActivity.class));
36                break;
37        }
38
39    }
40}

MainActivity.java包含两个按钮. 第一个启动了一个活动,该活动在摄像机捕获的比特图像中扫描QR代码,并返回QR代码中的数据(如果有)。

1<uses-feature
2        android:name="android.hardware.camera"
3        android:required="true" />
4
5    <uses-permission android:name="android.permission.CAMERA" />
6    <uses-feature android:name="android.hardware.camera.autofocus" />
7
8    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
9    <uses-permission android:name="android.permission.INTERNET" />

要共享和访问由其他应用程序创建的文件,我们需要在AndroidManifest.xml文件中添加下面的供应商标签。

1<provider
2            android:name="android.support.v4.content.FileProvider"
3            android:authorities="${applicationId}.provider"
4            android:exported="false"
5            android:grantUriPermissions="true">
6            <meta-data
7                android:name="android.support.FILE_PROVIDER_PATHS"
8                android:resource="@xml/provider_paths" />
9        </provider>

这需要从我们的QR代码扫描器中获取摄像头捕获的图像,以便为Android应用程序。让我们从第一个,即PictureBarcodeActivity.java开始。

 1<?xml version="1.0" encoding="utf-8"?>
 2<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
 3    xmlns:tools="https://schemas.android.com/tools"
 4    android:layout_width="match_parent"
 5    android:layout_height="match_parent"
 6    android:paddingBottom="@dimen/activity_vertical_margin"
 7    android:paddingLeft="@dimen/activity_horizontal_margin"
 8    android:paddingRight="@dimen/activity_horizontal_margin"
 9    android:paddingTop="@dimen/activity_vertical_margin">
10
11    <ImageView
12        android:id="@+id/imageView"
13        android:layout_width="150dp"
14        android:layout_height="150dp"
15        android:layout_centerHorizontal="true"
16        android:src="@mipmap/journaldev_logo" />
17
18    <TextView
19        android:id="@+id/txtResultsHeader"
20        android:layout_width="wrap_content"
21        android:layout_height="wrap_content"
22        android:layout_below="@+id/imageView"
23        android:layout_centerHorizontal="true"
24        android:text="Results"
25        android:textSize="18sp"
26        android:textStyle="bold" />
27
28    <TextView
29        android:id="@+id/txtResultsBody"
30        android:layout_width="match_parent"
31        android:layout_height="wrap_content"
32        android:layout_below="@+id/txtResultsHeader"
33        android:layout_centerHorizontal="true"
34        android:layout_marginTop="@dimen/activity_horizontal_margin"
35        android:gravity="center" />
36
37    <Button
38        android:id="@+id/btnOpenCamera"
39        android:layout_width="wrap_content"
40        android:layout_height="wrap_content"
41        android:layout_alignParentBottom="true"
42        android:layout_centerHorizontal="true"
43        android:layout_marginBottom="@dimen/activity_horizontal_margin"
44        android:layout_marginTop="@dimen/activity_horizontal_margin"
45        android:text="@string/open_camera" />
46</RelativeLayout>

下面是PictureCodeActivity.java类的代码。

  1package com.journaldev.barcodevisionapi;
  2
  3import android.Manifest;
  4import android.content.Context;
  5import android.content.Intent;
  6import android.content.pm.PackageManager;
  7import android.graphics.Bitmap;
  8import android.graphics.BitmapFactory;
  9import android.net.Uri;
 10import android.os.Bundle;
 11import android.os.Environment;
 12import android.provider.MediaStore;
 13import android.support.annotation.NonNull;
 14import android.support.v4.app.ActivityCompat;
 15import android.support.v4.content.FileProvider;
 16import android.support.v7.app.AppCompatActivity;
 17import android.util.Log;
 18import android.util.SparseArray;
 19import android.view.View;
 20import android.widget.Button;
 21import android.widget.TextView;
 22import android.widget.Toast;
 23
 24import com.google.android.gms.vision.Frame;
 25import com.google.android.gms.vision.barcode.Barcode;
 26import com.google.android.gms.vision.barcode.BarcodeDetector;
 27
 28import java.io.File;
 29import java.io.FileNotFoundException;
 30
 31public class PictureBarcodeActivity extends AppCompatActivity implements View.OnClickListener {
 32
 33    Button btnOpenCamera;
 34    TextView txtResultBody;
 35
 36    private BarcodeDetector detector;
 37    private Uri imageUri;
 38    private static final int REQUEST_CAMERA_PERMISSION = 200;
 39    private static final int CAMERA_REQUEST = 101;
 40    private static final String TAG = "API123";
 41    private static final String SAVED_INSTANCE_URI = "uri";
 42    private static final String SAVED_INSTANCE_RESULT = "result";
 43
 44    @Override
 45    protected void onCreate(Bundle savedInstanceState) {
 46        super.onCreate(savedInstanceState);
 47        setContentView(R.layout.activity_barcode_picture);
 48
 49        initViews();
 50
 51        if (savedInstanceState != null) {
 52            if (imageUri != null) {
 53                imageUri = Uri.parse(savedInstanceState.getString(SAVED_INSTANCE_URI));
 54                txtResultBody.setText(savedInstanceState.getString(SAVED_INSTANCE_RESULT));
 55            }
 56        }
 57
 58        detector = new BarcodeDetector.Builder(getApplicationContext())
 59                .setBarcodeFormats(Barcode.DATA_MATRIX | Barcode.QR_CODE)
 60                .build();
 61
 62        if (!detector.isOperational()) {
 63            txtResultBody.setText("Detector initialisation failed");
 64            return;
 65        }
 66    }
 67
 68    private void initViews() {
 69        txtResultBody = findViewById(R.id.txtResultsBody);
 70        btnOpenCamera = findViewById(R.id.btnTakePicture);
 71        txtResultBody = findViewById(R.id.txtResultsBody);
 72        btnOpenCamera.setOnClickListener(this);
 73    }
 74
 75    @Override
 76    public void onClick(View v) {
 77
 78        switch (v.getId()) {
 79            case R.id.btnTakePicture:
 80                ActivityCompat.requestPermissions(PictureBarcodeActivity.this, new
 81                        String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
 82                break;
 83        }
 84
 85    }
 86
 87    @Override
 88    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
 89        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
 90        switch (requestCode) {
 91            case REQUEST_CAMERA_PERMISSION:
 92                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
 93                    takeBarcodePicture();
 94                } else {
 95                    Toast.makeText(getApplicationContext(), "Permission Denied!", Toast.LENGTH_SHORT).show();
 96                }
 97        }
 98    }
 99
100    @Override
101    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
102        if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) {
103            launchMediaScanIntent();
104            try {
105
106                Bitmap bitmap = decodeBitmapUri(this, imageUri);
107                if (detector.isOperational() && bitmap != null) {
108                    Frame frame = new Frame.Builder().setBitmap(bitmap).build();
109                    SparseArray<Barcode> barcodes = detector.detect(frame);
110                    for (int index = 0; index < barcodes.size(); index++) {
111                        Barcode code = barcodes.valueAt(index);
112                        txtResultBody.setText(txtResultBody.getText() + "\n" + code.displayValue + "\n");
113
114                        int type = barcodes.valueAt(index).valueFormat;
115                        switch (type) {
116                            case Barcode.CONTACT_INFO:
117                                Log.i(TAG, code.contactInfo.title);
118                                break;
119                            case Barcode.EMAIL:
120                                Log.i(TAG, code.displayValue);
121                                break;
122                            case Barcode.ISBN:
123                                Log.i(TAG, code.rawValue);
124                                break;
125                            case Barcode.PHONE:
126                                Log.i(TAG, code.phone.number);
127                                break;
128                            case Barcode.PRODUCT:
129                                Log.i(TAG, code.rawValue);
130                                break;
131                            case Barcode.SMS:
132                                Log.i(TAG, code.sms.message);
133                                break;
134                            case Barcode.TEXT:
135                                Log.i(TAG, code.displayValue);
136                                break;
137                            case Barcode.URL:
138                                Log.i(TAG, "url: " + code.displayValue);
139                                break;
140                            case Barcode.WIFI:
141                                Log.i(TAG, code.wifi.ssid);
142                                break;
143                            case Barcode.GEO:
144                                Log.i(TAG, code.geoPoint.lat + ":" + code.geoPoint.lng);
145                                break;
146                            case Barcode.CALENDAR_EVENT:
147                                Log.i(TAG, code.calendarEvent.description);
148                                break;
149                            case Barcode.DRIVER_LICENSE:
150                                Log.i(TAG, code.driverLicense.licenseNumber);
151                                break;
152                            default:
153                                Log.i(TAG, code.rawValue);
154                                break;
155                        }
156                    }
157                    if (barcodes.size() == 0) {
158                        txtResultBody.setText("No barcode could be detected. Please try again.");
159                    }
160                } else {
161                    txtResultBody.setText("Detector initialisation failed");
162                }
163            } catch (Exception e) {
164                Toast.makeText(getApplicationContext(), "Failed to load Image", Toast.LENGTH_SHORT)
165                        .show();
166                Log.e(TAG, e.toString());
167            }
168        }
169    }
170
171    private void takeBarcodePicture() {
172        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
173        File photo = new File(Environment.getExternalStorageDirectory(), "pic.jpg");
174        imageUri = FileProvider.getUriForFile(PictureBarcodeActivity.this,
175                BuildConfig.APPLICATION_ID + ".provider", photo);
176        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
177        startActivityForResult(intent, CAMERA_REQUEST);
178    }
179
180    @Override
181    protected void onSaveInstanceState(Bundle outState) {
182        if (imageUri != null) {
183            outState.putString(SAVED_INSTANCE_URI, imageUri.toString());
184            outState.putString(SAVED_INSTANCE_RESULT, txtResultBody.getText().toString());
185        }
186        super.onSaveInstanceState(outState);
187    }
188
189    private void launchMediaScanIntent() {
190        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
191        mediaScanIntent.setData(imageUri);
192        this.sendBroadcast(mediaScanIntent);
193    }
194
195    private Bitmap decodeBitmapUri(Context ctx, Uri uri) throws FileNotFoundException {
196        int targetW = 600;
197        int targetH = 600;
198        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
199        bmOptions.inJustDecodeBounds = true;
200        BitmapFactory.decodeStream(ctx.getContentResolver().openInputStream(uri), null, bmOptions);
201        int photoW = bmOptions.outWidth;
202        int photoH = bmOptions.outHeight;
203
204        int scaleFactor = Math.min(photoW / targetW, photoH / targetH);
205        bmOptions.inJustDecodeBounds = false;
206        bmOptions.inSampleSize = scaleFactor;
207
208        return BitmapFactory.decodeStream(ctx.getContentResolver()
209                .openInputStream(uri), null, bmOptions);
210    }
211}

下面是从上面的代码中得出的几点推断。

  • 联合国 以下代码创建了条码检测器 () ) QQ 探测器 = 新的条码检测器. Builder(getApplicationContext () () ). set Barcode Formats (Barcode.DATA_MATRIX QQ barcode.QR_CODE .built (); . . * 需要扫描的格式类型设定在set Barcode Formats ()'. *take BarcodePicture ()'函数发射相机的地方。 要取回图像, 我们使用发射介质ScanIntent () 来调用图像 URI 搜索图像 。 (_) ) * A'Frame.Builder"用于创建比图图像的框架. 在框架上方,条形码探测器扫描可能的QR码. 以上代码中的以下一行创建出 Bitmap. QQ 框架 = 新框架. Builder (. setBitmap (bitmap).building (); QQ
  • 我们已经创建了 SparseArray , 它将通过在 Barcode 检测器上引用 detect ()' 方法, 包含图像中所有可能的 QR 代码 。 QQ SparseArray < Barcode > 条码 = detect (frame); (_) (中文(简体) ). 要获得 QR 代码的格式, valueFormat' 字段在条码实例之上被调用, 如下文所示 。 (_ _) 条码. valueAt (index). valueFormat
  • 要获取显示的值和原始值,请引用以下内容: __ 条码. valueAt(index.displayValue 条码. valueAt(index.rawValue _ )* 返回的相关值在文本视图中显示。 对于一个位图中的条码,其值被附加到当前文本View. (_) (英语)

ScannedBarcodeActivity.java类通过相机扫描条形码,我们从 这里生成了两个自定义QR代码。

 1<?xml version="1.0" encoding="utf-8"?>
 2<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
 3    android:layout_width="match_parent"
 4    android:layout_height="match_parent"
 5    android:padding="@dimen/activity_horizontal_margin">
 6
 7    <SurfaceView
 8        android:id="@+id/surfaceView"
 9        android:layout_width="match_parent"
10        android:layout_height="match_parent"
11        android:layout_above="@+id/btnAction"
12        android:layout_alignParentLeft="true"
13        android:layout_alignParentStart="true"
14        android:layout_centerVertical="true" />
15
16    <TextView
17        android:id="@+id/txtBarcodeValue"
18        android:layout_width="wrap_content"
19        android:layout_height="wrap_content"
20        android:layout_alignParentTop="true"
21        android:layout_marginLeft="@dimen/activity_horizontal_margin"
22        android:layout_marginStart="@dimen/activity_horizontal_margin"
23        android:text="No Barcode Detected"
24        android:textColor="@android:color/white"
25        android:textSize="20sp" />
26
27    <Button
28        android:id="@+id/btnAction"
29        android:layout_width="match_parent"
30        android:layout_height="wrap_content"
31        android:layout_alignParentBottom="true"
32        android:text="ADD CONTENT IN THE MAIL" />
33
34</RelativeLayout>

来自摄像头的 Android 条形码扫描器

ScannedBarcodeActivity.java的代码在下面。

  1package com.journaldev.barcodevisionapi;
  2
  3import android.Manifest;
  4import android.content.Intent;
  5import android.content.pm.PackageManager;
  6import android.net.Uri;
  7import android.os.Bundle;
  8import android.support.v4.app.ActivityCompat;
  9import android.support.v7.app.AppCompatActivity;
 10import android.util.SparseArray;
 11import android.view.SurfaceHolder;
 12import android.view.SurfaceView;
 13import android.view.View;
 14import android.widget.Button;
 15import android.widget.TextView;
 16import android.widget.Toast;
 17
 18import com.google.android.gms.vision.CameraSource;
 19import com.google.android.gms.vision.Detector;
 20import com.google.android.gms.vision.barcode.Barcode;
 21import com.google.android.gms.vision.barcode.BarcodeDetector;
 22
 23import java.io.IOException;
 24
 25public class ScannedBarcodeActivity extends AppCompatActivity {
 26
 27    SurfaceView surfaceView;
 28    TextView txtBarcodeValue;
 29    private BarcodeDetector barcodeDetector;
 30    private CameraSource cameraSource;
 31    private static final int REQUEST_CAMERA_PERMISSION = 201;
 32    Button btnAction;
 33    String intentData = "";
 34    boolean isEmail = false;
 35
 36    @Override
 37    protected void onCreate(Bundle savedInstanceState) {
 38        super.onCreate(savedInstanceState);
 39        setContentView(R.layout.activity_scan_barcode);
 40
 41        initViews();
 42    }
 43
 44    private void initViews() {
 45        txtBarcodeValue = findViewById(R.id.txtBarcodeValue);
 46        surfaceView = findViewById(R.id.surfaceView);
 47        btnAction = findViewById(R.id.btnAction);
 48
 49        btnAction.setOnClickListener(new View.OnClickListener() {
 50            @Override
 51            public void onClick(View v) {
 52
 53                if (intentData.length() > 0) {
 54                    if (isEmail)
 55                        startActivity(new Intent(ScannedBarcodeActivity.this, EmailActivity.class).putExtra("email_address", intentData));
 56                    else {
 57                        startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(intentData)));
 58                    }
 59                }
 60
 61            }
 62        });
 63    }
 64
 65    private void initialiseDetectorsAndSources() {
 66
 67        Toast.makeText(getApplicationContext(), "Barcode scanner started", Toast.LENGTH_SHORT).show();
 68
 69        barcodeDetector = new BarcodeDetector.Builder(this)
 70                .setBarcodeFormats(Barcode.ALL_FORMATS)
 71                .build();
 72
 73        cameraSource = new CameraSource.Builder(this, barcodeDetector)
 74                .setRequestedPreviewSize(1920, 1080)
 75                .setAutoFocusEnabled(true) //you should add this feature
 76                .build();
 77
 78        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
 79            @Override
 80            public void surfaceCreated(SurfaceHolder holder) {
 81                try {
 82                    if (ActivityCompat.checkSelfPermission(ScannedBarcodeActivity.this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
 83                        cameraSource.start(surfaceView.getHolder());
 84                    } else {
 85                        ActivityCompat.requestPermissions(ScannedBarcodeActivity.this, new
 86                                String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
 87                    }
 88
 89                } catch (IOException e) {
 90                    e.printStackTrace();
 91                }
 92
 93            }
 94
 95            @Override
 96            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
 97            }
 98
 99            @Override
100            public void surfaceDestroyed(SurfaceHolder holder) {
101                cameraSource.stop();
102            }
103        });
104
105        barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
106            @Override
107            public void release() {
108                Toast.makeText(getApplicationContext(), "To prevent memory leaks barcode scanner has been stopped", Toast.LENGTH_SHORT).show();
109            }
110
111            @Override
112            public void receiveDetections(Detector.Detections<Barcode> detections) {
113                final SparseArray<Barcode> barcodes = detections.getDetectedItems();
114                if (barcodes.size() != 0) {
115
116                    txtBarcodeValue.post(new Runnable() {
117
118                        @Override
119                        public void run() {
120
121                            if (barcodes.valueAt(0).email != null) {
122                                txtBarcodeValue.removeCallbacks(null);
123                                intentData = barcodes.valueAt(0).email.address;
124                                txtBarcodeValue.setText(intentData);
125                                isEmail = true;
126                                btnAction.setText("ADD CONTENT TO THE MAIL");
127                            } else {
128                                isEmail = false;
129                                btnAction.setText("LAUNCH URL");
130                                intentData = barcodes.valueAt(0).displayValue;
131                                txtBarcodeValue.setText(intentData);
132
133                            }
134                        }
135                    });
136
137                }
138            }
139        });
140    }
141
142    @Override
143    protected void onPause() {
144        super.onPause();
145        cameraSource.release();
146    }
147
148    @Override
149    protected void onResume() {
150        super.onResume();
151        initialiseDetectorsAndSources();
152    }
153}

下面是从上面的代码中得出的几点推断。

  • SurfaceView'在使图形用户界面快速化时能够显示相机预览图像。 界面 " SurfaceHolder " 。 Callback"用于接收表面所发生变化的信息(在此情况下是相机预览). " 沙发手" 回调执行三种方法:(_) ) - ** 变脸** : 当表面的大小或格式发生变化时,这种方法就称为.
  • ** 硬面所创造** : 当首先产生地表时,这个方法叫做.
  • ** surface被破坏**: 当表面被破坏时就叫这个 (_) ( )* " Camera Source " 与一个探测器一起管理相机。 这里表面 视图是基础探测器. CameraSource.start ()' 打开相机,开始向 SurfaceView 发送预览框。 相机源创建方式如下: 相机源 (- ) 相机源 (- ) 相机源 (- ) 相机源 (- ) 相机源 (- ) 相机源 (- ) 相机源源 (-) 相机源 (- ) 相机源 (- ) 相机源源(- ) 相机源(- ) * 我们在条形码探测器上指定了一个使用setProcessor ()`的处理器。 界面包含对接收从相机预览中接收QR代码并添加到SparseArray的方法的回调( --). ( )* QR 代码的值在 TextView 中使用了可操作的 Runnable 显示, 因为行码在背景线索中被检测出 。
  • 在这个例子中,我们用发电机创建了两个条码. 一个包含URL。 第二份载有电子邮件地址。 点击按钮后,根据检测到的QR代码值,我们要么启动URL,要么向从QR代码检测到的相关电子邮件地址发送电子邮件. ( (英语)

The output of the PictureBarcodeActivity.java is given below. bar code scanner for android app The output of the ScannedBarcodeActivity.java activity in action is given below. QR Code scanner for android That's all for QR code scanner project for android using Mobile Vision API. We've added the sample QR Codes to the source code. You can download the final Android QR Code Scanner/Barcode Scanner Project from the link below and play around with different QR Codes.

下载 QR 代码, 条形码扫描仪示例项目

Published At
Categories with 技术
Tagged with
comments powered by Disqus