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)
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
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.
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.