Archive for the ‘Andoid’ Category.

Realizzare un Parser XML con ANDROID

Ciao,
vi riporto questo utilissimo tutorial ANDROID relativo al parsing XML con android. E' utilissimo anche nel caso in cui vogliate realizzare un vostro RSS reader personalizzato.


Fonte: http://www.anddev.it/index.php?topic=180.0

Salve a tutti,
vorrei mostrarvi come è possibile fare il parsing di un documento XML tramite il Document Object Model.

A differenza del parsing tramite SAX, che legge il documento e fa scattare degli eventi (metodi dell'handler) ad ogni tag incontrato, il parsing tramite DOM legge la struttura ad albero di un XML. A discrezione dell'utente (programmatore) la struttura letta potrà essere direttamente interrogata (nel codice si capisce meglio di cosa si tratta).

Per documenti XML relativamente semplici, questo tipo di parsing risulta sicuramente più immediato e semplice da implementare. 
Tuttavia, per strutture con albero xml troppo profondo, questo metodo potrebbe risultare scomodo, e sarebbe quindi meglio optare per il sax parsing.

Vorrei osservare, che queste operazioni (DOM e SAX parsing) sono inerenti a Java più che ad android, ma visto che molte persone si avvicinano a questo fantastico linguaggio grazie ad android, ritengo giusto condividere questo tipo di informazioni su questa board.

Vediamo il documento che vogliamo analizzare:
 

Codice (XML): [Seleziona]

<?xml version="1.0" encoding="utf-8"?>
<messages>
        <note id="p501">
          <to>Carlo</to>
          <from>Luca</from>
          <heading>Promemoria</heading>
          <body>Ricordati gli appunti!</body>
        </note>
        
        <note id="p502">
          <to>Luca</to>
          <from>Carlo</from>
          <heading>Re: Promemoria</heading>
          <body>Ok, mi ricorderò!</body>
        </note>
</messages>


Creiamo una classe che rappresenta una nota:
 

Codice (Java): [Seleziona]

public class MyNote {
        private String body;
        private String heading;
        private String from;
        private String to;
        private String id;
        
        public String getId() {
                return id;
        }

        public void setId(String id) {
                this.id = id;
        }

        public String getFrom() {
                return from;
        }

        public void setFrom(String from) {
                this.from = from;
        }

        public String getTo() {
                return to;
        }

        public void setTo(String to) {
                this.to = to;
        }

        public String getHeading() {
                return heading;
        }

        public void setHeading(String heading) {
                this.heading = heading;
        }

        public String getBody() {
                return body;
        }

        public void setBody(String body) {
                this.body = body;
        }

        @Override
        public String toString() {
                return "MyNote [id=" + id  + ", from=" + from + ", to=" + to +", heading="
                                + heading + ",body=" + body+ "]";
        }
}


Creiamo una classe che gestisce il parsing: (potremmo utilizzare un metodo, ma in questo modo rendiamo più pulito e riutilizzabile il tutto)
Se eliminate i metodi di debug e le chiamate a questi metodi, vi accorgerete della semplicità di questo tipo di parsing(nel caso vi sembrasse troppo lungo :P).

 

Codice (Java): [Seleziona]

public class MyParser {
        static void vDebug(String debugString){         //metodi di convenienza
                Log.v("DomParsing", debugString+"\n");
        }
        static void eDebug(String debugString){
                Log.e("DomParsing", debugString+"\n");
        }
        
        ArrayList<MyNote> parsedData=new ArrayList<MyNote>(); //struttura dati che immagazzinerà i dati letti
        public ArrayList<MyNote> getParsedData() {  //metodo di accesso alla struttura dati
                return parsedData;
        }

    public void parseXml(String xmlUrl){
                
                Document doc;
                try {
                                                
                        doc=DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new URL(xmlUrl).openStream());
                        //Costruiamo il nostro documento a partire dallo stream dati fornito dall'URL
                        Element root=doc.getDocumentElement();
                        //Elemento(nodo) radice del documento
                        
                        vDebug("Root element :" + root.getNodeName());
                        vDebug("");
                        
                        //NodeList notes=root.getElementsByTagName("note"); //potremmo direttamente prendere gli elementi note
                        NodeList notes=root.getChildNodes(); 
                        //ma prediamo tutti i "figli" diretti di root. Utile se non avessimo solo "note" come figli di root
                        
                        for(int i=0;i<notes.getLength();i++){//per ogni
                                Node c= notes.item(i);//nodo
                                
                                
                                
                                if(c.getNodeType()==Node.ELEMENT_NODE){//controlliamo se questo è un nodo elemento (un tag)
                                        //se avessimo usato root.getElementsByTagName("note") questo controllo
                                        //non sarebbe stato necessario
                                        
                                        MyNote newNote=new MyNote(); //costruiamo un oggetto MyNote dove andremo a salvare i dati
                                        
                                        Element note=(Element)c; //cast da nodo a Elemento
                                        
                                        //non controlliamo if(note.getNodeName().equals("note"))  in quanto sappiamo di avere solo "note" come childs
                                        
                                        String id=note.getAttribute("id"); // lettura attributo
                                        vDebug("_Attributo note id:"+id);
                                        vDebug("");
                                        
                                        newNote.setId(id); // settiamo l'id del nostro oggetto MyNote
                                        
                                        NodeList noteDetails=c.getChildNodes();  //per ogni nota abbiamo i vari dettagli 
                                        for(int j=0;j<noteDetails.getLength();j++){
                                                Node c1=noteDetails.item(j);
                                                
                                                        if(c1.getNodeType()==Node.ELEMENT_NODE){ //anche in questo caso controlliamo se si tratta di tag
                                                                Element detail=(Element)c1; //cast
                                                                String nodeName=detail.getNodeName(); //leggo il nome del tag
                                                                String nodeValue=detail.getFirstChild().getNodeValue();//leggo il testo in esso contenuto
                                                                vDebug("______Dettaglio:"+nodeName);
                                                                vDebug("______Contenuto Dettaglio:"+nodeValue);
                                                                vDebug("");
                                                                
                                                                //a dipendenza del nome del nodo (del dettaglio) settiamo il relativo valore nell'oggetto
                                                                if(nodeName.equals("from"))
                                                                        newNote.setFrom(nodeValue);
                                                                
                                                                if(nodeName.equals("to"))
                                                                        newNote.setTo(nodeValue);
                                                                
                                                                if(nodeName.equals("heading"))
                                                                        newNote.setHeading(nodeValue);
                                                                
                                                                if(nodeName.equals("body"))
                                                                        newNote.setBody(nodeValue);
                                                                
                                                                
                                                        }
                                                
                                        }
                                        vDebug("");
                                
                                        parsedData.add(newNote); //aggiungiamo il nostro oggetto all'arraylist
                                }
                                                                                                
                        }                       
                //gestione eccezioni
                } catch (SAXException e) {
                        eDebug(e.toString());
                } catch (IOException e) {
                        eDebug(e.toString());
                } catch (ParserConfigurationException e) {
                        eDebug(e.toString());
                } catch (FactoryConfigurationError e) {
                        eDebug(e.toString());
                } 
                
        }
    
}


