Android-Debug-BridgeCuando guardamos las Shared Preferences en un dispositivo real, puede que no podamos acceder al fichero .xml generado desde el Android Device Monitor.

Para poder acceder tendríamos que ser root en el dispositivo.

Si no lo somos, podremos utilizar el hecho de que para cada package en Android se crea un usuario linux para ejecutarla. Por tanto podemos hacer uso de run-as en el Shell del ADB como explicamos a continuación.

Abrimos un terminal (o un una ventana de comandos) cmd.exe y nos posicionamos el la ruta donde tenemos instalado el SDK. Esta ruta se puede obtener en Android Studio abriendo el menú File/Settings y buscar en Appearance/Behavior/System Setings/Android SDK

Con el comando ./adb shell entramos en el árbol de directorios del dispositivo (del móvil emulado o del dispositivo real vinculado)

Una vez en el terminal en esa posición ejecutar los siguientes comandos, con lo que verificamos que no tenemos acceso al directorio /data/data/

./adb shell
ls -al
...
drwxrwx--x system system 2012-09-24 23:38 data
...
cd data/
ls
opendir failed, Permission denied

Pero como hemos dicho podemos utilizar run-as para solventar ese problema de acceso.

Para ejecutar run-as debemos haber entrado previamente al shell del adb con el comando ./adb shell

run-as com.your.package ls -l /data/data/com.your.package

Con esto,  estamos ejecutando el comando ls -l como si fuéramos el usuario com.your.package (sustituir por el de vuestra aplicación) en el árbol de directorios del dispositivo.

De esta forma ya puedo utilizar comandos (linux) para copiar, mover y borrar ficheros que la aplicación genera o modifica en nuestro dispositivo no rooteado. Recordar que estamos dentro del árbol de directorios del dispositivo (estamos dentro del adb shell).

También podemos utilizar otro método, run-as en modo interactivo, con lo que nos colocará en la carpeta /data del package correspondiente y podremos navegar desde ahí.

run-as com.your.package
shell@android:/data/data/com.your.package $ ls
cache
databases
lib
shared_prefs

Para que funcione la aplicación tiene que ser debuggable.

Esto significa que run-as funcionará para aplicaciones que estemos desarrollando nosotros o que han sido publicadas con el flag debbuggable a true. Lo que no funciona para la mayoría de las aplicaciones comerciales publicadas.

Acceso usando el servidor Matrix

Si estamos usando el servidor docente, cada alumno tiene un Sdk específico compartiendo la misma instalación de Android. Esto genera problemas con el adb y por ello se han modificado los puertos de acceso al mismo para cada alumno.

Por ello tenemos que indicar ciertos puertos para poder acceder a nuestro sistema de ficheros, estando en el emulador o utilizando nuestro dispositivo vía wifi y la VPN.

Identificar el puerto con el emulador y/o con un dispositivo.

Cuando arrancamos Android desde el lanzador, nos pide el número de dispositivo. Si no tecleamos ninguno y damos intro, entonces la instancia de Android Studio se vinculará únicamente con el emulador para poder depurar.

La imagen muestra las primeras líneas de la consola que lanza el Android Studio. Vemos como indica un puerto, en este caso el 7014. Este puerto es el que va a usar el adb de nuestro usuario.

Cuando nos conectamos con un dispositivo, introducimos el número de dispositivo al arrancar el lanzador. Entonces no muestra el número de puerto, pero cada dispositivo tiene asignado un número de puerto único para no colisionar.

Para determinar el número de puerto asignado al dispositivo podemos verlo con el siguiente comando:

ps -aux | grep amm12 | grep adb

En este caso es el alumno amm12 el que está consultando. Esto nos da el resultado de la siguiente imagen.

Donde vemos que tenemos dos adb funcionando, el anterior que es el que se lanzó con el emulador (7014) y el del dispositivo emulador, en este caso el 5004

(Si sólo hemos lanzado en la sesión de trabajo el Android Studio vinculado con el dispositivo externo, no aparecerá el 7014)

Acceder a los ficheros

Una vez que sabemos el puerto el acceso al shell se hace utilizando el puerto asignado al dispositivo (físico o emulador) con el parámetro -P <puerto> en los comandos adb.

Por ejemplo, para acceder al adb shell usaríamos la siguiente sintaxis.

adb -P 5004 shell

Esto nos abre un shell. Una vez dentro del shell  operaremos de la misma forma.

En esta imagen vemos como, desde el terminal de Android Studio, accedemos al sistema de ficheros del dispositivo físico conectado vía wifi. El dispositivo está conectado un una IP:puerto, en este caso se trata del puerto 6004. Este puerto no es el puerto al que tengo que conectar el adb, como vemos en la imagen, tras hacer ps -aux nos dice que el puerto del adb es el 5004. Este es el que conectamos en el comando adb -P

También vemos como una vez dentro del shell podemos tener ya acceso al almacenamiento del dispositivo, vemos las primeras lineas del comando ls.

Copiar ficheros desde el host hacia el dispositivo.

Normalmente con el entorno gráfico del Android Device Monitor podremos utilizar los botones de push y pull para mover ficheros desde el host hasta el dispositivo.

Pero como hemos comentado, en nuestra instalación en matrix no podemos acceder al File Explorer desde el Android Device Monitor, por lo que tenemos que hacerlo de otra forma.

Utilizar ./adb push directamente al directorio de la aplicación en el dispositivo no funciona por lo que hemos comentado de los permisos, y si entramos al dispositivo con ./adb shell entonces no vemos los directorios del host por lo que no podemos copiar los ficheros de él.

Lo que vamos a hacer es utilizar un directorio dentro del dispositivo al que tengamos acceso como paso intermedio donde depositar los ficheros. Este directorio, en el dispositivo, va a ser /sdcard/transfer.

Por tanto los pasos para copiar un fichero al directorio de la aplicación en el dispositivo son.

1) Desde un terminal del host copiar el fichero en el directorio del dispositivo /sdcard/transfer con el siguiente comando.

./adb push <ruta_en_host/fichero> /sdcard/transfer/fichero

2) Entrar en el dispositivo

./adb shell

3) Ejecutar run-as con el nombre del package para posicionarnos en el directorio de la aplicación.

run-as com.example.app

4) Utilizar comandos linux desde ahí para copiar/mover/borrar los ficheros de/hacia el directorio /sdcard/transfer

cp /sdcard/transfer/fichero .

5) Para sacar un fichero al host, primero salimos del dispositivo con exit y luego usamos adb pull

exit  (sale del adb shell)
./adb pull /sdcard/transfer/fichero <ruta_en_host/fichero>