Creare uno splash screen in Android

Gli splash screen sono utilizzati per mostrare all’utente del testo o delle immagini statiche prima ancora del completo caricamento dell’applicazione, soprattutto quando il caricamento richiede alcuni secondi. Senza un buon splash screen l’utente vede semplicemente uno schermo nero: più di 4-5 secondi di nero possono far desistere l’utente dal continuare ad aspettare!

Di solito uno splash screen è semplicemente una immagine a tutto schermo che mostra il nome dell’applicazione, il logo, del testo o, nelle versioni più evolute, una barra di caricamento.

popular_apps_splash_screens

Realizzare uno splash screen in Android è abbastanza semplice.

Creiamo una nuova blank activity, chiamiamola ad esempio “start”:

Screen shot 2015-07-19 at 1.59.12 PM

Possiamo cambiare il colore dello sfondo, aggiungere qualsiasi immagine e/o testo preferiamo.

Impostiamo ora l’activity come activity principale. Sarà la prima ad essere lanciata all’avvio dell’applicazione. A tal fine modifichiamo il manifest.xml in questo modo:


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="gianluca.connect4" >

    <application android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity android:name=".start"
            android:label="@string/app_name" >
            <intent -filter>
                <action android:name="android.intent.action.MAIN"></action>
                <category android:name="android.intent.category.LAUNCHER"></category>
            </intent>
        </activity>
    </application>
</manifest>

Ridefiniamo ora il metodo onCreate() nel sorgente start.java in questo modo:

public class start extends Activity
{
    int timeout = 2000;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start);

        new Handler().postDelayed(new Runnable()
        {
            @Override
            public void run()
            {
                Intent i = new Intent(start.this, main.class);
                startActivity(i);
                finish();
            }
        }, timeout);
    }
}

Praticamente non facciamo altro che creare un nuovo oggetto Runnable (un nuovo thread) e ne posticipiamo l’esecuzione a 2 secondi dall’evento onCreate(). L’intent che andiamo a creare chiamerà l’activity main che nel nostro caso è la prossima schermata dell’applicazione.

Avviando l’applicazione vedremo lo splash screen per 2 secondi, poi verrà lanciata l’activity main.
Il tempo di attesa impostato per lo splash screen può essere sfruttato in vari modi:

  • Caricare oggetti locali particolarmente pesanti (immagini, file audio etc..)
  • Accedere a risorse in rete e scaricare dati da backend remoti
  • Avviare, riavviare, disabilitare device locali (wifi, bluetooth etc..)
  • Nessuna operazione particolare, solo mostrare il nome dell’app, i contatti etc..

AliceDroid – Wifi password recovery tool per Android

Ho creato questa semplice app, la versione Android del tool Alicekeygen. Esattamente come la versione desktop questa applicazione permette il recupero immediato della password wifi per le reti del tipo Alice-xxxxxxxx. I router supportati sono quelli della famiglia con firmware AGPF.

device-2015-07-03-220912

L’applicazione è stata realizzata con AndroidStudio, l’IDE ufficiale Google per lo sviluppo su piattaforma Android. L’algoritmo del tool originale è scritto in C, il porting in Java ha prodotto un algoritmo identico per funzionalità anche se differente nella forma (in Java mancano i puntatori, regole di casting diverse, etc..etc..).

Il tool originale era una semplice applicazione da riga di comando: per recuperare la password occorreva specificare l’SSID della rete, il MAC address della rete stessa e il file dei magic number. Utilizzare questa app è invece molto più semplice e intuitivo: le reti rilevate vengono semplicemente elencate nella schermata principale.

device-2015-07-03-223309

Le reti del tipo “Alice-xxxxxxxx” vengono colorate di rosso ad indicare che sono quelle supportate dall’applicazione. Selezionando una di esse verrà aperta la schermata delle password candidate da provare per quella rete:

device-2015-07-03-223320

 

Per provare una password è sufficiente copiarla nella clipboard (cliccandoci sopra) ed aprire le impostazioni di rete per effettuare l’accesso.

L’app è gratuita e disponibile in Google Play

googleplay

 

 

 

Algoritmo in Java

Questo il porting Java dell’algoritmo originale:

String seriesXserial = "" + String.format("%05d", series) + "X" + String.format("%07d", serialsSet[j]);

/* calcola l'hash SHA256(fixedPadding + serie-X-seriale + MAC) */

try
{
   MessageDigest digest = MessageDigest.getInstance("SHA-256");
   digest.update(fixedPadding, 0, fixedPadding.length);
   digest.update(seriesXserial.getBytes(), 0, seriesXserial.getBytes().length);
   digest.update(macAddr, 0, macAddr.length);
   byte[] hash = digest.digest();

   char[] wpa = new char[24];
   StringBuilder sb = new StringBuilder();
   for (int i = 0; i &lt; 24; i++)
   {
      int s = hash[i] &amp; 0xFF;
      wpa[i] = charset[s];
      sb.append(wpa[i]);
   }

   if (passwordList.contains(sb.toString()) == false)
   {
      passwordList.add(sb.toString());
   }
}
catch(Exception e)
{
    return false;
}

SidBerry – Raspberry Pi SID player

Un SID jukebox realizzato con RasberryPi e il SID chip originale 6581. Il chip è alloggiato in una board custom collegata direttamente ai gpio del Rasberry!

