Creare un’applicazione in modalità kiosk in Android – 2

Nel precedente articolo abbiamo visto i passaggi necessari alla creazione di un’applicazione Android in modalità kiosk, e cioè di  un’app a tutto schermo, attiva possibilmente 24/7, in cui vengono disabilitate tutte le funzionalità di sistema che permettono di terminare l’app stessa e di tornare alla home. Tuttavia, non avendo accesso di root al dispositivo, non è stato possibile disabilitare i tasti “home” e “app recenti”, se non al costo di qualche hack, come quello utilizzato per mascherare la status bar. In questo modo, un utente tecnicamente più esperto sarà pur sempre in grado di escogitare un sistema per terminare la nostra app in modalità kiosk.

Rootando il device, la prospettiva cambia completamente: saremo in grado di eseguire comandi di sistema prima non accessibili, sia tramite un emulatore di terminale o shell adb, sia dalla nostra app stessa. L’unica limitazione è costituita dal fatto che, per rendere effettive le nuove impostazioni, bisognerà ogni volta riavviare il device. Vediamo dunque quali sono i passaggi necessari a fare del nostro dispositivo android un kiosk a tutto schermo “inespugnabile”.

Passi preliminari

Mentre con il primo metodo abbiamo cercato di gestire tutto dalla nostra app, è necessario sottolineare che l’approccio che useremo adesso necessita dell’intervento attivo del proprietario/amministratore del dispositivo. Dalla nostra applicazione eseguiremo soltanto il comando necessario a nascondere la barra di navigazione di Android. In realtà, via shell dovrebbe essere possibile configurare tutte le impostazioni di cui tra poco illustrerò il metodo manuale, ma non è detto che funzionino in tutti i device e in tutte le versioni di Android.

Andiamo dunque in Impostazioni/Display e selezioniamo Mai. In questo modo il display non andrà mai in timeout, anche se la nostra app non acquisisce mail il wake lock.

Successivamente, spostiamoci in Impostazioni/Sicurezza/Blocco Schermo e selezionialmo Nessuno. Questa impostazione, tuttavia, non impedisce all’utente di bloccare lo schermo manualmente (cfr. il primo articolo per il bypass della pressione breve sul tasto power).
Infine, abilitiamo le Opzioni Sviluppatore andando in Impostazioni/Informazioni sul tablet e cliccando sette volte su Numero build. Un messaggio toast ci avviserà col messaggio “Ora sei uno sviluppatore!“. Torniamo su Impostazioni e spostiamoci su Opzioni sviluppatore, attivando l’opzione “Rimani attivo. Lo schermo non va mai in stand-by sotto carica“, molto utile per i nostri scopi, dato che un’app kiosk viene di solito installata su device perennemente in carica.

Disabilitazione della barra di navigazione e della barra di sistema di Android

Una volta impostato il tablet in modo che non vada main in sleep o in lock screen, disabilitiamo la barra di navigazione di Android.

È importante tenere presente, come già fatto nella prima parte di questa guida, che, una volta resa effettiva questa opzione di sistema, non sarà più possibile uscire dall’app kiosk a tutto schermo, quindi bisogna implementare un meccanismo di terminazione dell’app stessa e informarne l’utente finale!

Disabilitazione della barra di navigazione e della barra di sistema di Android tramite emulatore di terminale

Come anticipato all’inizio di questa guida, una volta rootato il device, sarà molto semplice eseguire comandi di sistema via shell. In questo caso ho scelto di installare Android Terminal Emulator dal Play Store (per chi non avesse un account, basta abilitare da Impostazioni/Sicurezza il flag Origini Sconosciute e scaricare l’apk direttamente dal repository github dello sviluppatore, Jack Palevich). Terminata l’installazione, avviamo il terminale e digitiamo i seguenti comandi:

su
pm enable com.android.systemui
reboot

Al riavvio, tanto la barra di navigazione, quanto quella di stato non appariranno e saranno, di conseguenza, inutilizzabili. Per riabilitare basterà riaprire il terminale e digitare:

su
pm disable com.android.systemui
reboot

Disabilitazione della barra di navigazione e della barra di sistema di Android da programma

Possiamo dare i comandi appena illustrati direttamente dalla nostra app, magari al suo avvio, avvisando poi l’utente di eseguire il reboot tramite un popup o un avviso toast:

public void disableSystemUi()
{

    Thread thread = new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                Process process = Runtime.getRuntime().exec("su");
                DataOutputStream os = new DataOutputStream(process.getOutputStream());
                os.writeBytes("pm disable com.android.systemui\n");
                os.flush();
                os.writeBytes("exit\n");
                os.flush();
                process.waitFor();
                //////////////////////////////////////
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
    thread.start();
}

Di conseguenza, nell’evento di uscita della nostra app, che avremo sicuramente ricordato di implementare per non incorrere nelle ire del nostro utente finale, richiameremo il seguente metodo:

public void enableSystemUi()  {

    Thread thread = new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                Process process = Runtime.getRuntime().exec("su");
                DataOutputStream os = new DataOutputStream(process.getOutputStream());
                os.writeBytes("pm enable com.android.systemui\n");
                os.flush();
                os.writeBytes("exit\n");
                os.flush();
                process.waitFor();
                //////////////////////////////////////
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
    thread.start();
}

Anche questa volta, ricordiamo di riavviare.

Conclusioni

Abbiamo visto come impostare manualmente un tablet rootato perché non vada mai in sospensione o in blocco schermo, e abbiamo visto come eseguire i comandi necessari a nascondere la status bar a la navigation bar di Android, operazione imprescindibile per un’app in modalità kiosk full screen. Abbiamo anche visto i limiti di questo secondo approccio  e quali trappole nasconde. Volendo, si possono mescolare le metodologie impiegato in questo e nel precedente articolo, ma ciò che raccomando vivamente è di non disabilitare le barre di sistema e al contempo bypassare i tasti power e volume, ma soprattutto di non implementare anche il meccanismo di risveglio automatico della main activity, altrimenti non ci resterà che resettare il device alle impostazioni di fabbrica o disinstallare l’app via pc tramite adb.