android - subir - compartir carpeta gmail
Android 6: ¿ya no puedes compartir archivos? (4)
Alternativamente, no necesita tener un ContentProvider / FileProvider. Simplemente puede agregar el indicador que otorga permiso de lectura en el uri que se comparte. Específicamente, share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
debería hacer el truco.
Estoy compartiendo una imagen y este código funciona correctamente para dispositivos anteriores a Android 6:
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/*");
Uri uri = Uri.fromFile(new File(mFilename));
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
mContext.startActivity(Intent.createChooser(shareIntent, mChooserTitle));
Sin embargo, recibo el error tostado " no puedo adjuntar archivos vacíos " cuando intento compartir con Android 6.
Verifiqué que el archivo existe y no es de longitud cero.
Alguien tiene una solución para esto?
Lo resolví implementando FileProvider
, como lo sugirió @CommonsWare
Primero necesita configurar un FileProvider:
primero, agregue el
<provider>
a su archivo XML de manifiesto<provider android:name="android.support.v4.content.FileProvider" android:authorities="com.myfileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_provider_paths" /> </provider>
segundo, defina sus rutas de archivos en un archivo XML separado, lo llamé " file_provider_paths.xml "
<paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="share" path="/" /> </paths>
puedes encontrar la explicación completa en esta página de documentación
una vez que haya configurado su proveedor de archivos en XML, este es el código para compartir el archivo de imagen:
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/*");
Uri fileUri = FileProvider.getUriForFile(mContext, "com.myfileprovider", new File(mFilename));
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
mContext.startActivity(Intent.createChooser(shareIntent, mChooserTitle));
Otra forma en que solía solucionar este problema fue obtener URI de estilo de proveedor de contenido utilizando MediaScannerConnection
justo después de que escribió su archivo en el directorio público:
MediaScannerConnection.scanFile(context, new String[] {imageFile.toString()}, yourMimeType, new OnScanCompletedListener() {
@Override
public void onScanCompleted(String path, Uri uri) {
//uri = "content://" style URI that is safe to attach to share intent
}
});
Esta puede ser una solución más corta para sus necesidades.
Una limitación del sistema de permisos de tiempo de ejecución de Android 6.0 es que habrá casos de esquina que causen problemas. Lo que encontraste es uno: intentar compartir un archivo en el almacenamiento externo con una aplicación que no tiene los permisos de tiempo de ejecución activados para esa ruta de acceso a la UI en particular.
Digo que este es un "caso de esquina" porque, para que este error en la aplicación receptora afecte al usuario, el usuario no puede haber usado previamente esa aplicación y haber otorgado el permiso necesario. Ya sea:
El usuario nunca antes ha usado esa aplicación, pero aún intenta compartir contenido con ella, o
El usuario revocó el permiso a través de Configuración, pero no se dio cuenta de que rompería este poco de funcionalidad
Ambos son eventos de baja probabilidad.
Usted, como remitente, tiene dos opciones principales:
Alterar el uso de
file://
valoresfile://
Uri
, a favor de unContentProvider
servicio de archivos comoFileProvider
, por lo que el permiso ya no es necesario oSolo viviendo con la caja de la esquina