Anroid 多媒体 - 调用相机和相册

Android 多媒体学习笔记 —— 调用相机和相册

Anroid 多媒体 —— 调用相机和相册

调用相机拍照

调用相机其实在 File Provider 篇章中有所使用了,这里将对前面的例子进行简化。当然,File Provider 中该有的步骤还是要有的,主要是 ActivityResultLauncher 的变化。下面使用官方提供的 ActivityResultContracts.TakePicture 对象作为参数进行注册,在调用 launch() 方法时只需要传入 URI 即可,不需要自己构建 Intent 对象了。不过观察源码就会发现实现逻辑其实与 File Provider 中的是一样的,这里只是官方做好了封装。

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button takePhoto;
    private ImageView picture;
    private Uri imageUri;
    private File outputImage;
    // 注意泛型类型是 Uri 不是 Intent,因为调用 launch() 方法时传入的是由 File Provider 生成的 URI
    private ActivityResultLauncher<Uri> launcher = registerForActivityResult(new ActivityResultContracts.TakePicture(), new ActivityResultCallback<Boolean>() {
        @Override
        public void onActivityResult(Boolean result) {
            // 返回值代表图片是否成功保存在指定的 URI 中
            // TODO
        }
    });

    // ...

    @Override
    public void onClick(View v) {
        outputImage = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "output_image.jpg");

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            imageUri = FileProvider.getUriForFile(this, "com.amie.cameraalbum.FileProvider", outputImage);
        } else {
            imageUri = Uri.fromFile(outputImage);
        }
        launcher.launch(imageUri);
    }
}

这还不是最简单的使用方式,因为需要传入一个 URI,也就是说依旧需要使用 FileProvider。接下来使用 ActivityResultContracts.TakePicturePreview 对象作为参数进行注册则不需要 FileProvider,返回值是照片的 Bitmap 对象。不过因为没有指定保存路径,照片不会保存到本地,如要保存需另做处理。

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button takePhoto;
    private ImageView picture;
    private Uri imageUri;
    private File outputImage;
    // 泛型为 Void,调用 launch() 方法传入 null 即可
    private ActivityResultLauncher<Void> launcher = registerForActivityResult(new ActivityResultContracts.TakePicturePreview(), new ActivityResultCallback<Bitmap>() {
        @Override
        public void onActivityResult(Bitmap result) {
            // 可获取到拍摄照片的 Bitmap 对象
            // 如需保存到本地可自行处理
        }
    });

    // ...

    @Override
    public void onClick(View v) {
        launcher.launch(null);
    }
}

调用相册选择图片

和使用 FileProvider 调用相机一样,先采用最基础的方式调用相册,即自己构建 Intent。

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button pickPicture;
    private ImageView picture;
    private Uri imageUri;
    private ActivityResultLauncher<Intent> pickLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
        @Override
        public void onActivityResult(ActivityResult result) {
            if (result.getResultCode() == RESULT_OK) {
                Intent intent = result.getData();
                if (intent != null) {
                    Uri uri = intent.getData();
                    if (uri != null) {
                        // TODO
                    }
                }
            }
        }
    });

    // ...

    @Override
    public void onClick(View v) {
        // 这里的 action 可以使用 ACTION_GET_CONTENT 或 ACTION_OPEN_DOCUMENT
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        // 建议指定 Category
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        // 设置图片类型,全类型使用 setType("*/*")
        intent.setType("image/*");
        pickLauncher.launch(intent);
    }
}

ActivityResutlContract 官方实现好的默认合约中,GetContent 类和 GetMultipleContents 类可以用来获取手机中的资源,因此也可以使用这两个合约来获取手机中的图片,后者可用于图片多选。

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button pickPicture;
    private ImageView picture;
    // ActivityResultContracts.GetContent 只能单选
    private ActivityResultLauncher<String> launcher = registerForActivityResult(new ActivityResultContracts.GetContent(), new ActivityResultCallback<Uri>() {
        @Override
        public void onActivityResult(Uri result) {
            if (result != null) {
                picture.setImageURI(result);
            }
        }
    });

    // ActivityResultContracts.GetMultipleContents 可以多选
    private ActivityResultLauncher<String> multiLauncher = registerForActivityResult(new ActivityResultContracts.GetMultipleContents(), new ActivityResultCallback<List<Uri>>() {
        @Override
        public void onActivityResult(List<Uri> result) {
            if (!result.isEmpty()) {
                picture.setImageURI(result.get(0));
            }
        }
    });

    // ...

    @Override
    public void onClick(View v) {
        // launcher.launch("image/*"); // 单选
        // multiLauncher.launch("image/*"); // 多选
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿咩AmieVastness

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值