六、Android拍照与扫码


前言

👨‍💻👨‍🌾📝记录学习成果,以便温故而知新

项目目录

在这里插入图片描述

1.拍照

功能包括调摄像头拍照展示照片与相册加载照片展示
在这里插入图片描述

(1)代码PhotoActivity、activity_photo

package cn.fy.photo.activity;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.FileProvider;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Objects;

import cn.fy.photo.databinding.ActivityPhotoBinding;

public class PhotoActivity extends AppCompatActivity {

    private ActivityPhotoBinding binding;

    private final int TAKE_PHOTO_REQUEST = 1;//拍照
    private final int TAKE_ALBUM_REQUEST = 2;//相册

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_photo);
        binding = ActivityPhotoBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setTitle("照片");

        binding.btnTakePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(intent, TAKE_PHOTO_REQUEST);
            }
        });

        binding.btnTakeAlbum.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent, TAKE_ALBUM_REQUEST);
            }
        });
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {

        switch (item.getItemId()) {
            case android.R.id.home:
                finish();
                break;
            default:
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        ImageView img_result = binding.imageView;
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case TAKE_PHOTO_REQUEST:
                    // 拍照返回结果
                    Bitmap photo = data.getParcelableExtra("data");
                    // 按需求处理photo
                    binding.imageView.setImageBitmap(photo);
                    binding.imageView.invalidate();
                    break;

                case TAKE_ALBUM_REQUEST:
                    Uri selectImage = data.getData();

                    String[] FilePathColumn = {MediaStore.Images.Media.DATA};
                    Cursor cursor = getContentResolver().query(selectImage,
                            FilePathColumn, null, null, null);
                    cursor.moveToFirst();
                    //从数据视图中获取已选择图片的路径
                    int columnIndex = cursor.getColumnIndex(FilePathColumn[0]);
                    String picPath = cursor.getString(columnIndex);
                    Log.e("picpath", picPath);
                    cursor.close();
                    Bitmap bitmap = BitmapFactory.decodeFile(picPath);
                    binding.imageView.setImageBitmap(bitmap);
                    binding.imageView.invalidate();
                    break;
                default:
                    break;
            }
        }
    }
}
<?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=".activity.PhotoActivity">

    <Button
        android:id="@+id/btn_take_photo"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="60dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="60dp"
        android:text="拍照"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_take_album"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="60dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="60dp"
        android:text="相册"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_take_photo" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_marginStart="60dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="60dp"
        android:background="#009688"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_take_album" />

</androidx.constraintlayout.widget.ConstraintLayout>

(2)权限

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />

2.扫码

功能包括摄像头扫码与从图片读取二维码
在这里插入图片描述

(1)添加依赖

使用的是华为的组件实现,所以需要在模块build.gradle文件中添加依赖“implementation ‘com.huawei.hms:scanplus:1.3.0.300’”,位置如下图,红框中即是
在这里插入图片描述

(2)代码ScanCodeActivity、activity_scan_code

package cn.fy.photo.activity;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;

import com.huawei.hms.hmsscankit.ScanUtil;
import com.huawei.hms.ml.scan.HmsScan;
import com.huawei.hms.ml.scan.HmsScanAnalyzerOptions;

import cn.fy.photo.databinding.ActivityPhotoBinding;
import cn.fy.photo.databinding.ActivityScanCodeBinding;

public class ScanCodeActivity extends AppCompatActivity {

    private ActivityScanCodeBinding binding;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_scan_code);
        binding = ActivityScanCodeBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setTitle("扫码");

        binding.btnScan.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                scanCode(view);
            }
        });
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {

        switch (item.getItemId()) {
            case android.R.id.home:
                finish();
                break;
            default:
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    public static final int CAMERA_REQ_CODE = 111;
    public static final int DECODE = 1;
    private static final int REQUEST_CODE_SCAN_ONE = 0X01;

    //在启动扫码Activity的地方添加动态权限申请
    public void scanCode(View view) {
        requestPermission(CAMERA_REQ_CODE, DECODE);
    }

    private void requestPermission(int requestCode, int mode) {
        ActivityCompat.requestPermissions(
            this,
            new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE},
            requestCode);
    }
    //扫码格式通过setHmsScanTypes指定为QR码,如果需要支持其他码可以自己指定
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (permissions == null || grantResults == null) {
            return;
        }
        if (grantResults.length < 2 || grantResults[0] != PackageManager.PERMISSION_GRANTED || grantResults[1] != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        if (requestCode == CAMERA_REQ_CODE) {
            ScanUtil.startScan(this, REQUEST_CODE_SCAN_ONE, new HmsScanAnalyzerOptions.Creator().setHmsScanTypes(HmsScan.QRCODE_SCAN_TYPE).create());
        }
    }

    //在activity里面里面获取码结果
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != RESULT_OK || data == null) {
            return;
        }
        if (requestCode == REQUEST_CODE_SCAN_ONE) {
            HmsScan obj = data.getParcelableExtra(ScanUtil.RESULT);
            if (obj != null) {
                binding.txtResult.setText(obj.originalValue);
                Log.i(getClass().getName(), obj.originalValue);
            }
        }
    }
}
<?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=".activity.ScanCodeActivity">

    <Button
        android:id="@+id/btn_scan"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="60dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="60dp"
        android:text="扫码"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/txt_result"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="60dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="60dp"
        android:hint="内容"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_scan" />
