[Android]Copie os arquivos da pasta específica do aplicativo para a sua pasta de Downloads.

この記事は約10分で読めます。
スポンサーリンク

Coisas que eu quero fazer

Os arquivos criados na pasta exclusiva (\Android\data\nome do pacote) do aplicativo Android são copiados para a pasta de downloads do usuário.

No desenvolvimento moderno para Android, java.io.Arquivo Viajar utilizando este método tornou-se difícil.. Android 10 (API 29) e posteriorApresentadoArmazenamento com escopo Como resultado, as permissões de acesso ao armazenamento externo tornaram-se mais rigorosas.

Este artigo aborda a área privada dos aplicativos Android./data/data/... ou /Android/data/.../files)de,GRAVAR_ARMAZENAMENTO_EXTERNO Sem exigir muita autoridade., uma área segura para compartilhamento de arquivos (DownloadIsso explica como movê-lo para ).

fundo

Em versões anteriores do Android, os aplicativos eram… GRAVAR_ARMAZENAMENTO_EXTERNO Assim que obtive as permissões necessárias, pude gravar arquivos em praticamente qualquer lugar no armazenamento externo.

No entanto, com a introdução do Armazenamento com Escopo, cada aplicativo pode usar seu próprio espaço privado.MediaStore Uma coleção compartilhada específica gerenciada por (Fotos, DownloadO acesso foi restrito apenas a (etc.).

Em outras palavras, os aplicativos não podem mais colocar arquivos arbitrariamente em pastas de outros aplicativos ou em locais aleatórios no armazenamento compartilhado.

Esta é uma maneira simples de mover arquivos de uma área privada para uma área compartilhada do usuário.. Arquivo.renomearPara() ou Arquivo.copiar() Essas são as principais razões pelas quais ele não pode ser usado.

Para que você vai usá-lo?

Durante o processamento, os arquivos são gerenciados em uma pasta privada e, após a conclusão, são movidos para uma pasta acessível ao usuário (para downloads, etc.).

Mova os arquivos da pasta Privada para uma pasta acessível ao usuário (arquive-os) para fins de backup.

スポンサーリンク

implementação

Implemente da seguinte forma:

(Isso é implementado como um método da Activity.)

import android.provider.MediaStore;
import android.content.ContentValues; 
import android.os.Environment;

    public void moveFileToDownloads( Path privatePath) {
        File privateFile = privatePath.toFile();
        ContentValues values = new ContentValues();
        values.put(MediaStore.MediaColumns.DISPLAY_NAME, privateFile.getName());
        values.put(MediaStore.MediaColumns.MIME_TYPE, "application/zip");

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
            values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS + File.separator + APPNAME);
        }

        ContentResolver resolver = this.getContentResolver();
        Uri uri = null;

        try {
            uri = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values);
            if (uri == null) {
                throw new RuntimeException("MediaStore insert failed.");
            }

            try (OutputStream os = resolver.openOutputStream(uri);
                 FileInputStream is = new FileInputStream(privateFile)) {
                if (os == null) {
                    throw new RuntimeException("Failed to open output stream.");
                }

                byte[] buffer = new byte[4096];
                int length;
                while ((length = is.read(buffer)) > 0) {
                    os.write(buffer, 0, length);
                }

                privateFile.delete();
            }
        } catch (Exception e) {
            e.printStackTrace();
            if (uri != null) {
                resolver.delete(uri, null, null);
            }
        }
    }

O argumento `privatePath` é o caminho para o arquivo a ser movido para a pasta Downloads.

Se você estiver armazenando o caminho do arquivo como uma String, poderá convertê-lo usando `Path path = Paths.get(pathString);`.

Explicação do código

        ContentValues values = new ContentValues();
        values.put(MediaStore.MediaColumns.DISPLAY_NAME, privateFile.getName());
        values.put(MediaStore.MediaColumns.MIME_TYPE, "application/zip");

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
            values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS + File.separator + APPNAME);
        }

Criando ContentValues ​​(informações sobre o arquivo salvo). Altere o MIME_TYPE conforme necessário.

A parte `APPNAME` em `values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS + File.separator + APPNAME);` é o nome da pasta a ser criada na pasta Download. Se você estiver salvando diretamente na pasta Download, `Environment.DIRECTORY_DOWNLOADS` é suficiente.

        ContentResolver resolver = this.getContentResolver();
        Uri uri = null;

        try {
            uri = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values);
            if (uri == null) {
                throw new RuntimeException("MediaStore insert failed.");
            }

Crie um resolvedor e obtenha o URI (o caminho para salvar).

                byte[] buffer = new byte[4096];
                int length;
                while ((length = is.read(buffer)) > 0) {
                    os.write(buffer, 0, length);
                }

                privateFile.delete();

Este código copia o conteúdo de um arquivo e exclui o arquivo original. Se você estiver copiando e não movendo o arquivo, não chame `privateFile.delete();`.

        } catch (Exception e) {
            e.printStackTrace();
            if (uri != null) {
                resolver.delete(uri, null, null);
            }
        }

Isso é tratamento de erros. `resolver.delete(uri, null, null);` exclui o arquivo com falha na pasta Download.

コメント

タイトルとURLをコピーしました