La board può riprodurre qualsiasi SID file, basta caricare i file .sid nella sdcard del Rasberry, avviare il player e collegare all’uscita jack un paio di casse preamplificate o meglio uno stereo.

SID chip

Il SID originale, nelle varianti 6581 e 8580, è controllato caricando i suoi 29 registri interni con i valori opportuni al momento opportuno. La sequenza di byte inviati genera l’effetto o la musica desiderati. Ogni registro è 1 byte ed i registri sono in tutto 29 quindi c’è bisogno di almeno 5 gpio di indirizzo (2^5=32) e 8 gpio di dati per un totale di 13 gpio. Un altro gpio è richiesto per la linea CS del chip (Chip Select).

220px-MOS6581.svg

Fortunatamente il Raspberry ha ben 17 gpio e i 14 richiesti sono perfettamente pilotabili con la libreria WiringPi. Gli altri pin del chip servono per i due condensatori dei filtri interni (CAP_a e CAP_b), alimentazione, linea R/W (che andremo a collegare direttamente a GND, siamo sempre in scrittura), entrata del segnale di clock, linea di reset (collegata sempre a VCC) e uscita audio analogica (AUDIO OUT).

Ecco la configurazione dei registri interni del SID:

SID_registers_fit

Qui per una descrizione più dettagliata del funzionamento interno del chip:

http://www.waitingforfriday.com/index.php/Commodore_SID_6581_Datasheet

Hardware

La board riproduce esattamente le “condizioni al contorno” per il SID chip come se si trovasse alloggiato in un Commodore 64 originale. L’application note originale mostra chiaramente i collegamenti da effettuare e i pochi componenti esterni richiesti (generatore di clock, condensatori e poco altro).

SID_original_schematic_fit

Unica differenza, le linee di indirizzo e dati vengono dirottate direttamente sui gpio del RasberryPi.

NOTA IMPORTANTE!: Il RasberryPi ragiona in logica CMOS a 3.3V mentre il SID chip è TTL a 5V quindi completamente incompatibili a livello di tensioni. Fortunatamente, siccome andiamo unicamente a scrivere nei registri, il RasberryPi dovrà soltanto applicare 3.3v ai capi del chip, più che sufficienti per essere interpretati come livello logico alto dal SID.

20150516_160221

Lo schematico completo:

sidberry

Software

Il grosso del lavoro. Volevo una soluzione completamente stand-alone, senza l’ausilio di player esterni (come ACID64) e quindi ho realizzato un player che emula gran parte di un C64 originale. L’emulatore è necessario in quanto i file .sid sono programmi in linguaggio macchina 6502 e come tali devono essere eseguiti. Il player è scritto in C/C++ e basato sul mio emulatore MOS CPU 6502   più un semplice array di 65535 byte come memoria RAM (il C64 originale ha infatti 64K di RAM). Il player carica il codice programma contenuto nel file .sid nella RAM virtuale più un codice assembly aggiuntivo che ho chiamato micro-player: sostanzialmente si tratta di un programma minimale scritta in linguaggio macchina per CPU 6502 che assolve a due compiti specifici:

  • installare i vettori di reset e interrupt alle locazioni corrette
  • chiamare la play routine del codice sid ad ogni interrupt

Questo perchè il codice che genera la musica in un comune C64 è una funzione chiamata ad intervalli regolari (50 volte al secondo, 50Hz). La chiamata è effettuata per mezzo di un interrupt esterno. In questo modo è possibile avere musica e un qualsiasi altro programma (videogioco ad esempio) in esecuzione nello stesso momento.

Altre componenti sono il parser per i file .sid e la libreria WiringPi per pilotare i GPIO del RaspberryPi.

Questo il layout dell’intero applicativo, a destra è la memoria RAM virtuale 64K

Screen shot 2015-05-17 at 5.41.36 PM

Questo è il codice assembler del micro-player:

// istallazione del vettore di reset (0x0000)
memory[0xFFFD] = 0x00;
memory[0xFFFC] = 0x00;</p>
// istallazione del vettore di interrupt, punta alla play routine (0x0013)
memory[0xFFFF] = 0x00;
memory[0xFFFE] = 0x13;

// codice del micro-player
memory[0x0000] = 0xA9;
memory[0x0001] = atoi(argv[2]); // il registro A viene caricato con il numero della traccia (0-16)

memory[0x0002] = 0x20; // salta alla init-routine nel codice sid
memory[0x0003] = init &amp; 0xFF; // lo addr
memory[0x0004] = (init &gt;&gt; 8) &amp; 0xFF; // hi addr

memory[0x0005] = 0x58; // abilitiamo gli interrupt
memory[0x0006] = 0xEA; // nop
memory[0x0007] = 0x4C; // loop infinito
memory[0x0008] = 0x06;
memory[0x0009] = 0x00;

// Interrupt service routine (ISR)
memory[0x0013] = 0xEA; // nop
memory[0x0014] = 0xEA; // nop
memory[0x0015] = 0xEA; // nop
memory[0x0016] = 0x20; // saltiamo alla play routine
memory[0x0017] = play &amp; 0xFF;
memory[0x0018] = (play &gt;&gt; 8) &amp; 0xFF;
memory[0x0019] = 0xEA; // nop
memory[0x001A] = 0x40; // return from interrupt

Pagina GitHub del progetto: https://github.com/gianlucag/SidBerry