</androidx.constraintlayout.widget.ConstraintLayout>

(3)权限

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />

    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />

3.MainActivity

package cn.fy.photo;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import cn.fy.photo.activity.PhotoActivity;
import cn.fy.photo.activity.ScanCodeActivity;
import cn.fy.photo.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

    private ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        Button btnPhoto = binding.btnPhoto;
        btnPhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, PhotoActivity.class);
                //Intent intent = new Intent(MainActivity.this, PicActivity.class);
                startActivity(intent);
            }
        });

        Button btnScanCode = binding.btnScanCode;
        btnScanCode.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, ScanCodeActivity.class);
                startActivity(intent);
            }
        });
    }
}
<?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=".MainActivity">

    <Button
        android:id="@+id/btn_photo"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="60dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="60dp"
        android:text="照片"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_scan_code"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="60dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="60dp"
        android:text="扫码"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_photo" />
</androidx.constraintlayout.widget.ConstraintLayout>

4.AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />

    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCode">
        <activity android:name="com.huawei.hms.hmsscankit.ScanKitActivity" />
        <activity
            android:name=".activity.ScanCodeActivity"
            android:exported="false">
            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>
        <activity
            android:name=".activity.PhotoActivity"
            android:exported="false">
            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>
    </application>

</manifest>
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android操作系统中实现二维码生成与扫码功能是一个常见的需求,而为了方便实现该功能,可以选择使用二维码插件进行开发。Android平台上比较常用的二维码插件包括Zxing和QRCode等。 首先,在使用插件前需要在项目Gradle中添加插件依赖,就以Zxing为例,在项目build.gradle中添加依赖: ``` dependencies { implementation 'com.google.zxing:core:3.3.3' } ``` 生成二维码可以通过调用Zxing库中的MultiFormatWriter类来实现,示例代码: ``` MultiFormatWriter multiFormatWriter = new MultiFormatWriter(); BitMatrix bitMatrix = multiFormatWriter.encode(textToEncode, BarcodeFormat.QR_CODE, qrCodeWidth, qrCodeHeight); BarcodeEncoder barcodeEncoder = new BarcodeEncoder(); Bitmap bitmap = barcodeEncoder.createBitmap(bitMatrix); ``` 其中,textToEncode表示要生成二维码的文本信息,qrCodeWidth和qrCodeHeight表示二维码的宽度和高度,一般情况下可以设置为200x200。 扫码功能需要调用Zxing库中的IntentIntegrator类,在代码中使用: ``` private void startScan() { IntentIntegrator integrator = new IntentIntegrator(this); integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE_TYPES); integrator.setPrompt("Scan a QRcode"); integrator.setCameraId(0); integrator.setBeepEnabled(false); integrator.initiateScan(); } ``` 其中,setDesiredBarcodeFormats表示需要识别的码的类型,setPrompt表示扫码时的提示信息,setCameraId表示使用的相机,setBeepEnabled表示是否有声音提示。 当扫描完成后,需要在onActivityResult()方法中处理扫描结果,示例代码: ``` @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data); if(result != null) { if(result.getContents() == null) { Log.d(TAG, "Cancelled"); } else { Log.d(TAG, "Scanned: " + result.getContents()); } } else { super.onActivityResult(requestCode, resultCode, data); } } ``` 在上述代码中,通过解析扫描结果的IntentResult类来获取识别出的二维码信息,如果result.getContents()为null则表示扫码取消,否则就可以得到扫描结果了。 总之,对于Android平台上的二维码生成与扫码功能实现,通过使用Zxing或QRCode等插件可以方便快捷地实现该需求,即通过调用插件提供的API来生成或识别二维码即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值