Aggiungiamo questa permission al manifest:
 

Codice (XML): [Seleziona]

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
Usiamo ciò che abbiamo creato:

Codice (Java): [Seleziona]

public class DomParsing extends Activity {
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        String xmlUrl="http://www.xxxx.xx/myfiles/messages.xml";
        MyParser parser=new MyParser(); //otteniamo un istanza del nostro parser 
        parser.parseXml(xmlUrl);//usiamo il parser
        ((TextView)findViewById(R.id.result)).setText(parser.getParsedData().toString()); 
        //per semplicità stampiamo il toString (che richiamerà i toString di MyNote) dell'arraylist risultato dal parsing
    }   
}

Concatenare due files ( anche mp3 ) su ANDROID

A seguire una utile funzione in grado di concatenare due files ( presenti preferibilmente nella vostra /mnt/sdcard ).

La concatenazione ha effetto anche se utilizzata con files MP3.
 

 

public void concatFiles(String file1,String file2,String out){
    	FileInputStream fistream1;
		try {
			fistream1 = new FileInputStream(file1);
			FileInputStream fistream2 = new FileInputStream(file2);//second source file
	        SequenceInputStream sistream = new SequenceInputStream(fistream1, fistream2);
 
	        FileOutputStream fostream = new FileOutputStream(out);//destinationfile
 
	        int temp;
 
	        while( ( temp = sistream.read() ) != -1)
	        {
	            // System.out.print( (char) temp ); // to print at DOS prompt
	            fostream.write(temp);   // to write to file
	        }
	        fostream.close();
	        sistream.close();
	        fistream1.close();
	        fistream2.close();
		}catch(Exception e){
 
		}
}

