Recuperar la ruta de acceso del archivo de la intención de DownloadManager detectada
Desde Android 4.2 si un usuario descarga algún archivo en el navegador se utiliza el DownloadManager. Si el usuario hace clic en la notificación de "descarga completa", un intento es y siempre se inició. Antes de Android 4.2, la intención era tener la ruta del archivo descargado en el contenido, de modo que:
intent.getData()
file:///storage/emulated/0/Download/some_file.ext
una cadena como file:///storage/emulated/0/Download/some_file.ext
. Sin embargo, desde Android 4.2 el gestor de descargas difunde e intenta con un esquema de content
, como el content://downloads/all_downloads/2334
.
- ¿Cómo obtener el estado de la descarga?
- Android: descarga el archivo desde Internet mediante DownloadManager y guárdelo en la memoria interna
- DownloadManager - entendiendo ERROR_HTTP_DATA_ERROR
- Android DownloadManager "Imposible abrir archivo"
- ¿Por qué este cursor está vacío?
¿Cómo recupero la ruta del archivo local para un archivo descargado?
He intentado lo siguiente:
public static String getRealPathFromURI(Uri contentUri, Activity activity) { DownloadManager downloadManager = (DownloadManager) activity.getSystemService(Activity.DOWNLOAD_SERVICE); String[] contentParts = contentUri.getEncodedPath().split("/"); Cursor q = downloadManager.query(new DownloadManager.Query().setFilterById(Integer.parseInt(contentParts[contentParts.length - 1]))); if (q == null) { // Download no longer exists return null; } q.moveToFirst(); return q.getString(q.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME)); }
Pero el cursor nunca devuelve ninguna fila (por lo que q.getCount() == 0
y por lo tanto la última declaración return
una excepción). Además, el hack al analizar la identificación del archivo de descarga desde el Uri parece extraño.
ACTUALIZACIÓN: También he intentado:
input = getActivity().getContentResolver().openInputStream(contentUri);
Pero esto devuelve un error que indica
Permiso Negación: lectura com.android.providers.downloads.DownloadProvider uri contenido: // downloads / all_downloads / 2334 desde pid = 30950, uid = 10064 requiere android.permission.ACCESS_ALL_DOWNLOADS, o grantUriPermission ()
Es evidente que no puedo acceder a las descargas (ya que mi aplicación no las inició – el navegador sí) a través de ContentProvider
.
- Establecer carpeta personalizada Android Download Manager
- Error en el administrador de descargas android
- ¿Cómo mostrar el progreso de la descarga en la barra de progreso de Android?
- Notificación desaparece - Android DownloadManager
- podemos abrir la carpeta de descarga a través de. ¿intención?
- DownloadManager.ACTION_DOWNLOAD_COMPLETE Receptor de difusión que recibe el mismo ID de descarga más de una vez con diferentes estados de descarga en Android
- Agregue manualmente archivos locales a la aplicación Descargas
- DownloadManager VS ¿Implementación de descarga propia?
Obtener a través de la resolución de contenido es lo correcto. No cada URL de contenido va a ser un archivo. Por ejemplo, la aplicación Galería le proporcionará uri que traducir a una llamada de red o un archivo local dependiendo de la fuente.
Incluso si llegas a la ruta del archivo real, es probable que no pueda leerlo, debido a los permisos de archivo, aunque puede tener suerte de que está en el almacenamiento externo. ¿Has probado a agregar Eso no funcionará, ya que el permiso es a nivel de firma 🙁 android.permission.ACCESS_ALL_DOWNLOADS
a tu aplicación como sugiere la excepción?
Esto es lo que funcionó. En primer lugar, no puede (y no debe querer) obtener la ruta del archivo como botteaap correctamente señalado. (Créditos a él por establecerme en el camino correcto.) En su lugar obtendrá un permiso temporal automáticamente para acceder al contenido del archivo, usando:
InputStream input = getContentResolver().openInputStream(intent.getData());
Puede leer este InputStream
como cualquier otro en Java. Parece que no hay manera de obtener el nombre del archivo. Si necesita un archivo, primero escriba el flujo de entrada en un archivo (temporal).
La SecurityException
es lanzada cuando se revocó su acceso temporal. Esto sucedió para mí en algunos archivos que traté de leer incorrectamente antes y específicamente cuando el Intención fue recogido en mi Acticity onNewIntent
.
Solo quiero añadir a la respuesta de @erickok ya que me tomó varias horas entender esto. Como se indica por @ jcesarmobile, sólo se garantiza que sea capaz de obtener el nombre y el tamaño del archivo, no la ruta completa.
Puede obtener el nombre y el tamaño de la siguiente manera y, a continuación, guardar en un archivo temporal:
String filename = null; Long filesize = null; Cursor cursor = null; try { cursor = this.getContentResolver().query(intent.getData(), new String[] { OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE}, null, null, null ); if (cursor != null && cursor.moveToFirst()) { filename = cursor.getString(0); filesize = cursor.getLong(1); } } finally { if (cursor != null) cursor.close(); }