我正在开发一款适用于Android的App,你可以编写NFC标签。 这是代码:
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
我不知道为什么不写在里面。有什么想法吗?
非常感谢!
答案 0 :(得分:1)
非常感谢你的帮助。 我终于找到了不将数据写入标签的原因。我必须使用此功能将卡重新格式化为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
}
再次非常感谢你!
问候。