在Android4.0推出的时候,一个非常引人注目的功能就是NFC(Near Field Communication).

Near Field Communication (NFC) is a set of short-range wireless technologies, typically requiring a distance of 4cm or less to initiate a connection. NFC allows you to share small payloads of data between an NFC tag and an Android-powered device, or between two Android-powered devices.

翻译:
近场通讯(NFC)是一系列短距离无线技术,一般需要4cm或者更短去初始化连接。近场通讯(NFC)允许你在NFC tag和Android设备或者两个Android设备间共享小负载数据。

典型的应用为刷卡应用,如刷信用卡,公交车卡,吃饭的饭卡之类。腾讯2011年1月份文章“Android首款NFC近场通信应用推出”,说明了基于Android的NFC应用目前已经有了,得益于日本在手机刷卡的应用氛围。据2011年7月网易文章“PayPal推出Android系统NFC移动支付服务”报道,PayPal已经做了尝试了,相信这股风很快要刮到中国。

下面我们从技术的层面来分析一下这个技术。

官方的图片示例为:

这是NFC的开发流程,参考文章 “【NFC在android中的应用API】”。

相关的类代码有:NfcAdapter,NdefMessage, NdefRecord,ACTION_TAG_DISCOVERED.
在功能层面上,涉及到了NFC的读写功能。下面我们分别来做总结。
在代码层上面:

使用的时候,需要在AndroidManifest.xml里面加一些权限以及属性。

"android.permission.NFC" /> "android.hardware.nfc" android:required= "true" /> "10" />

这里注意,在Android Version 9的时候仅仅支持了ACTION_TAG_DISCOVERED,对于其他的需要10以上。

在上面的基础上,还需要增加intent-filter的支持。

     "android.nfc.action.NDEF_DISCOVERED" />      "android.intent.category.DEFAULT" />      "text/plain" />

获取NfcAdapter的代码为:

public static String getStatusNfcDevice () {      NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter();      if (nfcAdapter.isEnabled()) {           String status = "enabled" ;           return status;      }      else {          String status = "disabled" ;          return status;      } }

处理函数为

public void onResume() {      super .onResume();      if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {          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];              }          }      }      //process the msgs array }

完整的一个操作代码摘自Google Android NFC Guide代码(略加注释):

package com.example.android.beam;   import android.app.Activity; import android.content.Intent; import android.nfc.NdefMessage; import android.nfc.NdefRecord; import android.nfc.NfcAdapter; import android.nfc.NfcAdapter.CreateNdefMessageCallback; import android.nfc.NfcEvent; import android.os.Bundle; import android.os.Parcelable; import android.widget.TextView; import android.widget.Toast; import java.nio.charset.Charset;   //继承并实现接口CreateNdefMessageCallback方法createNdefMessage public class Beam extends Activity implements CreateNdefMessageCallback {      NfcAdapter mNfcAdapter;      TextView textView;        @Override      public void onCreate(Bundle savedInstanceState) {          super .onCreate(savedInstanceState);          setContentView(R.layout.main);          TextView textView = (TextView) findViewById(R.id.textView);          // Check for available NFC Adapter          //检测是否有NFC适配器          mNfcAdapter = NfcAdapter.getDefaultAdapter( this );          if (mNfcAdapter == null ) {              Toast.makeText( this , "NFC is not available" , Toast.LENGTH_LONG).show();              finish();              return ;          }          // Register callback          //注册回调函数          mNfcAdapter.setNdefPushMessageCallback( this , this );      }        @Override      public NdefMessage createNdefMessage(NfcEvent event) {          String text = ( "Beam me up, Android!\n\n" +                  "Beam Time: " + System.currentTimeMillis());          //回调函数,构造NdefMessage格式          NdefMessage msg = new NdefMessage(                  new NdefRecord[] { createMimeRecord(                          "application/com.example.android.beam" , text.getBytes())           /**            * The Android Application Record (AAR) is commented out. When a device            * receives a push with an AAR in it, the application specified in the AAR            * is guaranteed to run. The AAR overrides the tag dispatch system.            * You can add it back in to guarantee that this            * activity starts when receiving a beamed message. For now, this code            * uses the tag dispatch system.            */            //,NdefRecord.createApplicationRecord("com.example.android.beam")          });          return msg;      }        @Override      public void onResume() {          super .onResume();          // Check to see that the Activity started due to an Android Beam          //得到是否检测到ACTION_NDEF_DISCOVERED触发          if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {              processIntent(getIntent());          }      }        //重载Activity类方法处理当新Intent到来事件      @Override      public void onNewIntent(Intent intent) {          // onResume gets called after this to handle the intent          setIntent(intent);      }        /**       * Parses the NDEF Message from the intent and prints to the TextView       */      //关键处理函数,处理扫描到的NdefMessage      void processIntent(Intent intent) {          textView = (TextView) findViewById(R.id.textView);          Parcelable[] rawMsgs = intent.getParcelableArrayExtra(                  NfcAdapter.EXTRA_NDEF_MESSAGES);          // only one message sent during the beam          NdefMessage msg = (NdefMessage) rawMsgs[ 0 ];          // record 0 contains the MIME type, record 1 is the AAR, if present          textView.setText( new String(msg.getRecords()[ 0 ].getPayload()));      }        /**       * Creates a custom MIME type encapsulated in an NDEF record       */      public NdefRecord createMimeRecord(String mimeType, byte [] payload) {          byte [] mimeBytes = mimeType.getBytes(Charset.forName( "US-ASCII" ));          NdefRecord mimeRecord = new NdefRecord(                  NdefRecord.TNF_MIME_MEDIA, mimeBytes, new byte [ 0 ], payload);          return mimeRecord;      } }