Poichè è stato utilizzato solo JAVA la funzione è utilizzabile anche in software non ANDROID ( ma semplicemente JAVA ).

Copiare i propri assets ANDROID nella sdcard

A seguire vi allego una utilissima funzione in grado di spostare gli assets della vostra applicazione ANDROID verso la cartella relativa alla card sd ( anche se non avete sul vostro dispositivo una SD ricordate che la cartella /mnt/sdcard – o simile – sarà presente comunque ).

Questa operazione è essenziale nel caso in cui voleste modificare / rendere disponibili all'utilizzatore della vostra app i file sonori / grafici della stessa.

La stessa funzione potrebbe essere utilizzata per creare un dump del proprio db locale, leggibile poi mediante un semplice accesso alla /mnt/sdcard.

private void copyAssets() {
		File folder = new File(Environment.getExternalStorageDirectory() + &quot;/DIRTEMP&quot;);
		boolean success = true;
		if (!folder.exists()) {
		    success = folder.mkdir();
		}
		if (success) {
			AssetManager assetManager = getAssets();
		    String[] files = null;
		    try {
		        files = assetManager.list(&quot;&quot;);
		    } catch (IOException e) {
		        String err=&quot;&quot;;
		    }
		    for(String filename : files) {
		        InputStream in = null;
		        OutputStream out = null;
		        try {
		          in = assetManager.open(filename);
		          out = new FileOutputStream(Environment.getExternalStorageDirectory() + "/DIRTEMP/" + filename);
		          copyFile(in, out);
		          in.close();
		          in = null;
		          out.flush();
		          out.close();
		          out = null;
		        } catch(IOException e) {
 
		        }       
		    }
		} else {
		    // Do something else on failure 
		}
 
	}

Fatene buon uso!


Connettere una APP Android ad un database mysql remoto

Una delle soluzioni più semplici ed utilizzate e quelle di costruire un "service in the middle". In pratica un servizio che si ponga nel mezzo e si occupi di serializzare/deserializzare i dati sa caricare/scaricare.

Ipotizziamo di avere sul server MYSQL remoto la seguente tabella:


CREATE TABLE `people` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`name` VARCHAR( 100 ) NOT NULL ,
`sex` BOOL NOT NULL DEFAULT '1',
`birthyear` INT NOT NULL
)

In PHP potremmo serializzare i risultati di una query nel formato JSON in questo modo:


  1. <?php
  2. mysql_connect("host","username","password");
  3. mysql_select_db("PeopleData");

  4. $q=mysql_query("SELECT * FROM people WHERE birthyear>'".$_REQUEST['year']."'");
  5. while($e=mysql_fetch_assoc($q))
  6.         $output[]=$e;

  7. print(json_encode($output));

  8. mysql_close();
  9. ?>

Maggiori informazioni sul formato JSON qui: http://it.wikipedia.org/wiki/JSON

