android之NFC基础技术分享
16lz
2021-12-04
近场通讯(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文件配置如下:
有不足之处敬请谅解或者留言指出,谢谢。
更多相关文章
- 对Android及移动互联网的大局观看法!
- 对Android及移动互联网的大局观看法!
- [转]Android(安卓)应用程序基础(Application Fundamentals)
- Android面试看重你什么?(推荐!!!)
- android socket通信
- Android体系框架
- android studio 使用NDK和swig编译c++示例
- Android:你要的WebView与 JS 交互方式 都在这里了
- sscanf函数引起android 5.0卡死,C++中慎用C库函数