2

我正在为您编写 NFC 标签的 android 应用程序。这是代码:

public class MainActivity extends Activity {
NfcAdapter adapter;
PendingIntent pendingIntent;
IntentFilter writeTagFilters[];
boolean writeMode;
Tag myTag;
Context context;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //Definimos el layout a usar
    setContentView(R.layout.activity_main);
    context = this;
    //Los elementos que vamos a usar en el layout
    Button btnWrite = (Button)findViewById(R.id.button);
    final TextView message = (TextView)findViewById(R.id.edit_message);
    //setOnCLickListener hará la acción que necesitamos
    btnWrite.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
  try{
          //Si no existe tag al que escribir, mostramos un mensaje de que no existe.
          if(myTag == null){
              Toast.makeText(context, context.getString(R.string.error_notag), Toast.LENGTH_LONG).show();
          }else{
              //Llamamos al método write que definimos más adelante donde le pasamos por
              //parámetro el tag que hemos detectado y el mensaje a escribir.
              write(message.getText().toString(), myTag);
              Toast.makeText(context, context.getString(R.string.ok_write), Toast.LENGTH_LONG).show();
          }
   }catch(IOException e){
       Toast.makeText(context, context.getString(R.string.error_write),Toast.LENGTH_LONG).show();
       e.printStackTrace();
   }catch(FormatException e){
       Toast.makeText(context, context.getString(R.string.error_write), Toast.LENGTH_LONG).show();
       e.printStackTrace();
   }
 }

});

    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_TAG_DISCOVERED);
    tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
    writeTagFilters = new IntentFilter[]{tagDetected};
}
//El método write es el más importante, será el que se encargue de crear el mensaje 
//y escribirlo en nuestro tag.
private void write(String text, Tag tag) throws IOException, FormatException{
  //Creamos un array de elementos NdefRecord. Este Objeto representa un registro del mensaje NDEF   
  //Para crear el objeto NdefRecord usamos el método createRecord(String s)
  NdefRecord[] records = {createRecord(text)};
  //NdefMessage encapsula un mensaje Ndef(NFC Data Exchange Format). Estos mensajes están 
  //compuestos por varios registros encapsulados por la clase NdefRecord  
  NdefMessage message = new NdefMessage(records);
  //Obtenemos una instancia de Ndef del Tag
  Ndef ndef = Ndef.get(tag);
  ndef.connect();
  ndef.writeNdefMessage(message);
  ndef.close();
}
//Método createRecord será el que nos codifique el mensaje para crear un NdefRecord
private NdefRecord createRecord(String text) throws UnsupportedEncodingException{
    String lang = "us";
    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];

    payLoad[0] = (byte) langLength;

    System.arraycopy(langBytes, 0, payLoad, 1, langLength);
    System.arraycopy(textBytes, 0, payLoad, 1+langLength, textLength);

    NdefRecord recordNFC = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], payLoad);

    return recordNFC;

}
//en onnewIntent manejamos el intent para encontrar el Tag
protected void onNewIntent(Intent intent){
    if(NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())){
        myTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        Toast.makeText(this, this.getString(R.string.ok_detected) + myTag.toString(), Toast.LENGTH_LONG).show();

    }
}

public void onPause(){
    super.onPause();
    WriteModeOff();
}
public void onResume(){
    super.onResume();
    WriteModeOn();
}

private void WriteModeOn(){
    writeMode = true;
    adapter.enableForegroundDispatch(this, pendingIntent, writeTagFilters, null);
}

private void WriteModeOff(){
    writeMode = false;
    adapter.disableForegroundDispatch(this);
}

}

该标签被完美检测到,但如果我尝试写入它会给我以下错误:

java.io.IOException
at android.nfc.tech.Ndef.writeNdefMessage(Ndef.java:313)
at com.example.nfc_prueba.MainActivity.write(MainActivity.java:91)
at com.example.nfc_prueba.MainActivity.access$0(MainActivity.java:76)

标签类型为:Mifare Classic 1K

不知道为什么不写。任何的想法?

非常感谢你!

4

1 回答 1

2

非常感谢您的帮助。我终于找到了不向标签写入数据的原因。我必须使用此功能将卡重新格式化为 NDEF:

NdefFormatable formatable = NdefFormatable.get(tag);

    if (formatable != null) {
      try {
        formatable.connect();

        try {
          formatable.format(message);
        }
        catch (Exception e) {
          // let the user know the tag refused to format
        }
      }
      catch (Exception e) {
        // let the user know the tag refused to connect
      }
      finally {
        formatable.close();
      }
    }
    else {
      // let the user know the tag cannot be formatted
    }

再一次非常感谢你!

问候。

于 2013-10-30T13:04:51.870 回答