Autore Topic: Scrittura su NFC  (Letto 3448 volte)

Offline Lomba1986

  • Utente normale
  • ***
  • Post: 173
  • Respect: +1
    • Mostra profilo
Scrittura su NFC
« il: 03 Agosto 2012, 10:15:17 CEST »
0
Ciao a tutti...argomento nuovo e io che dimostro la mia incapacità...

Sto cercando di fare un banale programma che scriva su NFC un tag...
Ho spulciato vari esempi e quello che segue è il mio codice:

Codice (Java): [Seleziona]
package gulliver.provanfc;

import java.io.IOException;
import java.nio.charset.Charset;

import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.nfc.tech.NdefFormatable;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.view.View;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class LettoreNfc extends Activity
{
        private TextView testo;
        private Button button;
        private EditText edit;
       
        NfcAdapter mNfcAdapter;
        PendingIntent mNfcPendingIntent;       
        IntentFilter[] filters;
        IntentFilter tagDetected;
       
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_lettore_nfc);
       
        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
        testo = (TextView)findViewById(R.id.testo);
        button = (Button)findViewById(R.id.button1);
        edit = (EditText)findViewById(R.id.editText1);
       
        mNfcPendingIntent = PendingIntent.getActivity(this, 0,
                new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
     
        tagDetected = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
        filters = new IntentFilter[] { tagDetected };
       
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                //prova trasmissione dati NFC
                trasmetti();
            }
        });
       
        resolveIntent(getIntent());
        Log.i("LettoreNfc","fine OnCreate");
    }
   
   

    //funzione trasmissione dati
    public void trasmetti()
    {
       
        Tag tag = this.getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
        if(writeTag(getNoteAsNdef(),tag))
                Log.i("LettoreNfc","Trasmissione ok");
        else
                Log.i("LettoreNfc","Trasmissione fallita");
    }
   
    private NdefMessage getNoteAsNdef() {
        byte[] textBytes = edit.getText().toString().getBytes();
        NdefRecord textRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA, "text/plain".getBytes(),
                new byte[] {}, textBytes);
        return new NdefMessage(new NdefRecord[] { textRecord });
    }
   
    /*
    * Writes an NdefMessage to a NFC tag
    */

    public static boolean writeTag(NdefMessage message, Tag tag) {
       
        Log.i("LettoreNfc",message.getRecords()[0].toString());
        int size = message.toByteArray().length;
        try {
            Ndef ndef = Ndef.get(tag);
            if (ndef != null) {
                ndef.connect();
                if (!ndef.isWritable()) {
                    return false;
                }
                if (ndef.getMaxSize() < size) {
                    return false;
                }
                ndef.writeNdefMessage(message);
                return true;
            }
            else
            {
                NdefFormatable format = NdefFormatable.get(tag);
                if (format != null) {
                    try {
                        format.connect();
                        format.format(message);
                        return true;
                    } catch (IOException e) {
                        return false;
                    }
                } else {
                    return false;
                }
            }
        } catch (Exception e) {
            return false;
        }
    }

   
    @Override
    protected void onNewIntent(Intent intent)
    {
        Log.i("LettoreNfc","onNewIntent");
        setIntent(intent);
        resolveIntent(intent);
    }
   
    void resolveIntent(Intent intent)
    {
        // Parse the intent
        String action = intent.getAction();
        String tmp="0";
        String tmp2="0";
        Log.i("LettoreNfc 2",action);
        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action))
        {
            Log.i("LettoreNfc","dentro if resolveIntent");
                // When a tag is discovered we send it to the service to be save. We
            // include a PendingIntent for the service to call back onto. This
            // will cause this activity to be restarted with onNewIntent(). At
            // that time we read it from the database and view it.
            Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
            NdefMessage[] msgs;
            if (rawMsgs != null) {
                msgs = new NdefMessage[rawMsgs.length];
                for (int i = 0; i < rawMsgs.length; i++) {
                    msgs[i] = (NdefMessage) rawMsgs[i];
                    tmp2 = msgs[0].getRecords()[0].getPayload().toString();
                }
            } else {
                // Unknown tag type
                byte[] empty = new byte[] {};
                NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, empty, empty);
                NdefMessage msg = new NdefMessage(new NdefRecord[] {record});
                msgs = new NdefMessage[] {msg};
                //tentativo estrapolazione stringa dati
                tmp = msg.getRecords()[0].getPayload().toString();
            }
            // Setup the views
           
            Log.i("LettoreNfc tmp",tmp);
            Log.i("LettoreNfc tmp2",tmp2);
        }
        else
        {
            Log.i("LettoreNfc", "Unknown intent " + intent);
            finish();
            return;
        }
    }
}

