一、调用摄像头拍照
在xml中添加一个button和一个imageview显示图片
<Button
android:id="@+id/takePhotoBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="照相"/>
<ImageView
android:id="@+id/imageview"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
具体的代码:
takePhotoBtn.setOnClickListener {
outputImage=File(externalCacheDir,"output_image.jpg")
if (outputImage.exists()){
outputImage.delete()
}
outputImage.createNewFile()
imageUri= if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){
FileProvider.getUriForFile(this,"com.app.cameraal",outputImage)
}else{
Uri.fromFile(outputImage)
}
//启动相机
val intent=Intent("android.media.action.IMAGE_CAPTURE")
intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri)
startActivityForResult(intent,takePhoto)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode){
takePhoto ->{
if (resultCode==Activity.RESULT_OK){
//将拍摄照片显示出来
val bitmap=BitmapFactory.decodeStream(contentResolver.openInputStream(imageUri))
imageview.setImageBitmap(bitmap)
}
}
}
首先创建一个file对象,用于存放摄像头拍摄的图片,这里把图片命名为output_image.jpg,并存放在手机SD卡的应用关联目录下面,具体图片保存的目录:/sdcard/Android/data/<package name>/cache。因为在Android6.0开始,读写SD卡被列为了危险权限,如果图片存储在SD卡的任何位置都需要权限处理才能使用。接着进行判断设备版本,7.0以下的版本用fromFile()方法将file对象转换成Uri对象,这个Uri对象标识着图片的真实路径。否则调用FileProvider的getUriFile()方法将File对象转换成一个封装Uri对象,getUriForFile()方法接收三个参数,第一个参数传入context对象,第二个参数可以是任意的字符串,第三个对象是刚刚创建的file对象。FileProvider是一种特殊的ContentProvider,它可以对数据进行保护,可以选择性的将封装过的Uri共享给外部,从而提高应用安全性。接下来构建Intent对象,Intent的action指定为android.media.action.IMAGE_CAPTURE,再调用intent的putExtra()方法指定图片的输出地址,这里填入刚刚获得的Uri对象,最后调用startActivityForResult()方法启动Activity。因此拍完照之后会返回到onActivityResult()方法中。可以调用bitmapFactory的decodeStream()方法将图片解析成Bitmap对象,然后显示在imageview上面。
最后contentProvider需要在manifest中注册才可以,
<provider
android:authorities="com.app.cameraal"
android:name="androidx.core.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths">
</meta-data>
</provider>
provider标签使用<meta-data>指定的Uri共享路径,并引用@xml/file_paths,下面创建一个file_paths.xml文件
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="my_images"
path="/"/>
</paths>
二、调用摄像头拍照
具体代码:
selectPhotoBtn.setOnClickListener {
val intent=Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.type="image/*"
startActivityForResult(intent,fromPhoto)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode){
....
fromPhoto ->{
if (requestCode==Activity.RESULT_OK&&data!=null){
data.data?.let {
val bitmap=getBitmapFromUri(imageUri)
imageview.setImageBitmap(bitmap)
}
}
}
}
}
private fun getBitmapFromUri(uri: Uri)=contentResolver.openFileDescriptor(uri,"r")?.use{
BitmapFactory.decodeFileDescriptor(it.fileDescriptor)
}
网友评论