1.AndroidManifest.xml
加入權限
與最低版本
android:minsdkversion="17" android:targetsdkversion="17"
2.activity_main.xml
3.MainActivity.java
import java.io.IOException;
import nl.paulus.nfctagwriter.R;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
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.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
/**
* Activity to write NFC tags with own mimetype and ID Based on the excellent
* tutorial by Jesse Chen
* http://www.jessechen.net/blog/how-to-nfc-on-the-android-platform/
*/
public class MainActivity extends Activity {
boolean mWriteMode = false;
private NfcAdapter mNfcAdapter;
private PendingIntent mNfcPendingIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
((Button) findViewById(R.id.button))
.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mNfcAdapter = NfcAdapter
.getDefaultAdapter(MainActivity.this);
mNfcPendingIntent = PendingIntent.getActivity(
MainActivity.this,
0,
new Intent(MainActivity.this,
MainActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
0);
//開啟寫入
enableTagWriteMode();
new AlertDialog.Builder(MainActivity.this)
.setTitle("感應tag寫入")
.setOnCancelListener(
new DialogInterface.OnCancelListener() {
@Override
public void onCancel(
DialogInterface dialog) {
//關閉寫入
disableTagWriteMode();
}
}).create().show();
}
});
}
private void enableTagWriteMode() {
mWriteMode = true;
IntentFilter tagDetected = new IntentFilter(
NfcAdapter.ACTION_TAG_DISCOVERED);
IntentFilter[] mWriteTagFilters = new IntentFilter[] { tagDetected };
mNfcAdapter.enableForegroundDispatch(this, mNfcPendingIntent,
mWriteTagFilters, null);
}
private void disableTagWriteMode() {
mWriteMode = false;
mNfcAdapter.disableForegroundDispatch(this);
}
@SuppressLint("NewApi")
@Override
protected void onNewIntent(Intent intent) {
// Tag writing mode
if (mWriteMode
&& NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
NdefRecord record = NdefRecord.createMime( //需要Android 4.1(API Level 16)
((TextView) findViewById(R.id.mime)).getText().toString(),
((TextView) findViewById(R.id.value)).getText().toString()
.getBytes());
NdefMessage message = new NdefMessage(new NdefRecord[] { record });
if (writeTag(message, detectedTag)) {
Toast.makeText(this, "成功寫入!",
Toast.LENGTH_LONG).show();
}
}
//讀取寫入訊息 看是否有寫入
try {
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage[] msgs = new NdefMessage[rawMsgs.length];
for (int i = 0; i < rawMsgs.length; i++) {
msgs[i] = (NdefMessage) rawMsgs[i];
}
NdefMessage msg = msgs[0];
String msgstring = new String(msg.getRecords()[0].getPayload(), "UTF-8");
Toast.makeText(getApplicationContext(), msgstring, Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
/* 檢查訊息 */
public boolean writeTag(NdefMessage message, Tag tag) {
int size = message.toByteArray().length;
try {
Ndef ndef = Ndef.get(tag);
if (ndef != null) {
ndef.connect();
if (!ndef.isWritable()) {
Toast.makeText(getApplicationContext(),
"Error: tag not writable", Toast.LENGTH_SHORT)
.show();
return false;
}
if (ndef.getMaxSize() < size) {
Toast.makeText(getApplicationContext(),
"Error: tag too small", Toast.LENGTH_SHORT).show();
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;
}
}
}
參考來源:https://github.com/balloob/Android-NFC-Tag-Writer
http://stackoverflow.com/questions/7917567/strange-character-on-android-ndef-record-payload

您好,
回覆刪除拙學有一個NFC的疑惑請輩指引,NFC手機和NFC晶片卡之間,
從晶片卡讀取資料,處理加入其他資料(如時間),再寫入晶片卡,
這一連串動作,是否可以在一次感應下就完成?
因為目前拙學作出來是感應時,只有讀取,不會寫入,再感應才會寫入,
也就是讀取和寫入要分兩次感應,能不能一次感應就完成讀取,處理,寫入的動作呢?
查過許多參考書和網路資料,有的說可以,但都沒有實例,全部都是讀寫分開,
到底可不可以一次感應就完成呢?
拙學 Stephen您好,
拙學有一個NFC的疑惑請輩指引,NFC手機和NFC晶片卡之間,
從晶片卡讀取資料,處理加入其他資料(如時間),再寫入晶片卡,
這一連串動作,是否可以在一次感應下就完成?
因為目前拙學作出來是感應時,只有讀取,不會寫入,再感應才會寫入,
也就是讀取和寫入要分兩次感應,能不能一次感應就完成讀取,處理,寫入的動作呢?
查過許多參考書和網路資料,有的說可以,但都沒有實例,全部都是讀寫分開,
到底可不可以一次感應就完成呢?
拙學 Stephen tzushow@gmail.com
可以的喔,把讀取的程式碼放在寫入的程式碼前面就好了
刪除protected void onNewIntent(Intent intent) {
NFCManager nfcHelper = new NFCManager(this);
/* 取出寫入tag */
String msgstring = nfcHelper.writeNFC(intent); //先感應取出tag內的訊息
String myMessage = ((TextView) findViewById(R.id.value)).getText().toString()+msgstring;//字串處理:輸入的字串+原先的字串
// Tag writing mode
if (mWriteMode
&& NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
NdefRecord record = NdefRecord.createMime( //需要Android 4.1(API Level 16)
((TextView) findViewById(R.id.mime)).getText().toString(),
myMessage.getBytes()); //寫入處理過的字串
...
...
}
不好意思能不能請問手機本身怎麼取出自己nfc_tag
回覆刪除似乎是要看裝置得nfc感應器是否支援的樣子,您可以參考這篇
刪除https://stackoverflow.com/questions/6138077/can-an-android-nfc-phone-act-as-an-nfc-tag?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
好的感謝您
刪除