美文网首页
Android Kotlin 5.0、7.0 、8.0、9.0、

Android Kotlin 5.0、7.0 、8.0、9.0、

作者: hao_developer | 来源:发表于2019-12-06 16:16 被阅读0次

android 10.0需要添加以下配置才能获取到文件路径

在application节点下添加一下代码
android:requestLegacyExternalStorage="true"

package com.yqx.tuisong

import android.Manifest
import android.app.Activity
import android.content.ContentValues
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.text.TextUtils
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import androidx.core.os.EnvironmentCompat
import kotlinx.android.synthetic.main.activity_camera_view.*
import java.io.File
import java.text.SimpleDateFormat
import java.util.*


/**
 * @package com.yqx.tuisong
 * @fileName CameraActivity
 * @data on 2019/12/6 14:32
 * @autor zhuhao
 * @describe TODO
 * @company 一启享
 */
class CameraActivity : AppCompatActivity() {

    val REQUEST_ORIGINAL = 110
    val REQUEST_ORIGINAL_PHOTO = 111
    // 是否是Android 10以上手机
    val isAndroidQ = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
    //用于保存拍照图片的uri
     var mCameraUri: Uri? = null
    // 用于保存图片的文件路径,Android 10以下使用图片路径访问图片
    var mCameraImagePath: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_camera_view)
        requestPermissions()

        var photoFile: File? = null
        var photoUri: Uri? = null

        cameraBtn.setOnClickListener {

            if (isAndroidQ){  // 适配android 10
                photoUri = createImageUri();
            }else{//10以下
                photoFile = createImageFile()
                if (photoFile != null && photoFile!!.exists() ) {
                    mCameraImagePath = photoFile?.getAbsolutePath();
                    if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){//7.0以上
                        //适配Android 7.0文件权限,通过FileProvider创建一个content类型的Uri
                        photoUri  = FileProvider.getUriForFile(this@CameraActivity,"com.yqx.tuisong.fileprovider",photoFile!!)
                    }else{
                        photoUri  = Uri.fromFile(photoFile);
                    }
                }else{
                    Toast.makeText(this,"创建失败",Toast.LENGTH_SHORT).show()
                }
            }
            mCameraUri = photoUri;
            if (photoUri != null) {
                val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
                //为拍摄的图片指定一个存储的路径
                intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri)
                startActivityForResult(intent, REQUEST_ORIGINAL)
            }
        }

        photoBtn.setOnClickListener {

            val intent = Intent()
            intent.action = Intent.ACTION_PICK
            intent.type = "image/*"
            startActivityForResult(intent, REQUEST_ORIGINAL_PHOTO)

        }

    }

    /**
     * 创建保存图片的文件
     */
    private fun createImageFile(): File? {
        val imageName: String = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
        val storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
        if (!storageDir!!.exists()) {
            storageDir.mkdir()
        }
        val tempFile = File.createTempFile( imageName, ".jpg",storageDir)
        return if (Environment.MEDIA_MOUNTED != EnvironmentCompat.getStorageState(tempFile)) {
            null
        } else tempFile
    }

    /**
     * 创建图片地址uri,用于保存拍照后的照片 Android 10以后使用这种方法
     */
    private fun createImageUri(): Uri? {
        val status = Environment.getExternalStorageState()
        // 判断是否有SD卡,优先使用SD卡存储,当没有SD卡时使用手机存储
        return if (status == Environment.MEDIA_MOUNTED) {contentResolver
            .insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, ContentValues() )
        } else {
            contentResolver.insert(MediaStore.Images.Media.INTERNAL_CONTENT_URI, ContentValues())
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == Activity.RESULT_OK){
            when(requestCode){
                REQUEST_ORIGINAL ->{//拍照返回
                    if (isAndroidQ) {
                        // Android 10 使用图片uri加载
                        showImage.setImageURI(mCameraUri);
                    } else {
                        // 使用图片路径加载
                        showImage.setImageBitmap(BitmapFactory.decodeFile(mCameraImagePath));
                    }
                }
                REQUEST_ORIGINAL_PHOTO ->{//相册返回
                    val photoPath = getPhotoFromPhotoAlbum.getRealPathFromUri(this, data?.getData());
                    if (!TextUtils.isEmpty(photoPath)){
                        // 使用图片路径加载
                        if (isAndroidQ) {
                            showImage.setImageURI(data?.getData());
                        }else{
                            showImage.setImageBitmap(BitmapFactory.decodeFile(photoPath));
                        }
                    }
                }
            }
        }else{
            Toast.makeText(this,"取消",Toast.LENGTH_SHORT).show()
        }
    }

    fun requestPermissions() {

        if (Build.VERSION.SDK_INT >= 23) {
            val checkPermissions =
                ContextCompat.checkSelfPermission(this, Manifest.permission.LOCATION_HARDWARE)
            if (checkPermissions != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(
                    this,
                    arrayOf(
                        Manifest.permission.LOCATION_HARDWARE,
                        Manifest.permission.CHANGE_WIFI_STATE,
                        Manifest.permission.READ_EXTERNAL_STORAGE,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.CAMERA,
                        Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.ACCESS_COARSE_LOCATION
                    )
                    , 1
                )
                return
            }
        }
    }

}

AndroidManifest.xml的配置

<application
        android:name=".MyApplication"
        android:allowBackup="true"
.....

<provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.yqx.tuisong.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                tools:replace="android:resource"
                android:resource="@xml/files_path" />
        </provider>

 </application>

files_path.xml文件的创建

image.png
<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <paths>

        <files-path path="files" name="files" />
        <cache-path path="files" name="cache" />
        <external-path path="files" name="external" />
        <external-files-path path="files" name="externalfiles"/>
        <!-- 此标签需要 support 25.0.0以上才可以使用-->
        <external-cache-path  path="files" name="externalcache"/>
        <external-path name="camera_photos" path="."  />
        <!--<external-cache-path  path="my_images" name="Android/data/com.gs.common/files/Pictures/"/>
        <external-cache-path  path="images" name="Pictures/"/>
        <external-cache-path  path="dcim" name="DCIM/"/>-->
    </paths>
</resources>

相关文章

网友评论

      本文标题:Android Kotlin 5.0、7.0 、8.0、9.0、

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