Ora...il problema è che non scrive... o meglio il tag arriva (ho fatto una prova e la tipologia del tag sembrerebbe cambiare) ma non riesco a capire come mai non riesco a scrivere correttamente il tag (mettendoci una semplice stringa di testo). So sicuro che non funziona perchè nel momento in cui passo il telefono sulla card, e la mia applicazione è deinstallata il telefono mi avvisa che un nuovo tag è stato trovato ed è del tipo "text/plain" ma non mi visualizza il contenuto... Cosa che invece faceva quando un collega gli aveva caricato un tag lui...

Ciao a tutti e grazie
Non esistono problemi, ma solo soluzioni...

Offline Lomba1986

  • Utente normale
  • ***
  • Post: 173
  • Respect: +1
    • Mostra profilo
Re:Scrittura su NFC
« Risposta #1 il: 03 Agosto 2012, 16:33:02 CEST »
0
Ho rilsolto  8-)
Alla facciaccia dell'esempio che ho postato!!!

Vi allego di seguito il nuovo codice funzionante..magari è d'aiuto per vedere come funziona...è estrapolato da un esempio trovato in rete, non è farina del mio sacco (a parte i commenti  :-P)
Però è utile per capire...

Codice (Java): [Seleziona]
public class MainActivity extends Activity {