上面代码还需要在AndroidManifest.xml文件里面添加

   "android.nfc.action.NDEF_DISCOVERED" />    "android.intent.category.DEFAULT" />    "application/com.example.android.beam" />

在对NFC设备进行写操作的时候,相关代码:

private void enableTagWriteMode() {      mWriteMode = true ;      IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);      mWriteTagFilters = new IntentFilter[] { tagDetected };      mNfcAdapter.enableForegroundDispatch( this , mNfcPendingIntent, mWriteTagFilters, null ); }

 

@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);          if (NfcUtils.writeTag(NfcUtils.getPlaceidAsNdef(placeidToWrite), detectedTag)) {              Toast.makeText( this , "Success: Wrote placeid to nfc tag" , Toast.LENGTH_LONG)                  .show();              NfcUtils.soundNotify( this );          } else {              Toast.makeText( this , "Write failed" , Toast.LENGTH_LONG).show();          }      } }

 

/* * Writes an NdefMessage to a NFC tag */ public static 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()) {                  return false ;              }              if (ndef.getMaxSize() < size) {                  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 ;      } }

相关的AndroidManifest.xml文件配置如下:

".CheckInActivity" >             "android.nfc.action.NDEF_DISCOVERED" />        "application/vnd.facebook.places" />        "android.intent.category.DEFAULT" />     

参考文章:

http://developer.android.com/guide/topics/nfc/nfc.html

http://stackoverflow.com/questions/5078649/android-nfc-sample-demo-reads-only-fake-information-from-the-tag

http://developer.android.com/guide/topics/nfc/index.html

http://money.163.com/11/0714/09/78TPVJOL00253CVK.html

http://www.cnblogs.com/jfttcjl/archive/2011/11/09/2242045.html

http://www.jessechen.net/blog/how-to-nfc-on-the-android-platform/

另外有几个专门推动NFC技术的联盟:

http://open-nfc.org/wp/nfchal/

http://www.classic.nxp.com/theme/nfc/

http://www.nfc-forum.org/home/

官方关于NFC的翻译文档见:

http://blog.csdn.net/nicebooks/article/details/6223956

参考库:

http://code.google.com/p/guava-libraries/

更多相关文章

  1. android adb 文章
  2. android 关于 发送post请求的代码总结(包含加上参数)
  3. Android Audio代码分析12 - stream type续
  4. android代码常识
  5. 登录+注册界面的实现(代码)
  6. 通过代码设置Android联系人的头像
  7. Android下MP3播放器的实现源代码02
  8. Android下MP3播放器的实现源代码03
  9. Android Audio代码分析21 - 创建AudioEffect对象

随机推荐

  1. 获取调试版和开发版的SHA1时报错'keytool
  2. android中关闭所有activity方法
  3. Android:异步处理之AsyncTask的应用(二)
  4. Android面试题(部分2)
  5. X-Library系列Android应用框架详解
  6. 如何分析和研究Log文件
  7. android 5.0新特性学习--RecyclerView
  8. Android(安卓)R.java 中 identifier expe
  9. 解决IE apk变成zip:Android(安卓)手机应用
  10. PhoneGap入门经典——理解PhoneGap应用程