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文件的创建
<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>
网友评论