        NfcAdapter adapter;
        PendingIntent pendingIntent;
        IntentFilter writeTagFilters[], resumeFilter[];
        boolean writeMode;
        Tag mytag;
        Context ctx;

        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.main);

                ctx=this; //contesto dell'activity
               
                Button btnWrite = (Button) findViewById(R.id.button);
                final TextView message = (TextView)findViewById(R.id.edit_message);

                btnWrite.setOnClickListener(new View.OnClickListener()
                {
                        public void onClick(View v) {
                                try {
                                        if(mytag==null){
                                                Toast.makeText(ctx, ctx.getString(R.string.error_detected), Toast.LENGTH_LONG ).show();
                                        }else{
                                                write(message.getText().toString(),mytag);
                                                Toast.makeText(ctx, ctx.getString(R.string.ok_writing), Toast.LENGTH_LONG ).show();
                                        }
                                } catch (IOException e) {
                                        Toast.makeText(ctx, ctx.getString(R.string.error_writing), Toast.LENGTH_LONG ).show();
                                        e.printStackTrace();
                                } catch (FormatException e) {
                                        Toast.makeText(ctx, ctx.getString(R.string.error_writing) , Toast.LENGTH_LONG ).show();
                                        e.printStackTrace();
                                }
                        }
                });
               
                //NfcAdapter per registrare l'activity per avere la priorità per gestire i tag trovati
                adapter = NfcAdapter.getDefaultAdapter(this);
               
                //PendingIntent per l'abilitazione/disabilitazione al foregroundDispatch
                pendingIntent = PendingIntent.getActivity(this, 0, new Intent(
                                                                                        this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
               
                //annuncio che l'applicazione può lavorare con i tag NFC
                //associando un determinato filtro
               
                //modo generico e devo associargli una tipologia
                IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
                try
                {
                        tagDetected.addDataType("*/*");
                }
                catch (MalformedMimeTypeException e)
                {
                        e.printStackTrace();
                }
                resumeFilter = new IntentFilter[] { tagDetected };
               
                //modo alternativo: non necessita di specificare il tipo di data, ma è più restrittivo
                tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
               
                tagDetected.addCategory(Intent.CATEGORY_DEFAULT);//aggiunta della categoria
                writeTagFilters = new IntentFilter[] { tagDetected };
               
                /* Posso associare più filtri all'intent per poi gestirli in maniera differente
                 * quando essi si verificano di volta in volta; devono essere filtri differenti
                 */

               
        }
       
        private void write(String text, Tag tag) throws IOException, FormatException
        {
                //creazione del NdefRecord da spedire
                NdefRecord[] records = { createRecord(text) };
                //creazione del messaggio da inviare
                NdefMessage  message = new NdefMessage(records);
               
                // Get an instance of Ndef for the tag.
                Ndef ndef = Ndef.get(tag);
                // Enable I/O
                ndef.connect();
                // Write the message
                ndef.writeNdefMessage(message);
                // Close the connection
                ndef.close();
        }
       
        //costruzione del record da scrivere nella card
        private NdefRecord createRecord(String text) throws UnsupportedEncodingException
        {
                //Costruzione del payload da trasmettere
                String lang       = "en";
                byte[] textBytes  = text.getBytes();
                byte[] langBytes  = lang.getBytes("US-ASCII");
                int    langLength = langBytes.length;
                int    textLength = textBytes.length;
                byte[] payload    = new byte[1 + langLength + textLength];

                // set status byte (see NDEF spec for actual bits)
                payload[0] = (byte) langLength;

                // copy langbytes and textbytes into payload
                System.arraycopy(langBytes, 0, payload, 1,              langLength);
                System.arraycopy(textBytes, 0, payload, 1 + langLength, textLength);

                //costruzione del record da scrivere
                NdefRecord recordNFC = new NdefRecord(NdefRecord.TNF_MIME_MEDIA,  
                                                                                "text/plain".getBytes(),  new byte[0], payload);

                return recordNFC;
        }
       
        //chiamato dal sistema per gestire il tag dopo che il sistema ha deciso quale applicazione
        //gestirà tale tag
        @Override
        protected void onNewIntent(Intent intent)
        {
               
                Toast.makeText(this, intent.getAction(), Toast.LENGTH_LONG ).show();
                if(NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())||
                                NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()))
                {
                        mytag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);    
                        Toast.makeText(this, this.getString(R.string.ok_detection) + mytag.toString(), Toast.LENGTH_LONG ).show();
                        leggi(intent);
                }
        }
       
       
        //funzione per leggere il nome del tag
        public void leggi(Intent intent)
        {
                Log.i("ProvaNfc2","Lettura");
                //recupero i dati estensi dall'evento
                Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
                String action = intent.getAction();
                NdefMessage[] msgs = null;
                if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action))
            {
                if (rawMsgs != null)
                {
                    msgs = new NdefMessage[rawMsgs.length];
                   
                    for (int i = 0; i < rawMsgs.length; i++) {
                       
                        msgs[i] = (NdefMessage) rawMsgs[i];
                    }
       
                    NdefMessage msg = msgs[0];
                    try
                    {
                        //estrapolazione del payload contenuto nel TAG
                        String temp = new String(msg.getRecords()[0].getPayload(), "UTF-8");
                        //taglio i primi 3 caratteri che sono identificativi della codifica
                        temp = temp.substring(3);
                       
                        //stampa della stringa
                        Toast.makeText(this,temp,Toast.LENGTH_SHORT).show();
                        temp = new String(msg.getRecords()[0].getType(),"UTF-8");
                        Toast.makeText(this,temp,Toast.LENGTH_SHORT).show();
                    }
                    catch (Exception e)
                    {
                        e.printStackTrace();
                    }
                }
            else
            {
                // Unknown tag type
                byte[] empty = new byte[] {};
                NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, empty, empty);
                NdefMessage msg = new NdefMessage(new NdefRecord[] {
                    record
                });
                msgs = new NdefMessage[] { msg };
                Log.i("ProvaNfc2","tag sconosciuto");
            }
            }
        else
        {
                Log.i("ProvaNfc2","Tag sconosciuto");
            finish();
        }
        }
       
        @Override
        public void onPause(){
                super.onPause();
                WriteModeOff();
        }

        @Override
        public void onResume(){
                super.onResume();
                WriteModeOn();
        }

        private void WriteModeOn(){
                writeMode = true;
                //registrazione per la precedenza alla gestione dell'evento
                adapter.enableForegroundDispatch(this, pendingIntent, resumeFilter, null);
                //adapter.enableForegroundDispatch(this, pendingIntent, writeTagFilters, null);
        }

        private void WriteModeOff(){
                writeMode = false;
                //disabilitazione alla gestione prioritaria del tag
                adapter.disableForegroundDispatch(this);
        }
}
Non esistono problemi, ma solo soluzioni...

