Visualizzazione post con etichetta Nexus S. Mostra tutti i post
Visualizzazione post con etichetta Nexus S. Mostra tutti i post

mercoledì 26 marzo 2014

Cyanogenmod 11 KitKat su Nexus S

Volevo provare ad usare Android Wear ma e' necessario avere un telefono con almeno Android 4.3 (non e' contemplato l'uso di tablet come il Nexus 7 2012) per cui ho deciso di modificare il Nexus S (rimasto fermo ad Android 4.1) per installare la Cyanogenmod 11 Android KitKat 4.4



La procedura prevede di scarica l'immagine Cyanogenmod da questo link e si carica il file cm-11-20131122-UNOFFICIAL-crespo.zip sulla memoria del telefono

Per poter installare il file e' necessario utilizzare la CWM Recovery da questo link ed in particolare il file recovery-clockwork-6.0.4.3-crespo.img (ho provato con la recovery gia' installata ma non ha funzionato)

per installare la CWM si collega il telefono, lo si accende con la combinazione Power + Vol Su e da shell si digita

fastboot flash recovery recovery-clockwork-6.0.4.3-crespo.img

a questo punto si rispenge e si riaccende il telefono sempre con la combinazione Power + Vol Su e si seleziona l'opzione Recovery (Vol Su e Vol Giu'per spostarsi, Power per selezionare), si effettua il wipe dei dati e si installa da zip file cm-11-20131122-UNOFFICIAL-crespo.zip

Le applicazioni Gooogle si scaricano da questo link e si installano con procedura simile (install from zip file)



Alla fine il telefono si riavvia con Android 4.4. E' forse un filino piu' lento della versione 4.1 ma e' assolutamente usabile (unico appunto e' che la tastiera di Unlock del pin della Sim card e' schiacciata ed i tasti non sono cosi' comodi da selezionare)

venerdì 6 dicembre 2013

Speech To Text in Android

La funzione SpeechToText e' compresa nelle API di Android e permette di parlare al microfono del telefono e ricevere in risposta la stringa di quanto e' stato detto. Possono essere quindi implementati dei comandi vocali associati all'evento ed alla stringa pronunciata



Per provare questo sistema e' stata creata, sulla base una semplice applicazione basata sull'esempio a questo link

L'implementazione e' molto semplice ma ci sono un paio di dettagli non trascurabili
1) Non tutti i telefoni sono abilitati al SpeechToText (per esempio il Samsung Next Turbo GT-5570i non ha questa funzione mentre il Nexus S si'...francamente non riesco a capire il motivo della differenza)

2) La funzione Speech To Text ricalca il modo di lavorare di Siri per Apple. L'elaborazione non avviene in locale ma il file audio viene mandato ai server di Google che lo elaborano e rimandano indietro la stringa del risultato


di seguito il codice

MainActivity.java
---------------------------------------------------------
package com.luca.innocenti.texttospeech;

import java.util.ArrayList;

import android.os.Bundle;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.speech.RecognizerIntent;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;


public class MainActivity extends Activity {

protected static final int RESULT_SPEECH = 1;
private TextView testo;
private Button pulsante;

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

testo = (TextView) findViewById(R.id.textView1);
pulsante = (Button) findViewById(R.id.button1);

pulsante.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);

                intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,       RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
                intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, "it-IT");

                try {
                    startActivityForResult(intent, RESULT_SPEECH);
                    testo.setText("-------");
                } catch (ActivityNotFoundException a) {
                    Toast t = Toast.makeText(getApplicationContext(),"Speech to Text non disponibile su questo telefono",
                            Toast.LENGTH_SHORT);
                    t.show();
                }
            }
        });
}


@Override
   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
       super.onActivityResult(requestCode, resultCode, data);
 
       switch (requestCode) {
       case RESULT_SPEECH: {
           if (resultCode == RESULT_OK && null != data) {
 
               ArrayList<String> text = data
                       .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
 
               testo.setText(text.get(0));
           }
           break;
       }
 
       }
   }

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

}
---------------------------------------------------------
activity_main.xml
---------------------------------------------------------
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="28dp"
        android:text="Push to Talk" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button1"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="80dp"
        android:text="--------" />

</RelativeLayout>

---------------------------------------------------------

