由于Android具有良好的开源优势,可进行深度定制开发。 安卓系统市场应用比windows晚,虽然支持的应用不如windows系统多,但由于系统的免费开放性,众多软件厂商经过近几年的开发,已经有越来越多的应用加入进来,目前支持办公、教学、娱乐已经完全没有问题。因此,越来越多的行业接受并认可基于Android操作系统的设备。

目前市面上大多数工业控制设备开始采用Android系统了,然而这部分设备并没有搭载原生的NFC功能。随着近年来,NFC功能需求的兴起,很多行业需要一直可以支持Android系统的可接入Android设备并进行二次开发的
NFC读写器。因此, L3-U这款NFC读写器
应运而生。作为一款采用USB免驱 的NFC读写器,支持在windows、Android、linux等操作系统,免费提供基于上述各种系统的SDK,方便客户进行功能扩展和二次开发。

L3-U这款USB免驱动NFC读写器已经设计好了USB 驱动,用户在基于Android系统的设备上只有能获取USB
HOST权限或者采用OTG传输就可以使用,无需安装额外驱动。如果你其它非标准的Android设备,需要提供设备我们进行编译驱动。以下为标准的具有USB
HOST权限的设备接入NFC读写器的过程。供大家在进行NFC读写器二次开发过程中参考!

1、在项目中对AndroidManifest.xml文件进行配置,获取相关权限。
<uses-permission android:name="android.permission.NFC" /> <uses-feature
android:name="android.hardware.nfc" android:required="true" /> <uses-sdk
android:minSdkVersion="12" android:targetSdkVersion="17" /> <intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category
android:name="android.intent.category.DEFAULT" /> <data
android:mimeType="text/*" /> </intent-filter> <intent-filter> <action
android:name="android.nfc.action.TECH_DISCOVERED" /> </intent-filter>
<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_tech_filter" />
 
<uses-permission android:name="android.permission.NFC" />     <uses-feature  
      android:name="android.hardware.nfc"         android:required="true" /> 
添加了这句代码,会使得在应用商店下载应用是过滤掉不支持NFC功能的设备。
这里声明了三种intent筛选条件,分别是action为

android.nfc.action.NDEF_DISCOVERED,

android.nfc.action.TECH_DISCOVERED,

android.nfc.action.TAG_DISCOVERED。

这一步可以帮助android系统内的NFC模块在扫描到一个NFC目标的时候寻找到我们的activity来进行交互。

android系统内的NFC模块在扫描到一个NFC目标后会通过以下几步来寻找到合适的处理NFC消息的activity。在这之前先介绍两个概念,1、Tag代表一个NFC目标,当android设备扫描到一个NFC目标的时候会将相关数据封装成一个Tag实例,通过Intent传递给合适的activity去做处理。2、TagTechnology表示NFC标签支持的技术,可以通过Tag的getTechList()获取。

Tag的分发步骤:

a、先看Tag中是否包含了系统支持的NDEF数据,如果包含则分发给注册了action为ACTION_NEDF_DISCOVERED的activity。

b、如果Tag中不包含系统支持的NDEF数据或者没有找到注册了action为ACTION_NDEF_DISCOVERED的activity,则NFC系统模块尝试分发给一个action为ACTION_TECH_DISCOVERED的activity。NFC系统模块在分发是首先分析NFC
Tag支持的Tag Technology,然后寻找支持这类Tag
Technology的activity,然后封装了Tag数据的Intent分发给对应的activity。

c、如果上面两种都不满足,则发送action为ACTION_TAG_DISCOVERED的intent