Il passo successivo sarà quello di lavorare ( ad esempio ) con i dati "serializzati" JSON nel modo seguente:

  1. String result = "";
  2. //the year data to send
  3. ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
  4. nameValuePairs.add(new BasicNameValuePair("year","1980"));

  5. //http post
  6. try{
  7.         HttpClient httpclient = new DefaultHttpClient();
  8.         HttpPost httppost = new HttpPost("http://example.com/getAllPeopleBornAfter.php");
  9.         httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
  10.         HttpResponse response = httpclient.execute(httppost);
  11.         HttpEntity entity = response.getEntity();
  12.         InputStream is = entity.getContent();
  13. }catch(Exception e){
  14.         Log.e("log_tag""Error in http connection "+e.toString());
  15. }
  16. //convert response to string
  17. try{
  18.         BufferedReader reader = new BufferedReader(newInputStreamReader(is,"iso-8859-1"),8);
  19.         StringBuilder sb = new StringBuilder();
  20.         String line = null;
  21.         while ((line = reader.readLine()) != null) {
  22.                 sb.append(line + "\n");
  23.         }
  24.         is.close();

  25.         result=sb.toString();
  26. }catch(Exception e){
  27.         Log.e("log_tag""Error converting result "+e.toString());
  28. }

  29. //parse json data
  30. try{
  31.         JSONArray jArray = new JSONArray(result);
  32.         for(int i=0;i<jArray.length();i++){
  33.                 JSONObject json_data = jArray.getJSONObject(i);
  34.                 Log.i("log_tag","id: "+json_data.getInt("id")+
  35.                         ", name: "+json_data.getString("name")+
  36.                         ", sex: "+json_data.getInt("sex")+
  37.                         ", birthyear: "+json_data.getInt("birthyear")
  38.                 );
  39.         }
  40. }
  41. }catch(JSONException e){
  42.         Log.e("log_tag""Error parsing data "+e.toString());
  43. }


Ovviamente se si vuole gestire la connessione in HTTPS la cosa è fattibile.

 

 

Gestire l’update della GUI di un APP Android mediante un Handler

Un problema molto ricorrente con cui si scontrano i novelli sviluppatori ANDROID è quello di dover gestire l'update della propria User Interface da una Activity in maniera asincrona ( senza cioè l'intervento di un evento da parte dell'utente ).

Per risolvere problematiche del genere io consiglierei l'utilizzo di un Handler.

Android ci mette a disposizione un meccanismo particolare per scambiare messaggi tra thread diversi a prescindere del tipo di thread, cioè worker o main thread.

Il modello prevede un insieme di classi definite nel package android.os che implementa un meccanismo che comprende una coda di messaggi condivisa dal main e worker thread. Il worker thread in questo caso 'produce' i messaggi e il main thread li 'consuma'. Questi messaggi possono tradursi in azioni, cioè il worker thread invia un messaggio che indica di settare un valore ad un controllo grafico ed il main thread lo esegue. 

Questo potrebbe essere un esempio di Handler:


private Handler textChangeHandler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
         time++;
         TextView secondi= (TextView) findViewById(R.id.secondi);
                secondi.setText("Secondi: " + time);
        }
    };

E questo potrebbe essere un modo di richiamarlo ( dalla funzione onCreate della propria Activity ):

    @Override
    public void onCreate(Bundle savedInstanceState) { 
       
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new_game);
        
        
        task = new TimerTask() {
            public void run() {
            textChangeHandler.sendEmptyMessage(0);
            }
        };
        timer.scheduleAtFixedRate(task,0,1000);
        …
    }

Come è possibile vedere il timer è stato schedulato per partire ogni secondo.

Molto semplice direi.

Alla prossima!

 

Sviluppare una APP Android con Eclipse Juno è davvero divertente

Devo ricredermi: programmare ANDROID con Eclipse non è mai stato così facile e piacevole.

