拍照及从相册选择照片

博主首次写博客,记录拍照及从相册选择功能。给出了关键源码,如显示图片 Base64 字符串的方法,还提及了 style.XML 和布局文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一次写博客,只为记录下拍照及从相册选择功能。

关键源码如下:

  点击打开拍照对话框,dialog从底部弹出
  /**
 * 显示拍照的对话框
 */
public void showCameraDialog() {
    Dialog dialog = new Dialog(this, R.style.dialogStyle);
    @SuppressLint("InflateParams") View view = LayoutInflater.from(this).inflate(R.layout.dialog_camera_main, null);
    TextView tvTakePhoto = view.findViewById(R.id.tv_take_photo);
    TextView tvPicture = view.findViewById(R.id.tv_picture);
    TextView tvCancel = view.findViewById(R.id.tv_cancel);
    dialog.setContentView(view);
    dialog.show();
    WindowManager.LayoutParams params = Objects.requireNonNull(dialog.getWindow()).getAttributes();
    params.width = this.getWindowManager().getDefaultDisplay().getWidth();
    dialog.getWindow().setAttributes(params);
    dialog.getWindow().setGravity(Gravity.BOTTOM);
    tvCancel.setOnClickListener(view1 -> dialog.dismiss());
    tvTakePhoto.setOnClickListener(view13 -> {
        onTakePhoto();
        dialog.dismiss();
    });
    tvPicture.setOnClickListener(view12 -> {
        onPicture();
        dialog.dismiss();
    });
}
 /**
 * 拍照
 */
public void onTakePhoto() {
	//先请求权限代码
    applyWritePermission();
}

/**
 * 相册选择
 */
public void onPicture() {
    Intent albumIntent = new Intent(Intent.ACTION_PICK);
    albumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
    startActivityForResult(albumIntent, ALBUM_RESULT_CODE);
}
/**
 * 请求权限并调用相机
 */
public void applyWritePermission() {
    String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA};

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        int check = ContextCompat.checkSelfPermission(this, permissions[0]);
        // 权限是否已经 授权 GRANTED---授权  DINIED---拒绝
        if (check == PackageManager.PERMISSION_GRANTED) {
            //调用相机
            useCamera();
        } else {
            requestPermissions(permissions, 1);
        }
    } else {
        useCamera();
    }
}
public static boolean hasSdcard() {
    return Environment.getExternalStorageState().equals(
            Environment.MEDIA_MOUNTED);
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        useCamera();
    } else {
        // 没有获取 到权限
        showToast("拍照需要存储权限");
    }
}

/**
 * 使用相机
 */
private void useCamera() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (hasSdcard()) {
        Uri imageUri;
        File file = new File(Environment.getExternalStorageDirectory(),
                System.currentTimeMillis() + ".jpg");
        picturePath = file.getPath();
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            // 从文件中创建uri
            imageUri = Uri.fromFile(file);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        } else {
            //改变Uri
            imageUri = FileProvider.getUriForFile(this, this.getPackageName() + ".FileProvider", file);
            //添加权限
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        }
        // 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_CAREMA
        startActivityForResult(intent, REQUEST_CAMERA);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == Activity.RESULT_OK) {
        if (requestCode == ALBUM_RESULT_CODE) {
            picturePath = GetPathFromUri.getPath(MainActivity.this, data.getData());
        }
        presenter.compressByPath(picturePath);
        lyPhoto.setVisibility(View.GONE);
        ryDisplay.setVisibility(View.VISIBLE);
    }
}
/**
 * @param picturePath 图片路径
 *           压缩图片
 */
public void compressByPath(String picturePath) {
    iMainView.showProgressBar(mContext.getResources().getString(R.string.loadding_picture));
    Observable.just(picturePath)
            .subscribeOn(Schedulers.io())
            .map(s -> Base64Utils.bitmapToBase64(BitmapFactory.decodeFile(picturePath), 70))
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(s -> {
                iMainView.showPictureBase64Str(s);
                iMainView.hideProgressBar();
            });
}

public void showPictureBase64Str(String pictureStr) {
Glide.with(this).load(picturePath).into(imgDisplayPic);
picBase64Str = pictureStr;
}

style.XML 如下:

佈局文件如下:

<?xml version="1.0" encoding="utf-8"?>

<View
    android:layout_width="match_parent"
    android:layout_height="0.5dp"
    android:background="@color/divider_bg" />

<TextView
    android:id="@+id/tv_take_photo"
    android:layout_width="match_parent"
    android:layout_height="48dp"
    android:gravity="center"
    android:text="拍照"
    android:textColor="@color/text_key"
    android:textSize="@dimen/size6" />

<View
    android:layout_width="match_parent"
    android:layout_height="0.5dp"
    android:background="@color/divider_bg" />

<TextView
    android:id="@+id/tv_picture"
    android:layout_width="match_parent"
    android:layout_height="48dp"
    android:gravity="center"
    android:text="从手机相册选择"
    android:textColor="@color/text_key"
    android:textSize="@dimen/size6" />

<View
    android:layout_width="match_parent"
    android:layout_height="6dp"
    android:background="@color/divider_bg" />

<TextView
    android:id="@+id/tv_cancel"
    android:layout_width="match_parent"
    android:layout_height="48dp"
    android:gravity="center"
    android:text="取消"
    android:textColor="@color/text_key"
    android:textSize="@dimen/size6" />

<View
    android:layout_width="match_parent"
    android:layout_height="0.5dp"
    android:background="@color/divider_bg" />
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值