Environment.getExternalStorageDirectory() deprecated in API level 29 java

前端 未结 6 1030
梦毁少年i
梦毁少年i 2020-11-22 13:08

Working on android Java, recently updated SDK to API level 29 now there is a warning shown which states that

Environment.getExternalStorageDirectory() i

6条回答
  •  遥遥无期
    2020-11-22 13:49

    This is a small example how to get URI for a file if you want to take photo using default camera and store it in a DCIM folder (DCIM/app_name/filename.jpg):

    Open camera (remember about CAMERA permission):

    private var photoURI: Uri? = null
    
    private fun openCamera() {
        Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { takePictureIntent ->
            photoURI = getPhotoFileUri()
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
            takePictureIntent.resolveActivity(requireActivity().packageManager)?.also {
                startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
            }
        }
    }
    

    And get URI:

    private fun getPhotoFileUri(): Uri {
        val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
        val fileName = "IMG_${timeStamp}.jpg"
    
        var uri: Uri? = null
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            val resolver = requireContext().contentResolver
            val contentValues = ContentValues().apply {
                put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
                put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
                put(MediaStore.MediaColumns.RELATIVE_PATH, "DCIM/app_name/")
            }
    
            uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
        }
    
        return uri ?: getUriForPreQ(fileName)
    }
    
    private fun getUriForPreQ(fileName: String): Uri {
        val dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
        val photoFile = File(dir, "/app_name/$fileName")
        if (photoFile.parentFile?.exists() == false) photoFile.parentFile?.mkdir()
        return FileProvider.getUriForFile(
            requireContext(),
            "ru.app_name.fileprovider",
            photoFile
        )
    }
    

    Don't forget about WRITE_EXTERNAL_STORAGE permission for pre Q and add a FileProvider to AndroidManifest.xml.

    And get a result:

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            REQUEST_IMAGE_CAPTURE -> {
                photoURI?.let {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                        val thumbnail: Bitmap =
                            requireContext().contentResolver.loadThumbnail(
                                it, Size(640, 480), null
                            )
                    } else {
                        // pre Q actions
                    }
                }
            }
        }
    }
    

提交回复
热议问题