A patto però di avere a disposizione un terminale fisico su cui fare il debug della propria APP. Questo è sicuro ( l'emulatore infatti risulta davvero ancora troppo lento per consentire un debug agevole ).

Nel mio caso ho utilizzato il mio Samsung Galaxy S2 e devo dire che il risultato è stato davvero piacevole: tempi di upload e debug brevissimi.

E' stato sufficiente installare i driver del telefono ( nel mio caso ho installato direttamente KIES ), mettere il cellulare in modalità DEBUG ( menù sviluppo -> Modalità DEBUG ) e subito è stato riconosciuto da ECLIPSE come dispositivo disponibile.

Come non parlare della nuova versione di Eclipse ( JUNO )?

La stessa è scaricabile qui: http://www.eclipse.org/downloads/

Davvero fenomenale. Tutti gli aspetti più noiosi sono ora programmabili in maniera visuale e con la massima comodità ( ovvio che per fare qualcosa di una seppur minima complessità serve avere una buona infarinatura dell'ANDROID SDK, ma ciò è normalissimo ).





Ritengo che gli appassionati di JAVA possano davvero divertirsi con strumenti tanto potenti quanto versatili.

Nel mio caso mi sono dilettato a creare il gioco seguente (se vi capita dategli un'occhiata e magari dategli un voto):



Considerando che per lo sviluppo dello stesso ho impiegato qualche ora, devo dire che i risultati sono davvero entusiasmanti.   

Gli enigmi del Dr Magnus e del suo gatto Ciccio

Oggi vorrei pubblicizzare un gioco per Android di mia creazione.

Il gioco è nato per scherzo ma presenta davvero parecchi punti di interesse. E poi credo sia molto simpatico.

Riporto la descrizione da Google Play :)


Una pietra miliare nella storia dei quiz presentati da gatti. Ciccio è una star.


Il DrMagnus ( ed il suo gatto Ciccio ) ti hanno appena sfidato. Riuscirai ad arrivare alla fine di questo esilarante QUIZ gattoassistito? Ciccio è poliedrico, divertente, agguerrito.

Lasciati cullare da un accompagnamento d'autore basato su pezzi di musica classica suonati allegramente dal vivo ( da mia moglie ) e goditi i curati effetti sonori felini degni di un film di Spielberg.

Tutti ne parlano:

"Da un senso compiuto a ciò che ho creato"
Dio su "Gli enigmi del DrMagnus e del suo gatto Ciccio"

"Ciccio è un ANIMALE da palcoscenico"
Il commissario Rex su "Gli enigmi del DrMagnus e del suo gatto Ciccio"

"Amo Ciccio"
Charlize Theron ( o qualcuna che le assomigliava ) su "Gli enigmi del DrMagnus e del suo gatto Ciccio"

"Uno dei migliori giochi a QUIZ che abbia mai giocato da quando sono nato"
Mio figlio di 2 anni e mezzo su "Gli enigmi del DrMagnus e del suo gatto Ciccio"

"Avrei voluto presentarli io ma fortunatamente sono morto prima"
Mike Bongiorno su "Gli enigmi del DrMagnus e del suo gatto Ciccio"

"Adesso sarai costretto ad ucciderlo"
Gli (a)Mici del mio gatto dopo aver provato una beta versione de "Gli enigmi del DrMagnus e del suo gatto Ciccio"

"Chiamate il mio avvocato"
Il mio gatto su "Gli enigmi del DrMagnus e del suo gatto Ciccio"

Link Google Play: Qui

Samsung Galaxy S II: oggi l’aggiornamento a Ice Cream Sandwich

A differenza di altri paesi, i possessori italiani del Samsung Galaxy S2 sono stati destinati ad aspettare più tempo per poter vedere l’aggiornamento del sistema operativo made in Google. L’attesa, però, è finalmente finita! Durante la giornata di oggi la società sudcoreana rilascerà ufficialmente l’aggiornamento Ice Cream Sandwich.

La notizia è stata divulgata da Samsung Italia attraverso Twitter. Ancora non è chiaro precisamente quali saranno i dispositivi a cui l’aggiornamento è rivolto. Ma, quasi sicuramente, sarà possibile effettuare l’upgrade esclusivamente su Samsung Galaxy S2 no-brand italiani. Non si hanno informazioni circa la validità dello stesso anche per le versioni brandizzate dai vari operatori. Tra qualche ora ne sapremo di più.

Fonte:http://www.chimerarevo.com/2012/04/23/samsung-galaxy-s-ii-laggiornamento-ice-cream-sandwich-sara-disponibile-entro-oggi-in-italia/

Samsung Galaxy S II: a quando Android 4?

Il problema con gli aggiornamenti Android è che questi vengono scaglionati nel tempo in modo così lento che spesso gli utenti diventano estremamente impazienti e passano settimane prima di poter aggiornare il proprio telefono.

Dopo che Google rilascia il codice sorgente ai vari produttori, tocca a questi ultimi realizzare l’aggiornamento definitivo del sistema, personalizzandolo sul proprio hardware, e questa non sempre è una cosa semplice, soprattutto se bisogna riprogettare un’interfaccia grafica diversa rispetto a quella di Android, proprio come accade, ad esempio, nel caso del Galaxy S II.
Anche quando un aggiornamento viene ultimato dal produttore, il suo iter non termina: deve essere sottoposto ai test dei vari operatori telefonici per verificare che non vi siano problemi tra il nuovo firmware e le loro reti. Ma, a questo punto, viene proprio da chiedersi quando quest’atteso aggiornamento sarà disponibile per gli utenti finali.

Telefoni SIM free
Samsung ha confermato che il Galaxy S II riceverà l’aggiornamento ad Android 4.0 Ice Cream Sandwich a partire da questa settimana (presumibilmente a partire dal 19 marzo). L’aggiornamento, secondo quanto dichiarato dalla stessa Samsung, sarà reso disponibile inizialmente in Europa, inclusa Polonia, Ungheria, Svezia e Corea, per poi essere gradualmente estesa agli altri mercati.

Telefoni distribuiti dagli operatori
Tutti gli operatori telefonici hanno ricevuto l’aggiornamento da Samsung e sono al lavoro per testare il nuovo firmware sulle proprie reti. Al momento nessuno ha saputo (o voluto) dire quando verrà rilasciato l’aggiornamento ai propri clienti. Quasi tutti si sono limitati a dichiarare che stanno lavorando sull’aggiornamento e che questo sarà rilasciato al più presto possibile.

Fonte: http://www.mobilejournal.net/android/samsung-galaxy-s-ii-a-quando-android-4-9984

Android 4.0 e Galaxy S II: disponibile una prima ROM beta

Samsung sta lavorando alacremente per poter portare Android 4 Ice Cream Sandwich sullo smartphone che ha fatto furore nel 2011, ovvero il Galaxy S II. Di tanto in tanto trapela qualche informazione o, come in questo caso, qualche ROM in versione beta…

La ROM che è possibile scaricare adesso da questo indirizzo è una beta, che lascia però vedere come sarà la versione definitiva di Ice Cream Sandwich per il Galaxy S II, per il cui rilascio non sono state ancora fornite date ufficiali.


La ROM è stata aggiornata il 31 gennaio, quindi è piuttosto recente, ed è basata sulla versione 4.0.3 di Android. Diverse modifiche sono state apportate rispetto alle precedenti: adesso quando si effettua lo scrolling c’è un effetto simil-3D, la stabilità è stata migliorata e l’aspetto e le funzioni pare siano molto simili a quelle della release attesa al debutto ufficiale. Migliorate anche le prestazioni, il riconoscimento facciale per lo sblocco del telefono e la gestione dei task.

Il miglioramento più gradito è però sicuramente quello relativo all’autonomia del telefono: la durata della batteria adesso è notevolmente superiore e questo, unito alla buona stabilità della ROM ne permette l’utilizzo anche se il Galaxy S II fosse il nostro unico telefono. 

Tutte le informazioni presenti su questo articolo sono protette dalla licenza CC Attribution-ShareAlike.