Permiso de Android denegado al leer / proc / self / exe de un hilo no principal
Estoy tratando de obtener el camino canónico de / proc / self / exe. Cuando hago esto en el hilo principal funciona, cuando hago esto en un diverso hilo que se bloquea con un IOException: "Permiso negado":
DBG E Thread: main E Path: /system/bin/app_process32 E Thread: Thread-21656 System.err W java.io.IOException: Permission denied W at java.io.File.canonicalizePath(Native Method) W at java.io.File.getCanonicalPath(File.java:414) W at java.io.File.getCanonicalFile(File.java:428) W at com.quanturium.testbugprocselfexe.MyActivity.getPathOfExecutable(MyActivity.java:36) W at com.quanturium.testbugprocselfexe.MyActivity.access$000(MyActivity.java:12) W at com.quanturium.testbugprocselfexe.MyActivity$1.run(MyActivity.java:26) W at java.lang.Thread.run(Thread.java:818)
Código:
- Lista de llamadas del sistema Linux de Linux
- Un comando de terminal para un Android enraizado para volver a montar / Sistema como lectura / escritura
- Cómo evitar el servicio de asesinato del sistema cuando se cancela la aplicación / actividad
- Android - mount: Sistema de archivos de sólo lectura
- Acceso a la notificación de Android TV
@Override protected void onCreate (Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getPathOfExecutable(); // Works as expected new Thread(new Runnable() { @Override public void run () { getPathOfExecutable(); // Trigger the IOException: Permission denied } }).start(); } private void getPathOfExecutable() { try { Log.e("DBG", "Thread: " + Thread.currentThread().getName()); Log.e("DBG", "Path: " + new File("/proc/self/exe").getCanonicalFile().getPath()); } catch (IOException e) { e.printStackTrace(); } }
Este error sólo ocurre cuando debuggable está configurado como false en el archivo build.gradle
Código para probarlo: https://github.com/quanturium/TestBugProcSelfExe
¿Se trata de un error o un comportamiento previsto? ¿Qué sería una solución para obtener la ruta del ejecutable actual?
- Información de la aplicación del sistema Android
- ¿Emulador de Android versión 16.0 persistant / system / storage?
- ¿Cómo puedo convertir mi aplicación en aplicación de sistema?
- Optimizar el esfuerzo de prueba de Android
- No se puede aplicar el brillo de la pantalla del sistema mediante programación en Android
- Obtención de todos los fondos de pantalla del sistema
- No se puede mostrar la barra del sistema Android después de ocultar
- Actualizar el proveedor de Android.
¿Bloquea el código? Si no, no debería haber ramificaciones de ejecutarlo en el hilo principal. Sin embargo, puedes hacerlo desde otro hilo, con:
Context.runOnUiThread(new Runnable() { getPathOfExecutable(); });
Este es el trabajo más limpio alrededor de lo que puedo pensar, a corto de la edición de los permisos de su archivo (que no puede obtener la ruta de acceso sin ejecutar su código en el hilo principal de todos modos), porque usted tiene r / w privilegios en / proc / Autoexe
Esto es muy raro, y todavía estoy investigando las diferencias de permiso en diferentes hilos en android.
Si usted puede conseguir que funcione en el hilo principal, mi opinión sería simplemente hacerlo en el hilo principal, y no se preocupe mucho por la optimización, ya que el rendimiento no es diferente en diferentes hilos.
¿Qué sería una solución para obtener la ruta del ejecutable actual?
Puesto que cada aplicación de Android se bifurca de Zygote, que es el primer proceso de Java vm cuando la máquina virtual creada por /system/bin/app_process
en el arranque del sistema.
Si intenta leer el /proc/self/exe
desde su aplicación para Android, el ejecutable real será /system/bin/app_process
. Incluso si lee esto fuera del hilo principal de la aplicación, el resultado es el mismo y no tendría el error de permiso en teoría.
La pregunta que me hiciste es un tipo de problema extraño, he probado con el siguiente código en Android 2.3.3 y funcionó bien.
new Thread() { /* (non-Javadoc) * @see java.lang.Thread#run() */ @Override public void run() { // TODO Auto-generated method stub super.run(); try { Log.d(TAG, new File("/proc/self/exe").getCanonicalFile().getPath()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }.start();
- Creación de un proyecto de Android desde la línea de comandos con Docker
- Android: Problema de APK firmado: no hay constructor predeterminado cuando hay uno