Android调用系统拍照裁剪和选图功能
2018-08-13 09:18
288 查看
最近项目中用到修改用户头像的功能,基本上都是模板代码,现在简单记录一下.
- 调用系统拍照
private fun openCamera() { //调用相机拍照 // 创建File对象,用于存储拍照后的图片 var outputImage = File(externalCacheDir, "output_image.jpg") try { if (outputImage.exists()) { outputImage.delete() } outputImage.createNewFile() } catch (e: IOException) { e.printStackTrace() } if (Build.VERSION.SDK_INT < 24) { imageUri = Uri.fromFile(outputImage) } else { //Android 7.0系统开始 使用本地真实的Uri路径不安全,使用FileProvider封装共享Uri //参数二:fileprovider绝对路径 com.yaoli.testcamerademo:项目包名 imageUri = FileProvider.getUriForFile(this@MainActivity, "com.yaoli.testcamerademo.fileprovider", outputImage) } // 启动相机程序 val intent = Intent("android.media.action.IMAGE_CAPTURE") intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri) startActivityForResult(intent, 1) }
为了适配Android7.0以后的版本,需要在AndroidManifest配置一下(在后面相册选图也需要用到)
<application> ... <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.yaoli.testcamerademo.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> </application>
其中的 file_paths是这样的
- 调用系统相册
private fun pickPhoto() { val intent = Intent("android.intent.action.GET_CONTENT") intent.type = "image/*"[code]startActivityForResult(
Intent.createChooser(intent,"Select Picture"), 2) // 打开相册,这种方式可以打开图片或图库或文件管理中的图片
}[/code]
再来看下onActivityResult
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { when (requestCode) { 1 -> {//拍照 if (resultCode == AppCompatActivity.RESULT_OK) { startPhoneCrop(imageUri!!) } } 2 -> {//打开相册 // 判断手机系统版本号 if (Build.VERSION.SDK_INT >= 21) { // 4.4及以上系统使用这个方法处理图片 handleImageOnKitKat(data!!) } else { // 4.4以下系统使用这个方法处理图片 handleImageBeforeKitKat(data!!) } }
START_CROP_IMAGE_REQUEST -> {
if (resultCode == Activity.RESULT_OK) {
var file = File(outputUri!!.path)
}
}
其中涉及到一些系统裁剪相关的方法
- 调用系统裁剪
/** * 调用系统裁剪的方法 */ private fun startPhoneCrop(uri: Uri) { outputUri = Uri.fromFile(File(Environment.getExternalStorageDirectory().absolutePath + "/" + System.currentTimeMillis() + ".jpg")) val intent = Intent("com.android.camera.action.CROP") if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) } intent.setDataAndType(uri, "image/*") //是否可裁剪 intent.putExtra("corp", "true") intent.putExtra("scale", true) //裁剪器高宽比 intent.putExtra("aspectY", 1) intent.putExtra("aspectX", 1) //设置裁剪框高宽 intent.putExtra("outputX", 150) intent.putExtra("outputY", 150) //返回数据 intent.putExtra("return-data", false) intent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri) intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()) startActivityForResult(intent, START_CROP_IMAGE_REQUEST) } // 4.4及以上系统使用这个方法处理图片 相册图片返回的不再是真实的Uri,而是分装过的Uri @TargetApi(21) private fun handleImageOnKitKat(data: Intent) { var imagePath = "" val uri: Uri = data.data if (DocumentsContract.isDocumentUri(this, uri)) { // 如果是document类型的Uri,则通过document id处理 val docId = DocumentsContract.getDocumentId(uri) if ("com.android.providers.media.documents" == uri.authority) { val id = docId.split(":")[1] // 解析出数字格式的id val selection = MediaStore.Images.Media._ID + "=" + id imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection) } else if ("com.android.providers.downloads.documents" == uri.authority) { val contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), docId.toLong()) imagePath = getImagePath(contentUri, null) } } else if ("content".equals(uri.scheme, true)) { // 如果是content类型的Uri,则使用普通方式处理 imagePath = getImagePath(uri, null) } else if ("file".equals(uri.scheme, true)) { // 如果是file类型的Uri,直接获取图片路径即可 imagePath = uri.path } val imgUri = FileProvider.getUriForFile(applicationContext, "com.yaoli.example.fileprovider", File(imagePath)) startPhoneCrop(imgUri) }private fun handleImageBeforeKitKat(data: Intent) { val uri = data.data val imagePath = getImagePath(uri, null) val imgUri: Uri = Uri.fromFile(File(imagePath)) startPhoneCrop(imgUri) }
private fun getImagePath(uri: Uri, selection: String?): String { var path = "" // 通过Uri和selection来获取真实的图片路径 val cursor = contentResolver.query(uri, null, selection, null, null) if (cursor != null) { if (cursor.moveToFirst()) { path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)) } cursor.close() } return path }
裁剪之后的返回也在onActivityResult方法中.
startActivityForResult(Intent.createChooser(intent, "Select Picture"), 2)
相关文章推荐
- Android 调用系统的拍照与裁剪功能
- android studio 适配android7.0 android 6.0拍照调用系统裁剪工具实现头像上传功能
- Android拍照、调用系统图库、裁剪图片到指定大小后输出
- Android调用系统相机拍照、从相册中取照片,裁剪,并保存到手机SD卡中,展示到界面
- Android实现图片的裁剪(不调用系统功能)
- android调用系统相机拍照后对相片进行裁剪[先存,明天看]
- AndroidAlbum 跳转到相册或者调用系统拍照的功能
- Android调用系统相册、拍照以及裁剪最简单的实现(兼容7.0)
- Android 调用系统拍照及相册裁剪后作为头像,兼容到5.0
- Android实现图片的裁剪(不调用系统功能)
- android调用系统拍照程序和从图库选取图片,返回后调用系统裁剪工具
- Android调用系统自带的拍照功能出现Failure delivering result ResultInfo的问题
- Android拍照和相册+系统裁剪功能返回图片
- android调用系统相机拍照并裁剪
- 文件件监听器,android系统拍照功能调用后删除系统生成的照片
- android调用系统相机拍照后对相片进行裁剪
- 手机调用系统的拍照和裁剪功能,假设界面有输入框EditText,在一些手机会出现点击EditText会弹出输入法,却不能输入的情况。
- Java乔晓松-android中调用系统拍照功能并显示拍照的图片
- android调用系统相机和相册进行拍照裁剪处理,解决不同安卓版本存在无法加载相册的问题,处理了是否有sd卡的存在的情况
- android 调用系统相册和系统拍照功能的Demo