web-dev-qa-db-fra.com

DownloadManager ne fonctionne pas pour Android 10 (Q)

J'ai battu ma tête contre ce problème pendant un certain temps ... Je mettais une application qui utilise DownloadManger pour effectuer une tâche simple, comme le téléchargement d'un fichier sur le répertoire public de stockage externe I.E:

Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)

Tout fonctionne bien ici depuis Android API 19-28. Son lors de la mise à jour de l'API 29 (Q/10) est l'endroit où les problèmes se produisent. Android Mise en œuvre de stockage et tellement obsolète le getExternalstoragePublicdirectory ... En conséquence, je dois trouver une solution compatible pour supporter les API 19 -29. Je ne peux pas utiliser le stockage d'applications interne puisque DownloDManager sera une exception de sécurité. Androids Documentation stipule que je peut utiliser le téléchargementmanager.request setDestinationUri et il mentionne même pour Android Q que je peux utiliser Context.getExternalFilesDir(String). Quand je le fais cependant, le chemin est toujours Le chemin émulé:

/storage/emulated/0/Android/data/com.my.package.name/files/Download/myFile.xml

Je reçois un rappel du gestionnaire de téléchargement que le téléchargement est terminé (avec ID de droite), mais je ne peux pas saisir le téléchargement de la zone que j'ai enregistrée. Je vérifie si le fichier existe et il retourne faux:

new File("/storage/emulated/0/Android/data/com.my.package.name/files/Download/myFile.xml").exists();

Toute aide est appréciée

Ajout de code pour le contexte. Donc configurer le gestionnaire de téléchargement

    private void startDownload() {
        IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
        registerReceiver(downloadReceiver, filter);

        String remoteURL= getString(R.string.remote_url);

        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(remoteUrl));
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
        request.setTitle(getString(R.string.download_title));
        request.setDescription(getString(R.string.download_description));
        request.setDestinationUri(Uri.fromFile(new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "myFile.xml")));

        DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
        mainDownloadID= manager.enqueue(request);
    }

vérification du fichier s'il existe:

new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "myFile.xml").exists(); //this returns false in the onReceive (and download IDs match)
7
New Guy

Chemins de fichiers en dehors des répertoires privés de l'application dans Android Q et ci-dessus inutile.

Voir https://developer.andrid.com/training/data-storage#scoped-Storage

Vous devez également demander à l'utilisateur de télécharger également les fichiers, cela vous permettra d'obtenir une URI pour la destination DownloadManager.

https://developer.andrid.com/training/data-storage/shared/documents-files#grant-access-Directory

Vous voudrez probablement persister cette permission

https://developer.andrid.com/training/data-storage/shared/documents-files#persist-permissions

0
Andrew

Oui, son stockage de portée mais même si vous pouvez télécharger le fichier dans Q + à l'aide de DownloadManger, aucun besoin de faire Android:requestLegacyExternalStorage="true"

Je fais de cette façon.

  1. manifeste
  • ->
  1. Téléchargermanger

     val fileName =
         Constants.FILE_NAME + Date().time
    
     val downloadUri = Uri.parse(media.url)
     val request = DownloadManager.Request(
         downloadUri
     )
     request.setAllowedNetworkTypes(
         DownloadManager.Request.NETWORK_WIFI or DownloadManager.Request.NETWORK_MOBILE
     )
         .setAllowedOverRoaming(true).setTitle("Some name")
         .setDescription("Downloading file")
         .setDestinationInExternalPublicDir(
             Environment.DIRECTORY_DOWNLOADS, File.separator + FOLDER + File.separator + fileName
         )
    
    
     Toast.makeText(
         context,
         "Download successfully to ${downloadUri?.path}",
         Toast.LENGTH_LONG
     ).show()
    
     downloadManager.enqueue(request)
    

Il posera donc une autorisation d'écriture ci-dessous q, mais dans q et q + il téléchargera sans demander la permission dans/télécharger/dossier dir.

0
Mohd Faizan