2、建立一个Activity页面,用于实现NFC读写的功能。NFC读写功能实现的代码如下:
package cc.lotusnfc; import java.io.IOException; import
java.nio.charset.Charset; import java.sql.Date; import
java.text.SimpleDateFormat; import java.util.Arrays; import cc.lotusnfc.R;
import android.nfc.FormatException; import android.nfc.NdefMessage; import
android.nfc.NdefRecord; import android.nfc.NfcAdapter; import
android.nfc.NfcManager; import android.nfc.Tag; import
android.nfc.tech.MifareClassic; import android.nfc.tech.Ndef; import
android.nfc.tech.NfcA; import android.os.Bundle; import android.os.Parcelable;
import android.annotation.SuppressLint; import android.app.Activity; import
android.app.PendingIntent; import android.content.Context; import
android.content.Intent; import android.content.IntentFilter; import
android.view.Menu; import android.view.View; import android.widget.Button;
import android.widget.EditText; import android.widget.TextView; import
android.widget.Toast; public class MainActivity extends Activity { private
TextView resultText; private PendingIntent pendingIntent; private
IntentFilter[] mFilters; private String[][] mTechLists; private Button
mJumpTagBtn; private boolean isFirst = true; private NfcAdapter m_NfcAdpater;
private EditText m_edtLog; private Intent m_NfcIntent = null; @Override
protected void onCreate(Bundle savedInstanceState) { // 获取nfc适配器,判断设备是否支持NFC功能
m_NfcAdpater = NfcAdapter.getDefaultAdapter(this); if (m_NfcAdpater == null) {
Toast.makeText(this, "Not Found NfcAdapter!", Toast.LENGTH_SHORT) .show();
//finish(); //return; } else if (!m_NfcAdpater.isEnabled()) {
Toast.makeText(this, "Please Enabled NfcAdapter", Toast.LENGTH_SHORT).show();
//finish(); //return; } super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); m_edtLog = (EditText)
findViewById(R.id.edtLog); m_edtLog.setText(""); pendingIntent =
PendingIntent.getActivity(this, 0, new Intent(this,
getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); IntentFilter ndef =
new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED); ndef.addCategory("*/*");
mFilters = new IntentFilter[] { ndef };// 过滤器 mTechLists = new String[][] { new
String[] { MifareClassic.class.getName() }, new String[] { NfcA.class.getName()
} };// 允许扫描的标签类型 } @Override public boolean onCreateOptionsMenu(Menu menu) { //
Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu); return true; }
@SuppressLint("NewApi") @Override protected void onResume() { // TODO
Auto-generated method stub super.onResume();
m_NfcAdpater.enableForegroundDispatch(this, pendingIntent, mFilters,
mTechLists); } private NdefMessage createMessage(String text) { NdefRecord[]
record = new NdefRecord[1]; String lang = "en"; byte[] langBytes =
lang.getBytes(Charset.forName("US-ASCII")); byte[] textBytes =
text.getBytes(Charset.forName("UTF-8")); char status = (char)
(langBytes.length); byte[] data = new byte[1 + langBytes.length +
textBytes.length]; data[0] = (byte) status; System.arraycopy(langBytes, 0,
data, 1, langBytes.length); System.arraycopy(textBytes, 0, data, 1 +
langBytes.length, textBytes.length); record[0] = new
NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data);
return new NdefMessage(record); } @Override protected void onNewIntent(Intent
intent) { // TODO Auto-generated method stub super.onNewIntent(intent);
m_NfcIntent = intent; String strWriteText = "春眠不觉晓"; if
(NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) { Tag
tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); Ndef ndef =
Ndef.get(tagFromIntent); if (ndef != null) { NdefMessage ndefMessage =
createMessage(strWriteText); try { ndef.connect(); // READ NdefMessage msg =
ndef.getNdefMessage(); if(null == msg) return; NdefRecord[] records =
msg.getRecords(); // NdefMessage nmsg = (NdefMessage) msgs[0]; NdefRecord
record = records[0]; String resultStr = ""; if (record.getTnf() ==
NdefRecord.TNF_WELL_KNOWN) { if (Arrays .equals(record.getType(),
NdefRecord.RTD_TEXT)) { byte[] payload = record.getPayload(); if (payload ==
null) return; try { String textEString = ((payload[0] & 0x80) == 0) ? "UTF-8" :
"UTF-16"; int languageCodeLength = payload[0] & 0x3f; resultStr = new
String(payload, languageCodeLength + 1, payload.length - languageCodeLength -
1, textEString); AddLog("Read:" + resultStr); } catch (Exception e) {
e.printStackTrace(); } } } // WRITE ndef.writeNdefMessage(ndefMessage);
AddLog("WRITE:" + strWriteText); ndef.close(); } catch (IOException e) { //
TODO Auto-generated catch block e.printStackTrace(); AddLog("IOException" ); }
catch (FormatException e) { // TODO Auto-generated catch block
e.printStackTrace(); AddLog("FormatException" ); } } } } private void
AddLog(String strLog) { SimpleDateFormat formatter = new
SimpleDateFormat("HH:mm:ss"); Date curDate = new
Date(System.currentTimeMillis());// 获取当前时间 String strDate =
formatter.format(curDate); if (null == m_edtLog) return; String strLogs =
m_edtLog.getText().toString().trim(); if (strLogs.equals("")) { strLogs =
strDate + " " + strLog; } else { strLogs += "\r\n" + strDate + " " + strLog; }
m_edtLog.setText(strLogs); } public void OnClearLogListener(View arg0) { if
(null == m_edtLog) return; m_edtLog.setText(""); } public void
OnSetNfcListener(View arg0) { startActivityForResult(new Intent(
android.provider.Settings.ACTION_WIRELESS_SETTINGS), 0); } public void
OnTestListener(View arg0) { String strWriteText = "春眠不觉晓"; if(null ==
m_NfcIntent) return; if
(NfcAdapter.ACTION_TECH_DISCOVERED.equals(m_NfcIntent.getAction())) { Tag
tagFromIntent = m_NfcIntent.getParcelableExtra(NfcAdapter.EXTRA_TAG); Ndef ndef
= Ndef.get(tagFromIntent); if (ndef != null) { NdefMessage ndefMessage =
createMessage(strWriteText); try { ndef.connect(); // READ NdefMessage msg =
ndef.getNdefMessage(); NdefRecord[] records = msg.getRecords(); // NdefMessage
nmsg = (NdefMessage) msgs[0]; NdefRecord record = records[0]; String resultStr
= ""; if (record.getTnf() == NdefRecord.TNF_WELL_KNOWN) { if (Arrays
.equals(record.getType(), NdefRecord.RTD_TEXT)) { byte[] payload =
record.getPayload(); if (payload == null) return; try { String textEString =
((payload[0] & 0x80) == 0) ? "UTF-8" : "UTF-16"; int languageCodeLength =
payload[0] & 0x3f; resultStr = new String(payload, languageCodeLength + 1,
payload.length - languageCodeLength - 1, textEString); AddLog("Read:" +
resultStr); } catch (Exception e) { e.printStackTrace(); } } } // WRITE
ndef.writeNdefMessage(ndefMessage); AddLog("WRITE:" + strWriteText);
ndef.close(); } catch (IOException e) { // TODO Auto-generated catch block
e.printStackTrace(); } catch (FormatException e) { // TODO Auto-generated catch
block e.printStackTrace(); } } } } }
 

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信