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
好的感謝您
刪除