android - camera intent fileprovider
SecurityException con grantUriPermission al compartir un archivo con FileProvider (2)
El primer problema en su código es el atributo exportado establecido en falso. Por favor, cámbialo a verdadero como,
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="au.com.example.AppA.fileprovider"
android:exported="true"
android:readPermission="au.com.example.READ_CONTENT"
android:writePermission="au.com.example.WRITE_CONTENT" >
</provider>
Lo segundo que debe hacer es: si la aplicación externa, la aplicación B está utilizando el proveedor de contenido en la aplicación A. Luego, en la aplicación Un archivo de manifiesto, mencione el permiso como,
<permission
android:name="au.com.example.READ_CONTENT"
>
</permission>
<permission
android:name="au.com.example.WRITE_CONTENT"
>
</permission>
y en la aplicación B mencionar usos-permiso como,
<uses-permission android:name="au.com.example.READ_CONTENT" />
<uses-permission android:name="au.com.example.WRITE_CONTENT" />
Por favor, avíseme si su problema se ha resuelto o no. Si no, envíe su código completo. Trataré de encontrar el problema. Gracias.
Tengo dos aplicaciones. Estoy tratando de compartir un archivo de la aplicación A a la aplicación B usando un FileProvider. La Aplicación A llama al método Insert en un ContentProvider en la Aplicación B para insertar un registro. Los datos insertados incluyen el Uri en el archivo que quiero compartir de la Aplicación A. El ContentProvider en la Aplicación B intentará leer el archivo compartido desde la Aplicación A. Como no estoy usando un Intento para compartir el archivo, estoy llamando a Context.grantUriPermission
en la aplicación A para permitir la lectura (y en ocasiones escribir):
mContext.grantUriPermission(MyPackageName, contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
Sin embargo, la ejecución de esta línea me da (Nombres cambiados para proteger a los inocentes):
java.lang.SecurityException: Uid 10066 does not have permission to uri content://au.com.example.AppA.fileprovider/MyFolder/MyFileName
at android.os.Parcel.readException(Parcel.java:1322)
at android.os.Parcel.readException(Parcel.java:1276)
at android.app.ActivityManagerProxy.grantUriPermission(ActivityManagerNative.java:2374)
at android.app.ContextImpl.grantUriPermission(ContextImpl.java:1371)
at android.content.ContextWrapper.grantUriPermission(ContextWrapper.java:400)
at etc...
La aplicación A tiene lo siguiente en el archivo Manifiesto:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="au.com.example.AppA.fileprovider"
android:exported="false"
android:grantUriPermissions="true"
android:readPermission="au.com.example.READ_CONTENT"
android:writePermission="au.com.example.WRITE_CONTENT" >
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
filepaths.xml tiene:
<paths>
<files-path
name="MyFolder"
path="MyFolder/" />
</paths>
Tanto la aplicación A como la aplicación B tienen lo siguiente:
<uses-permission android:name="au.com.example.READ_CONTENT" />
<uses-permission android:name="au.com.example.WRITE_CONTENT" />
Intenté definir los permisos en ambas aplicaciones. Ambos están firmados con la misma firma de depuración:
<permission
android:name="au.com.example.READ_CONTENT"
android:permissionGroup="MyGroup"
android:protectionLevel="signature" >
</permission>
<permission
android:name="au.com.example.WRITE_CONTENT"
android:permissionGroup="MyGroup"
android:protectionLevel="signature" >
</permission>
La ruta real en la que termina el archivo es:
/data/data/au.com.example.AppA/files/MyFolder
En este punto estoy perplejo. No sé por qué no puedo otorgar permiso para un archivo que acabo de crear dentro de la misma aplicación. Entonces mis preguntas son: ¿Por qué recibo esta excepción y cómo puedo otorgarle permiso a la aplicación B?
Bueno, después de una semana y mucho ensayo y error, parece que la respuesta es no especificar permisos. Entonces, el Manifiesto de la aplicación A debería contener:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="au.com.example.AppA.fileprovider"
android:exported="false"
android:grantUriPermissions="true" >
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
es decir, eliminé los permisos de lectura y escritura. Mi entendimiento inicial, y al no encontrar documentación que dijera lo contrario, era que estos eran necesarios para restringir el acceso. Sin embargo, descubrí que realmente interfieren y hacen que Context.grantUriPermission
falle. El acceso ya está limitado.
Para completar la imagen y responder la segunda parte de mi pregunta, encontré lo siguiente:
Denegación de permiso de Android en Widget RemoteViewsFactory for Content
Tuve que agregar:
final long token = Binder.clearCallingIdentity();
try {
[retrieve file here]
} finally {
Binder.restoreCallingIdentity(token);
}
al proveedor de contenido en la aplicación B. De lo contrario, también obtendría errores de seguridad.