Android 从相册选择照片,或者拍照 |
您所在的位置:网站首页 › 从相册里面选择照片 › Android 从相册选择照片,或者拍照 |
之前实现了 Android 拍照获取图片,现在需要再加上从相册选择照片。 交互其实有多种交互方式: 界面上直接放两个按钮:一个是拍照,一个是从相册选取。简单直接。 点击拍照按钮,弹出一个选择框,提供两个选项,一拍照,二从相册选择对于界面空间富裕的场景,我觉得第一种方式就非常方便了。当然,我也懒得搞那么复杂。。。 可是微信里面那个相机为啥那么方便呢?是否是自定义实现的相机,而不是调用的默认的相机应用。 kotlin registerForActivityResult 实现,目前推荐registerForActivityResult 并没有 startActivityForResult 的 requestCode 来判定从哪个 activity 返回的, 但是可以通过定义多个 launch 来区分,以使用不同的回调处理函数。 目前只是猜测,需要看看官方是否有使用说明,以及 github 上的开源代码来做参考。 从 https://stackoverflow.com/questions/62387789/capture-image-from-camera-gallery-and-display-in-activity-fragment-using-kotlin 看,确实跟我猜测的一样。 startActivityForResult 配合 onActivityResult,需要 requestCode 是因为没法指定回调函数, 只能使用固定的 onActivityResult 来处理,所以必须配一个 requestCode。 而 registerForActivityResult 则可以自由地生成 N 个对应的处理回调,那么确实就不需要 requestCode 了。 最终实现: val pickLauncher = registerForActivityResult(ActivityResultContracts.GetContent()){ uri: Uri? -> uri?.let { it -> Log.d("tag", it.toString()) val bitmap = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { ImageDecoder.decodeBitmap(ImageDecoder.createSource(this.contentResolver, it)) } else { MediaStore.Images.Media.getBitmap(this.contentResolver, it) } handleCameraImage(bitmap) } } val btnPickPicture = findViewById(R.id.btnPickPicture) btnPickPicture.setOnClickListener { pickLauncher.launch("image/*") }registerForActivityResult 的实现非常贴心,之前是用通用的方法ActivityResultContracts.StartActivityForResult(),这里用的是更简化的 ActivityResultContracts.GetContent(),可以直接获取到 Uri。 旧的代码实现 startActivityForResult, 已废弃可以参考这里的做法: https://stackoverflow.com/questions/10165302/dialog-to-pick-image-from-gallery-or-from-camera Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(takePicture, 0);//zero can be replaced with any action code (called requestCode) Intent pickPhoto = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(pickPhoto , 1);//one can be replaced with any action code protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) { super.onActivityResult(requestCode, resultCode, imageReturnedIntent); switch(requestCode) { case 0: if(resultCode == RESULT_OK){ Uri selectedImage = imageReturnedIntent.getData(); imageview.setImageURI(selectedImage); } break; case 1: if(resultCode == RESULT_OK){ Uri selectedImage = imageReturnedIntent.getData(); imageview.setImageURI(selectedImage); } break; } } registerForActivityResult 的介绍Android 官方虽然有介绍,但是太简陋了,没有更多的细节和使用教程。 https://developer.android.com/training/basics/intents/result 各种 Intent 的区别Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI) 弹出选择框,相册,或是文件管理。而文件管理中,没有文件。 ACTION_GET_CONTENT 与 ACTION_OPEN_DOCUMENT 的区别https://stackoverflow.com/questions/36182134/what-is-the-real-difference-between-action-get-content-and-action-open-document 《第一行代码》里是用的 ACTION_OPEN_DOCUMENT 配合 intent type image 来实现的相册图片选择。 ACTION_OPEN_DOCUMENT is not intended to be a replacement for ACTION_GET_CONTENT. The one you should use depends on the needs of your app: Use ACTION_GET_CONTENT if you want your app to simply read/import data. With this approach, the app imports a copy of the data, such as an image file. Use ACTION_OPEN_DOCUMENT if you want your app to have long term, persistent access to documents owned by a document provider. An example would be a photo-editing app that lets users edit images stored in a document provider.暂时没有必要纠结,可以参考网上怎么实现的选取图片并上传,来判定该使用哪个 action。 uri 的格式 content://com.android.providers.media.documents/document/image%3A213678 content://com.miui.gallery.open/raw/%2Fstorage%2Femulated%2F0%2FDCIM%2FScreenshots%2FScreenshot_2022-04-03-10-57-43-787_com.tencent.mm.jpg会有两种格式: 第一种是直接在弹出的选择框里选择图片 第二种是进入相册,选择的图片 通过 Uri 初始化一个 BitmapJava 代码: Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);Kotlin 代码: val bitmap = MediaStore.Images.Media.getBitmap(this.contentResolver, imageUri)但是 getBitmap 又废弃了。。。 'getBitmap(ContentResolver!, Uri!): Bitmap!' is deprecated. Deprecated in Java 拼凑了一个可以执行的代码: val bitmap = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { ImageDecoder.decodeBitmap(ImageDecoder.createSource(this.contentResolver, imageUri)) } else { MediaStore.Images.Media.getBitmap(this.contentResolver, imageUri) }参考 https://stackoverflow.com/questions/3879992/how-to-get-bitmap-from-an-uri 微信关注我哦 👍
我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式 tags: registerForActivityResult |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |