Android APIv29 FileNotFoundException EACCES (permissão negada)


9

Não consigo acessar o armazenamento ao criar para o targetSdkVersion v29.

Aqui está a minha configuração gradle:

    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    ...
        minSdkVersion 15
        targetSdkVersion 29

OBSERVAÇÃO: a WRITE_EXTERNAL_STORAGEpermissão é concedida e a mesma configuração funciona bem ao construir para targetSdkVersion 28.

Aqui está a minha implementação:

        val outputFolder = File(baseFolder + File.separator + "Output Folder")
        if (!outputFolder.exists()) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                Files.createDirectory(outputFolder.toPath()) //This allways returns false with targetSdkVersion 29
            } else {
                if (!outputFolder.mkdirs()) {
                    Log.e("SaveRaw", "Unable to create folder for audio recording")
                }
            }
        }

        outputFile = File("$baseFolder/Output Folder/$filename")
        try {
            fileOutputStream = FileOutputStream(outputFile)
        } catch (e: FileNotFoundException) {
            e.printStackTrace() // allways throwing exception here, even if Output Folder exists 
        }

e aqui está a exceção:

W/System.err: java.io.FileNotFoundException: /storage/emulated/0/Chirp Auto Tester/2019_10_17 10:44:43.raw: open failed: EACCES (Permission denied)
W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:496)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:235)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:186)

Espero que alguém tenha uma resposta, o que estou perdendo aqui?

Atualizar:

Aqui é de onde baseFoldervem. Observe que esse getExternalStorageDirectoryé um método obsoleto.

        val baseFolder: String = if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            Environment.getExternalStorageDirectory().absolutePath
        } else {
            context.filesDir.absolutePath
        }

obrigado


Tente usar esta biblioteca para ver as premissas github.com/googlesamples/easypermissions
Ruben Meiring

Como já mencionei, as permissões necessárias para a gravação de armazenamento externo são concedidas e a mesma instalação funciona ao criar com targetSdkVersion 28. Este não é um problema de permissão!
Dinu

Sua premissa adjacente, de acordo com o erro, não é possível acessar o arquivo / storage / emulated / 0 / Chirp Auto Tester / 2019_10_17 10: 44: 43.raw: open falhou: EACCES (permissão negada) , se o Android 10 usar escopo de armazenamento
Ruben Meiring

Como você explica que está funcionando quando está construindo para targetSdkVersion 28então? De acordo com o erro, sim, é um problema relacionado à permissão, mas não porque as permissões não são concedidas.
Dinu

2
Você não tem acesso do sistema de arquivos a locais arbitrários no armazenamento externo e removível. A limitação de armazenamento removível foi adicionada no Android 4.4. A limitação de armazenamento externo foi adicionada no Android 10.
CommonsWare

Respostas:


15

A partir do Android 11, a permissão de armazenamento está sendo revogada e os desenvolvedores precisam considerar maneiras alternativas de acessar o armazenamento de que precisam através do SAF ou do Media Store . Por enquanto, você pode continuar usando o que está usando adicionando o seguinte no manifesto nas tags do aplicativo:

android:requestLegacyExternalStorage="true"

Você pode considerar alterar seu minSDK para 19 e usá getExternalFilesDir()-lo para obter um caminho que não requer nenhuma permissão.


Ainda não está funcionando, mas definitivamente olhando na direção certa, agora estou conseguindo ENOENT (No such file or directory), no entanto, o diretório definitivamente existe. getExternalFilesDir()soa sobre a decisão certa de corrigir o problema.
Dinu

1
Apenas uma atualização rápida, acabei usando getExternalFilesDir()por enquanto.
Dinu

2

Quando seu aplicativo é direcionado para Build.VERSION_CODES.Q, o caminho retornado desse método não fica mais diretamente acessível aos aplicativos.

    val path = getExternalFilesDir(Environment.DIRECTORY_PICTURES.toString() + 
    File.separator + "Output Folder")
    val file = File(getExternalFilesDir(null), "filename.jpg")

Para mais detalhes, visite o Documentos


-1

você precisa solicitar permissão Manifest.permission.WRITE_EXTERNAL_STORAGE novamente.

antes da 9.0, você solicita apenas Manifest.permission.READ_EXTERNAL_STORAGE e também recebe Manifest.permission.WRITE_EXTERNAL_STORAGE, mas, a partir da 9.0, você pode obter apenas uma permissão que você requereu.

Perdoe meu inglês pobre.


Este não é um problema de permissão de solicitação, mencionei isso algumas vezes, ambas as permissões WRITE e READ EXTERNAL_STORAGE são concedidas. Consulte a resposta do Nikos para obter detalhes sobre por que você ainda não pode acessar o armazenamento externo, mesmo que as permissões sejam concedidas. E não se preocupe com o seu inglês, é ótimo.
Dinu

/ ** * 申请 相册 相册 * / public void galleryPicture () {if (ContextCompat.checkSelfPermission (mContext, Manifest.permission.READ_EXTERNAL_STORAGE)! = PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions (mContext) {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, STORAGE_PERMISSIONS_REQUEST_CODE); } else {openPic (mContext, CODE_GALLERY_REQUEST); }}
Gerry_Liang 23/10/19
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.