android - permission - cómo crear un archivo con permiso de lectura mundial en el subdirectorio del directorio de archivos
internal storage android example (4)
OP preguntó cómo dar acceso a un archivo en la siguiente jerarquía: appdir/files/subdir/myfile
.
Las respuestas proporcionadas aquí no tienen en cuenta la subcarpeta, así que creo que hay un margen de mejora.
Para acceder al archivo en jerarquía, un consumidor debe tener permiso de ejecución en cada carpeta en una ruta para poder acceder (leer, escribir, ejecutar) los archivos que se encuentran debajo.
Para API> = 24
A partir de la API 24, Android restringe el acceso a appdir
(aka / data / data / appdir):
Para mejorar la seguridad de los archivos privados, el directorio privado de aplicaciones dirigidas a Android 7.0 o superior tiene acceso restringido (0700). Esta configuración evita la fuga de metadatos de archivos privados, como su tamaño o existencia.
El appdir
no tiene permiso de ejecución mundial y, por lo tanto, no puede appdir
:
angler:/ $ cd /data/data
angler:/data/data $ cd com.myapp
/system/bin/sh: cd: /data/data/com.myapp: Permission denied
En pocas palabras: puede otorgar permiso de lectura mundial a uno de los archivos en la carpeta de su aplicación, pero ninguna otra aplicación (siempre que no compartan la misma ID de usuario de Linux) podrá leerlos.
No solo eso: el intento de pasar un file://
URI a una aplicación externa activará una FileUriExposedException .
Para API <24
La carpeta appdir
tiene permiso de ejecución mundial de forma predeterminada:
shell:/ $ cd /data/data
shell:/data/data $ cd com.myapp
shell:/data/data/com.myapp $
Tenga en cuenta que incluso la carpeta appdir/files
tiene permiso de ejecución mundial :
shell:/data/data/com.myapp $ cd files
shell:/data/data/com.myapp/files $
Pero si intenta crear una subcarpeta (debajo de la carpeta de files
), use este código:
File subdir = new File(context.getFilesDir(), "subfolder");
subdir.mkdir();
no tendrá permiso de ejecución mundial :
shell:/ $ cd /data/data/com.myapp/files
shell:/data/data/com.myapp/files $ cd subfolder
/system/bin/sh: cd: /data/data/com.myapp/files/subfolder: Permission denied
shell:/data/data/com.myapp/files $ run-as com.myapp
shell:/data/data/com.myapp $ cd files
shell:/data/data/com.myapp/files $ ls -l
total 72
drwx------ 3 u0_a226 u0_a226 4096 2016-11-06 11:49 subfolder
shell:/data/data/com.myapp/files $
Por lo tanto, tiene que otorgar explícitamente a la carpeta que acaba de crear el permiso de ejecución File#setExecutable utilizando File#setExecutable método de File#setExecutable (agregado en la API 9):
subdir.setExecutable(true, false);
Y solo entonces, como lo sugieren otros, puede crear su archivo y otorgarle permiso de lectura mundial:
File file = new File(subdir, "newfile");
if(!file.exists()) {
file.createNewFile();
file.setReadable(true, false);
}
Al hacerlo, cualquier aplicación externa podrá leer su archivo:
shell:/ $ cd /data/data/com.myapp/files
shell:/data/data/com.myapp/files $ cd subfolder
shell:/data/data/com.myapp/files/subfolder $ cat newfile > /sdcard/1
shell:/data/data/com.myapp/files/subfolder $ cd /sdcard
shell:/sdcard $ ls 1
1
Necesito crear archivos bajo myapp / files / subdir con permiso global en mi aplicación. Hago esto porque uso aplicaciones externas para abrir algunos archivos.
FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_WORLD_READABLE);
crea un archivo solo en la carpeta de archivos. Utilizando
File dir=new File(Constants.TASK_DIRECTORY);
dir.mkdirs();
File file=new File(dir, FILENAME);
file.createNewFile(); FileOutputStream fos=new FileOutputStream(file);
Crea archivos bajo subdirectorios pero con permisos privados. Necesito encontrar una manera de componer ambos para crear un archivo en un subdirectorio para que sea legible en todo el mundo
He intentado muchas cosas, pero ninguna me ayudó y esta fue la pregunta mía sin respuesta más larga.
Sé que esta es una vieja pregunta, pero aquí está la manera correcta
public void makeFileWorldReadable(String path)
{
File f = new File(path);
if(!f.exists()) // Create the file if it does not exist.
f.createNewFile();
f.setReadable(true, false);
}
Si lo está ejecutando en un dispositivo rooteado, cambie los permisos de archivo utilizando:
Runtime.getRuntime().exec("chmod 777 " + PATH + fileName);
O intente File.setReadable()
, File.setWritable
mientras crea el archivo.
Una solución alternativa que utilicé en el pasado fue volver a abrir el archivo ya existente utilizando openFileOutput en modo de anexión, y pasar las banderas legibles y / o escritas en todo el mundo durante ese tiempo. Luego cierre inmediatamente el archivo sin escribirlo.
Aunque me gustan más los nuevos métodos añadidos en API 9.