Offline tom

  • Nuovo arrivato
  • *
  • Post: 24
  • Respect: 0
    • Mostra profilo
Re:Scrittura su NFC
« Risposta #2 il: 03 Ottobre 2012, 17:36:52 CEST »
0
ottimo tutorial.....
mi funziona....... però voglio farti una domanda. Se della stringa che scrivo, voglio leggere un campo prezzo come potrei fare. Esempio se nel tag voglio scrivere: Pane integrale €1,00 e in fase di lettura avere un campo message dove c'è pane integrale, e un campo prezzo dove c'è 1,00. hai mai provato qualcosa del genere?

Offline Lomba1986

  • Utente normale
  • ***
  • Post: 173
  • Respect: +1
    • Mostra profilo
Re:Scrittura su NFC
« Risposta #3 il: 03 Ottobre 2012, 17:41:55 CEST »
0
ottimo tutorial.....
mi funziona....... però voglio farti una domanda. Se della stringa che scrivo, voglio leggere un campo prezzo come potrei fare. Esempio se nel tag voglio scrivere: Pane integrale €1,00 e in fase di lettura avere un campo message dove c'è pane integrale, e un campo prezzo dove c'è 1,00. hai mai provato qualcosa del genere?

Sinceramente no, è da un po' che non ci lavoro....nel senso, devo seguire quello che serve al mio capo...

Però a naso direi che potresti scrivere le due informazioni su due record diversi....nel primo scrivi "pane integrale" e nel secondo il prezzo...

Però appunto è da quando ho scritto il post che praticamente non ci lavoro più purtroppo...
Non esistono problemi, ma solo soluzioni...

Offline Nicola_D

  • Moderatore
  • Utente storico
  • *****
  • Post: 2479
  • SBAGLIATO!
  • Respect: +323
    • Github
    • Google+
    • nicoladorigatti
    • Mostra profilo
  • Dispositivo Android:
    Nexus 6p, Nexus 4, Nexus S, Nexus 7(2012)
  • Sistema operativo:
    Windows 7
Re:Scrittura su NFC
« Risposta #4 il: 03 Ottobre 2012, 22:14:26 CEST »
0
ottimo tutorial.....
mi funziona....... però voglio farti una domanda. Se della stringa che scrivo, voglio leggere un campo prezzo come potrei fare. Esempio se nel tag voglio scrivere: Pane integrale €1,00 e in fase di lettura avere un campo message dove c'è pane integrale, e un campo prezzo dove c'è 1,00. hai mai provato qualcosa del genere?

le righe importanti per fare ciò che chiedi sono:
Codice (Java): [Seleziona]
  //creazione del NdefRecord da spedire
                NdefRecord[] records = { createRecord(text) };
                //creazione del messaggio da inviare
                NdefMessage  message = new NdefMessage(records);
               