martedì 10 settembre 2013

Creazione di post automatici su Facebook con RFID su Android (7)



Qui viene descritto come pubblicare su Facebook in modo automatico mediante un telefono abilitato con Rfid. In pratica si tratta dell'unione di diversi post precedenti ed in particolare questo e questo


A differenza di Java, per creare una connessione Http in Android si devono prima settare i permessi nel file Manifest.xml (come al solito le modifiche rispetto ai post precedenti sono in giallo)


Manifest.xml
---------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.test4"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="7"
        android:targetSdkVersion="16" />

    <uses-permission android:name="android.permission.NFC"/>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission  android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.test4.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>


        <activity android:label="@string/event_verify" android:name="verifytagscanact">
            <intent-filter>
                <action android:name="android.nfc.action.TECH_DISCOVERED"/>
            </intent-filter>
            <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/filter_nfc"/>
        </activity>

    </application>

</manifest>
---------------------------------------------------

Nella main le modifiche sono minime e piuttosto simili a Java per l'oggetto HttpConnection. Molto peculiari sono le prime righe dopo OnCreate perche' sono relative ad una gestione specifica di Android (come si puo' leggere meglio spiegato in questo post)

MainActivity.java
---------------------------------------------------
package com.example.test4;

import android.os.Bundle;
import android.app.Activity;
import android.os.StrictMode;
import android.util.Log;
import android.view.Menu;
import android.nfc.Tag;
import android.nfc.NfcAdapter;
import android.nfc.tech.MifareClassic;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.widget.Toast;
import java.math.BigInteger;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class MainActivity extends Activity {

    NfcAdapter adapter;
    PendingIntent pendingIntent;
    IntentFilter writeTagFilters[];
    String[][] techListsArray;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        StrictMode.ThreadPolicy policy = new StrictMode.
        ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        adapter = NfcAdapter.getDefaultAdapter(this);

        pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
        try {
            tagDetected.addDataType("*/*");
        }
        catch (MalformedMimeTypeException e) {
            throw new RuntimeException("fail", e);
        }
        tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
        writeTagFilters = new IntentFilter[] { tagDetected };

        techListsArray = new String[][] { new String[] { MifareClassic.class.getName() } };

    }

    static String bin2hex(byte[] data) {
        return String.format("%0" + (data.length * 2) + "X", new BigInteger(1,data));
    }

    @Override
    protected void onNewIntent(Intent intent){
        //Toast.makeText(getApplicationContext(), "Trovato Tag", Toast.LENGTH_SHORT).show();
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        byte[] tagId = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);


        // trasmissione dati al server
      try {
            URL url = new URL("http://m.msn.unifi.it/luca/examples/rfid_server3.php?rfid="+bin2hex(tag.getId())+"&msg=cellulare");
            HttpURLConnection connection;
            connection = (HttpURLConnection) url.openConnection();

            readStream(connection.getInputStream());
            Toast.makeText(getApplicationContext(), bin2hex(tag.getId()), Toast.LENGTH_SHORT).show();
            } catch (Exception e) {
            e.printStackTrace();
              }
    

    }


 private void readStream(InputStream in) {
            BufferedReader reader = null;
            try {
                reader = new BufferedReader(new InputStreamReader(in));
                String line = "";
                while ((line = reader.readLine()) != null) {
                    System.out.println(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

        }

    public void onPause() {
        super.onPause();
        adapter.disableForegroundDispatch(this);
    }

    public void onResume() {
        super.onResume();
        adapter.enableForegroundDispatch(this, pendingIntent, writeTagFilters, techListsArray);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    
}

---------------------------------------------------
deve essere infine modificato il file /res/values/strings.xml


il file sul server e' identico a quello usato in precedenza

lunedì 9 settembre 2013

Lettura di RFID Mifare con API di Android

In questo post viene descritto come leggere i tag Rfid Mifare Classic (13.56 MHz) disponendo di un telefono con antenna NFC come il Nexus S (attenzione che per leggere



L'interno con l'hardware NFC di un Nexus S (IFixIt)


Si parte da un progetto vuoto (Hello World) e si effettuano le modeste modifiche indicate in giallo nel listato seguente


Per prima cosa si deve modificare il file Manifest per dichiarare l'uso del sensore NFC e si deve dichiare una nuova intent che si apre quando viene passato un tag sotto il lettore

Manifest.xml
------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.test4"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="10"
        android:targetSdkVersion="16" />

    <uses-permission android:name="android.permission.NFC"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.test4.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>


        <activity android:label="@string/event_verify" android:name="verifytagscanact">
            <intent-filter>
                <action android:name="android.nfc.action.TECH_DISCOVERED"/>
            </intent-filter>
            <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/filter_nfc"/>
        </activity>

    </application>

</manifest>
------------------------------------------------
Si deve creare poi una nuova cartella xml nelle risorse e si crea un nuovo file filter_nfc

/xml/filter_nfc.xml
------------------------------------------------
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.NfcA</tech>
        <tech>android.nfc.tech.MifareClassic</tech>
    </tech-list>
</resources>
------------------------------------------------

la Main Activity e' composta da un solo Adapter che apre una nuova intent. A questo punto si apre la funzione OnNewIntent che legge il contenuto del tag

MainActivity.java
------------------------------------------------
package com.example.test4;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.nfc.Tag;
import android.nfc.NfcAdapter;
import android.nfc.tech.MifareClassic;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.util.Log;
import android.widget.Toast;
import java.math.BigInteger;

public class MainActivity extends Activity {

    NfcAdapter adapter;
    PendingIntent pendingIntent;
    IntentFilter writeTagFilters[];
    String[][] techListsArray;

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

        adapter = NfcAdapter.getDefaultAdapter(this);

        pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
        try {
            tagDetected.addDataType("*/*");
        }
        catch (MalformedMimeTypeException e) {
            throw new RuntimeException("fail", e);
        }
        tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
        writeTagFilters = new IntentFilter[] { tagDetected };

        techListsArray = new String[][] { new String[] { MifareClassic.class.getName() } };

    }

    static String bin2hex(byte[] data) {
        return String.format("%0" + (data.length * 2) + "X", new BigInteger(1,data));
    }

    @Override
    protected void onNewIntent(Intent intent){
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        byte[] tagId = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
        Toast.makeText(getApplicationContext(), bin2hex(tag.getId()), Toast.LENGTH_SHORT).show();


    }

    public void onPause() {
        super.onPause();
        adapter.disableForegroundDispatch(this);
    }

    public void onResume() {
        super.onResume();
        adapter.enableForegroundDispatch(this, pendingIntent, writeTagFilters, techListsArray);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    
}


------------------------------------------------


martedì 3 settembre 2013

Rfid su Nexus S

Sono riuscito ad farmi prestare un tag Rfid da 13.56 MHz per testare la capacita' NFC di Nexus S. La storia racconta che la funzione di lettura/scrittura di Rfid era stata implementata all'interno di Android senza documentarla e che e' stata scoperta (e sfruttata) da alcuni utilizzatori




Per la prova ho usato un normale tag di sola lettura da 13.56 Mhz ed il programma NFC Reader, del quale sono disponibili anche i sorgenti su GitHub


L'antenna fa il suo lavoro anche se non e' molto sensibile (il tag va letteralmente strusciato sulla cover del telefono)



domenica 21 aprile 2013

Root su Nexus S I9023 con LInux

Le indicazioni di questo post derivano dai suggerimenti di questo link

Per ottenere i privilegi di root su un Nexus S esistono vari modi ed il piu' semplice e' usare il Nexus Root Toolkit ma questa soluzione funziona solo su Windows mentre io normalmente uso una Debian Box e quindi ho cercato strade che usino anche il sistema del pinguino


Per prima cosa si devono scaricare i file relativi ad una nuova recovery  (TeamWin Recovery)ed ai file per il rooting e si deve modificare il file android.rules

sudo gedit /etc/udev/rules.d/51-android.rules
sudo chmod 0644 /etc/udev/rules.d/51-android.rules---------------------------------------------------
# Google Nexus S
SUBSYSTEMS=="usb", ATTRS{idVendor}=="18d1", ATTRS{idProduct}=="4e21", MODE="0660", OWNER="luca" #Normal nexus s
SUBSYSTEMS=="usb", ATTRS{idVendor}=="18d1", ATTRS{idProduct}=="4e22", MODE="0660", OWNER="luca" #Debug & Recovery nexus s
SUBSYSTEMS=="usb", ATTRS{idVendor}=="18d1", ATTRS{idProduct}=="4e20", MODE="0660", OWNER="luca" #Fastboot nexus s
---------------------------------------------------
al termine dell'editazione si riavvia
/etc/init.d/udev restart

Di seguito si ritiene scontato avere l'SDK Android gia' montato

Sul sito di TeamWin c'e' un comodo motore di ricerca che seleziona il file per il proprio dispositivo..al momento io ho usato openrecovery-twrp-2.5.0.0-crespo.img mentre il rooting ho usato Superuser-3.1.3-arm-signed.zip.

Una volta scaricati i file si inserisce il Superuser sulla SDCard del telefono e si spenge il telefono e lo riavvia in fastboot mode (ovvero accendendo il telefono tenendo premuti Power e Vol +) e da linea di comando si digita

fastboot flash recovery openrecovery-twrp-2.5.9.0-crespo.img


al termine il terminale effettua un reboot
Si spenge di nuovo il terminale e si entra di nuovo in fastboot mode e stavolta si seleziona la voce di menu' Recovery (si usano i tasti del volume per salire e scendere ed il pusante di accensione per la conferma)
Il telefono si riavvia e si entra in Openrecovery
Si clicca su install e si seleziona Superuser-3.1.3-arm-signed.zip.
Si attende ed al nuovo riavvio il terminale e' sbloccato



sad

venerdì 12 aprile 2013

Riportare al firmware originale Nexus S GT-I9023

Mi sono comprato usato un Nexus S GT-I9023.
Il telefono mi e' arrivato con una custom ROM con Android 4.2.2 ed ho deciso riportarlo al firmware originale di Google (un po' perche' mi sembrava un po' scattoso, un po' per avere la sicurezza di compatibilita')

La procedura e' quanto mai semplice:
Si scarica il firmware originale del telefono a questo indirizzo e si scompatta in una macchina con SDK Android installato (in realta' basta avere adb e fastboot)
Si riavvia il telefono in fastboot mode
Si lancia quindi (su Linux) lo script flash-all.sh
Gia' finito...bello avere un Nexus



Il telefono riavviato in Fastboot Mode


Il riavvio dopo aver flashato

Questi sono i messaggi a video, si osservi il tempo totale
----------------------------------------------------------------------
root@debianx40:/home/luca/Downloads/soju-jzo54k# ./flash-all.sh 
sending 'bootloader' (1536 KB)...
OKAY [  0.210s]
writing 'bootloader'...
OKAY [  0.382s]
finished. total time: 0.592s
rebooting into bootloader...
OKAY [  0.001s]
finished. total time: 0.001s
< waiting for device >
sending 'radio' (12288 KB)...
OKAY [  1.641s]
writing 'radio'...
OKAY [  1.903s]
finished. total time: 3.545s
rebooting into bootloader...
OKAY [  0.001s]
finished. total time: 0.001s
archive does not contain 'boot.sig'
archive does not contain 'recovery.sig'
archive does not contain 'system.sig'
--------------------------------------------
Bootloader Version...: I9020XXLC2
Baseband Version.....: I9020XXKI1
Serial Number........: 373342FC9C0400EC
--------------------------------------------
checking product...
OKAY [  0.001s]
checking version-bootloader...
OKAY [  0.001s]
checking version-baseband...
OKAY [  0.001s]
sending 'boot' (3964 KB)...
OKAY [  4.966s]
writing 'boot'...
OKAY [  0.563s]
sending 'recovery' (4308 KB)...
OKAY [  0.768s]
writing 'recovery'...
OKAY [  0.643s]
sending 'system' (337443 KB)...
OKAY [ 75.814s]
writing 'system'...
OKAY [ 42.327s]
erasing 'userdata'...
OKAY [  0.361s]
formatting 'userdata' partition...
Erase successful, but not automatically formatting.
Can't determine partition type.
OKAY [  0.015s]
erasing 'cache'...
OKAY [  1.690s]
formatting 'cache' partition...
Erase successful, but not automatically formatting.
Can't determine partition type.
OKAY [  0.001s]
rebooting...

finished. total time: 127.162s

Geologi

  E so anche espatriare senza praticamente toccare strada asfaltata