myphoto.zip
在Android 11中,对用户隐私和数据访问进行了重大改进,这直接影响了应用程序如何处理照片选择和拍照功能。在之前的Android版本中,应用通常可以获得设备上所有照片的完全访问权限,但在Android 11中,这种做法已被限制。本教程将深入探讨如何在Android 11中正确实现选择照片和拍照功能,确保符合新的隐私政策。 我们需要了解Android 11中的存储权限变化。在Android 11之前,应用可以请求`READ_EXTERNAL_STORAGE`和`WRITE_EXTERNAL_STORAGE`权限来访问用户的整个外部存储。然而,Android 11引入了 scoped storage 概念,强制应用仅访问其私有目录以及通过特定API访问的公共目录。 1. 请求权限: 在Android 11中,对于读取和写入图片,你需要分别请求`Manifest.permission.READ_MEDIA_IMAGES`和`Manifest.permission.WRITE_MEDIA_IMAGES`权限。这些权限允许你的应用访问媒体库中的图像,但不包括整个外部存储。 2. 使用MediaStore API: 要让用户选择照片,不再可以直接遍历整个存储,而应使用`MediaStore`类。例如,你可以使用`ACTION_PICK`意图启动系统相册,让用户选择一张照片: ```java Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*"); startActivityForResult(intent, REQUEST_CODE_PICK_IMAGE); ``` 在`onActivityResult`方法中,你可以获取所选图片的URI: ```java @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_PICK_IMAGE && resultCode == RESULT_OK) { Uri selectedImageUri = data.getData(); // 处理URI并显示或保存图片 } } ``` 3. 拍照功能: 对于拍照功能,可以使用`Intent.ACTION_IMAGE_CAPTURE`启动相机应用。当你启动这个意图时,系统会保存拍摄的照片,并返回一个包含该照片URI的Intent。例如: ```java Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePictureIntent.resolveActivity(getPackageManager()) != null) { startActivityForResult(takePictureIntent, REQUEST_CODE_TAKE_IMAGE); } ``` 4. 处理返回的URI: `onActivityResult`中处理拍照返回的URI,可能需要将图片复制到应用的私有目录,因为相机应用可能会将图片保存在公共目录,这在Android 11中是受限的: ```java @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_TAKE_IMAGE && resultCode == RESULT_OK) { Uri photoUri = data.getData(); ContentResolver resolver = getContentResolver(); try (InputStream in = resolver.openInputStream(photoUri)) { File privateFile = createPrivateFile(); // 创建私有目录中的文件 try (OutputStream out = new FileOutputStream(privateFile)) { byte[] buffer = new byte[1024]; int read; while ((read = in.read(buffer)) != -1) { out.write(buffer, 0, read); } } // 使用私有文件进行后续操作 } catch (IOException e) { // 处理错误 } } } ``` 5. 图片裁剪: 如果需要让用户裁剪图片,可以使用`Intent.ACTION_EDIT`,或者使用第三方裁剪库如`androidx.core.content.FileProvider`。 6. 文件Provider: 在Android 11中,使用`ContentProvider`来共享文件,如相机应用返回的图片。你需要在AndroidManifest.xml中配置`<provider>`标签,为你的应用提供访问私有文件的权限。 适配Android 11的选择照片和拍照功能,关键在于理解新的存储权限和使用`MediaStore` API。同时,确保处理返回的URI时遵守scoped storage规则,将图片保存在应用的私有目录,并使用`ContentProvider`来安全地分享文件。通过遵循这些最佳实践,你的应用可以在尊重用户隐私的同时,提供流畅的图片选择和拍照体验。
- 1
- 2
- 3
- 4
- 5
- 云凡天河2021-12-17不好用,点哪都崩溃
- yang080701262022-12-07demo不能用啊
- 代码运行异常2022-04-14以后记得把外部的build.gradle带上,一运行起来还要重新弄个项目来套用
- Winmming2021-12-02选择照片路径:/storage/emulated/0/DCIM/Screenshots/Screenshot_2021-11-10-17-17-38-41_8b03ce35354e55ab8ccf3ac43b4b6b85.jpg Unable to decode stream: java.io.FileNotFoundException: /storage/emulated/0/DCIM/Screenshots/Screenshot_2021-11-10-17-17-38-41_8b03ce35354e55ab8ccf3ac43b4b6b85.jpg: open failed: EACCES (Permission denied) 不行的样子
- 粉丝: 13
- 资源: 8
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助