美文网首页学习之鸿蒙&Android
Android中调用摄像头和相册

Android中调用摄像头和相册

作者: 别看后面有人 | 来源:发表于2021-07-10 16:32 被阅读0次

一、调用摄像头拍照
在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)
    }

相关文章

网友评论

    本文标题:Android中调用摄像头和相册

    本文链接:https://www.haomeiwen.com/subject/vlqcpltx.html