现在很多手机已经配备了NFC(Near Field Communication 近场通信)的功能,我就为此专门研究过,可以到本文末尾下载源代码。

Android官方资料:http://developer.android.com/guide/topics/connectivity/nfc/index.html

相关资料参考:http://blog.csdn.net/nicebooks/article/details/6223956

相关Android应用:https://play.google.com/store/apps/details?id=com.nxp.nfc.tagwriter

关于NFC的知识就不讲了,下面直接看代码,主要是读取、写入的功能。先自己新建一个Android工程,下面是用到的变量:

    private NfcAdapter mNfcAdapter;//NFC适配器,就是那个NFC读卡器    PendingIntent mNfcPendingIntent;//用于截获系统Intent,因为系统检测到NFC卡片时会选择程序去响应    IntentFilter[] mWriteTagFilters;//IntentFilter表示满足本程序响应的条件    private boolean mWriteMode = false;//控制读写模式切换

还是建议看看官方资料,这样才能明白某些函数的意思。接下来,在onCreate函数里检测NFC:

        //获取默认NFC设备        mNfcAdapter = NfcAdapter.getDefaultAdapter(this); if (mNfcAdapter == null) { Toast.makeText(this, "该设备不支持NFC!", Toast.LENGTH_LONG).show(); finish(); return; } //查看NFC是否开启        if (!mNfcAdapter.isEnabled()){ Toast.makeText(this, "请在系统设置中先启用NFC功能", Toast.LENGTH_LONG).show(); finish(); return; } mNfcPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); IntentFilter ndefDetected = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); try { ndefDetected.addDataType("text/plain"); } catch (MalformedMimeTypeException e) { e.printStackTrace(); } mWriteTagFilters = new IntentFilter[] { ndefDetected };

这里先检测手机是否支持NFC,finish()表示退出程序。最后,给上面变量赋值,添加截获的NFC数据类型为"text/plain",表示纯文本。

所以,如果NFC卡片存的是URL地址,我们的程序将无法截获,系统会用浏览器打开。当我们按下Home键,这时就无需截获系统Intent了,添加如下代码:

 @Override protected void onResume() { super.onResume(); mNfcAdapter.enableForegroundDispatch(this, mNfcPendingIntent, mWriteTagFilters, null); } @Override protected void onPause() { super.onPause(); mNfcAdapter.disableForegroundNdefPush(this); }

手机发现了NFC Tag,如果我们已经添加了PendingIntent,并且满足我们的IntentFilter条件,就会触发一个如下事件:

    //必须的函数,截获系统itent,然后触发读取和写入操作 @Override protected void onNewIntent(Intent intent) { if (!mWriteMode && NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) { NdefMessage[] msgs = getNdefMessages(intent); String body = new String(msgs[0].getRecords()[0].getPayload()); System.out.println("***读取数据***" + body); tagInfo.setText(body); } if (mWriteMode && NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) { Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); boolean writesuccess = writeTag(getNoteAsNdef(), detectedTag); System.out.println("***写入数据***"); if (writesuccess){ Toast.makeText(this, "写入成功", Toast.LENGTH_SHORT).show(); } else{ Toast.makeText(this, "写入失败!", Toast.LENGTH_SHORT).show(); } } }

系统检测到Tag时,会将其所有信息封装到Intent中,我们截获了它就可以读取了。如果要写入,需要构造NdefMessage信息才行。

上面代码中的getNoteAsNdef用来根据输入构造NdefMessage:

    //从输入框获取信息,然后构造NdefMessage用于写入    private NdefMessage getNoteAsNdef() { byte[] textBytes = (inputText.getText().toString()).getBytes(); NdefRecord textRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA, "text/plain".getBytes(), new byte[] {}, textBytes); return new NdefMessage(new NdefRecord[] { textRecord }); }

实际读取数据部分如下:

    //实际读取数据部分    private NdefMessage[] getNdefMessages(Intent intent) { NdefMessage[] msgs = null; String action = intent.getAction(); if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action) || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) { Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); if (rawMsgs != null) { msgs = new NdefMessage[rawMsgs.length]; for (int i = 0; i < rawMsgs.length; i++) { msgs[i] = (NdefMessage) rawMsgs[i]; } } 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 }; } } else { // Log.d(TAG, "Unknown intent."); finish(); } return msgs; }

实际写入部分如下:

    //实际写入数据部分    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()) { System.out.println("Tag is read-only."); return false; } if (ndef.getMaxSize() < size) { System.out.println("Tag capacity is " + ndef.getMaxSize() + " bytes, message is " + size + " bytes."); return false; } ndef.writeNdefMessage(message); System.out.println("****写入数据成功***"); return true; } else { NdefFormatable format = NdefFormatable.get(tag); if (format != null) { try { format.connect(); format.format(message); System.out.println("**Formatted tag and wrote message**"); return true; } catch (IOException e) { System.out.println("==Failed to format tag.=="); return false; } } else { System.out.println("Tag doesn't support NDEF."); return false; } } } catch (Exception e) { System.out.println("!!写入数据失败!!"); } return false; }

上面的写入、读取部分都不是很简洁,因为要兼容到android 2.3(API 10)的版本,Android 4.0以上提供了比较简单的读写方式,可以参考下面的文章:

http://shanetully.com/2012/12/writing-custom-data-to-nfc-tags-with-android-example/

如果你需要这样的功能,比如检测到文本时便启动你的程序,你可以在配置文件里设置,查看官方文档即可,我这里没有这样的需求。

最后,打开AndroidManifest.xml文件,添加如下代码用于开启NFC权限。注意,我的源代码。

    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="14" />    <uses-permission android:name="android.permission.NFC" />

更多相关文章

  1. Android应用程序的调试方法
  2. Android系统源码数据库(mmssms.db)
  3. 详解Android获取系统内核版本的方法与实现代码
  4. android数据存储之File
  5. android 创建数字签名应用程序
  6. Android SystemProperties 系统属性分析
  7. android 7.0系统解决拍照的问题android.os.FileUriExposedExcept
  8. Android之WebView 防止调用系统浏览器打开页面
  9. 如果,编译Android时新添加的应用程序没有被编译进image

随机推荐

  1. Android用户界面程序设计示例
  2. Android应用开发提高系列(4)
  3. DataBinding使用详解
  4. Android保存图片到相册
  5. android横竖屏问题解决办法
  6. 在2.2下使用GridLayout
  7. Android(安卓)面试题笔记-------bindserv
  8. Android中Telephony学习笔记(5)-CDMA/GSM
  9. Android(安卓)底部菜单栏(RadioGroup+Frag
  10. Android——RecyclerView——Recycler类