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

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

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

相关的类代码有:NfcAdapter,NdefMessage, NdefRecord,ACTION_TAG_DISCOVERED.

在功能层面上,涉及到了NFC的读写功能。下面我们分别来做总结。

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

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

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

            

获取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方法createNdefMessagepublic 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文件里面添加:

      

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

private void enableTagWriteMode() {    mWriteMode = true;    IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);    mWriteTagFilters = new IntentFilter[] { tagDetected };    mNfcAdapter.enableForegroundDispatch(this, mNfcPendingIntent, mWriteTagFilters, null);}@Overrideprotected 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文件配置如下:

                          

有不足之处敬请谅解或者留言指出,谢谢。

更多相关文章

  1. 对Android及移动互联网的大局观看法!
  2. 对Android及移动互联网的大局观看法!
  3. [转]Android(安卓)应用程序基础(Application Fundamentals)
  4. Android面试看重你什么?(推荐!!!)
  5. android socket通信
  6. Android体系框架
  7. android studio 使用NDK和swig编译c++示例
  8. Android:你要的WebView与 JS 交互方式 都在这里了
  9. sscanf函数引起android 5.0卡死,C++中慎用C库函数

随机推荐

  1. Android环境配置
  2. 【按键】灭屏后瞬间按返回键,可以点亮屏幕
  3. Android中的动画详解系列【1】——逐帧动
  4. android的单元测试
  5. Android(安卓)判断SD卡是否存在及容量查
  6. Android--ListView滑动时出现黑屏解决方
  7. Android(安卓)aapt 工具介绍(转载)
  8. Android(安卓)下载文件 显示进度条
  9. android 常用代码备份
  10. Downloadmanager in android