studiati un attimo queste classi e leggi un po di documentazione a riguardo e capirai come!
IMPORTANTE:NON RISPONDO A PROBLEMI VIA MESSAGGIO PRIVATO
LOGCAT: Non sai cos'è? -> Android Debug Bridge | Android Developers
               Dov'è in Eclipse? -> Window -> Open Prospective -> DDMS e guarda in basso!
[Obbligatorio] Logcat, questo sconosciuto! (Gruppo AndDev.it LOGTFO) - Android Developers Italia

Offline tom

  • Nuovo arrivato
  • *
  • Post: 24
  • Respect: 0
    • Mostra profilo
Re:Scrittura su NFC
« Risposta #5 il: 05 Ottobre 2012, 18:45:23 CEST »
0
seguendo il tuo consiglio, ho un problema di lettura.
MI salta il campo message e legge solo il prezzo, cioè legge solo un campo. Perchè?

Offline Nicola_D

  • Moderatore
  • Utente storico
  • *****
  • Post: 2479
  • SBAGLIATO!
  • Respect: +323
    • Github
    • Google+
    • nicoladorigatti
    • Mostra profilo
  • Dispositivo Android:
    Nexus 6p, Nexus 4, Nexus S, Nexus 7(2012)
  • Sistema operativo:
    Windows 7
Re:Scrittura su NFC
« Risposta #6 il: 05 Ottobre 2012, 19:14:28 CEST »
0
seguendo il tuo consiglio, ho un problema di lettura.
MI salta il campo message e legge solo il prezzo, cioè legge solo un campo. Perchè?
hai controllato la "grandezza" dell'array di records?
IMPORTANTE:NON RISPONDO A PROBLEMI VIA MESSAGGIO PRIVATO
LOGCAT: Non sai cos'è? -> Android Debug Bridge | Android Developers
               Dov'è in Eclipse? -> Window -> Open Prospective -> DDMS e guarda in basso!
[Obbligatorio] Logcat, questo sconosciuto! (Gruppo AndDev.it LOGTFO) - Android Developers Italia

Offline salvatore.zagarella

  • Utente normale
  • ***
  • Post: 239
  • Respect: +2
    • Mostra profilo
    • Ieeng Solution
Re:Scrittura su NFC
« Risposta #7 il: 08 Novembre 2012, 12:32:05 CET »
0
Ragazzi una domanda,
ce modo di inserire una password o qualcosa per bloccare la scrittura del tag?

Offline Nicola_D

  • Moderatore
  • Utente storico
  • *****
  • Post: 2479
  • SBAGLIATO!
  • Respect: +323
    • Github
    • Google+
    • nicoladorigatti
    • Mostra profilo
  • Dispositivo Android:
    Nexus 6p, Nexus 4, Nexus S, Nexus 7(2012)
  • Sistema operativo:
    Windows 7
Re:Scrittura su NFC
« Risposta #8 il: 08 Novembre 2012, 15:56:33 CET »
0
Ragazzi una domanda,
ce modo di inserire una password o qualcosa per bloccare la scrittura del tag?
dipende da tag a tag, ad esempio i mifare classic hanno il blocco 4 di ogni settore che permette l'utilizzo di due chiavi.
i mifare ultralight in genere son senza protezione.
IMPORTANTE:NON RISPONDO A PROBLEMI VIA MESSAGGIO PRIVATO
LOGCAT: Non sai cos'è? -> Android Debug Bridge | Android Developers
               Dov'è in Eclipse? -> Window -> Open Prospective -> DDMS e guarda in basso!
[Obbligatorio] Logcat, questo sconosciuto! (Gruppo AndDev.it LOGTFO) - Android Developers Italia

Offline gigo

  • Nuovo arrivato
  • *
  • Post: 4
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy mini 2
  • Sistema operativo:
    Windows 7
Re:Scrittura su NFC
« Risposta #9 il: 23 Novembre 2012, 15:58:45 CET »
0
Nel caso di tag nfc classic, quindi predisposti all'utilizzo di password, in che modo il codice andrebbe modificato per poter inserire la password?

Gigo