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>