android NFC开发
2015-12-03 22:08
471 查看
先说说NFC开发总结,看了几天NFC开发资料,搜集了不少关于这方面的资料、demo、以及他人的总结。以下有部分是摘录总结的。因为要是现在总结也是那些,最后附送代码。关于demo我也有,有需要在评论去发邮箱给我。
本文的下载地址demo:http://download.csdn.net/detail/qq_16064871/9324211
当系统检测到一个NFC标签的时候,他会自动去寻找最合适的activity去处理这个intent.
NFC发出的这个Intent将会有三种action:
ACTION_NDEF_DISCOVERED:当系统检测到tag中含有NDEF格式的数据时,且系统中有activity声明可以接受包含NDEF数据的Intent的时候,系统会优先发出这个action的intent。
ACTION_TECH_DISCOVERED:当没有任何一个activity声明自己可以响应ACTION_NDEF_DISCOVERED时,系统会尝试发出TECH的intent.即便你的tag中所包含的数据是NDEF的,但是如果这个数据的MIMEtype或URI不能和任何一个activity所声明的想吻合,系统也一样会尝试发出tech格式的intent,而不是NDEF.
ACTION_TAG_DISCOVERED:当系统发现前两个intent在系统中无人会接受的时候,就只好发这个默认的TAG类型的
<uses-permissionandroid:name="android.permission.NFC"/>
然后是sdk级别限制:我个人建议API11开始比较合适:
<uses-sdkandroid:minSdkVersion="11"/>
如果是API8,在代码中,nfc功能设置的代码会出错,要抛出
例如:
NfcAdapter mAdapter = NfcAdapter.getDefaultAdapter(this);
mAdapter.isEnabled()
接着是特殊功能限制:
<uses-featureandroid:name="android.hardware.nfc"android:required="true"/>这个生命可以让你的应用在googleplay上被声明使用者必须拥有nfc功能。
一个nfc_tech_filter.xml中可以定义多个<tech-list>结构组。
<span style="font-size:18px;"><resources xmlns:xliff="urn:oasis:names:tc:xliff:documen</span>t:1.2">
<tech-list>
<tech>
android.nfc.tech.IsoDep</tech>
<tech>android.nfc.tech.NfcA</tech>
<tech>android.nfc.tech.NfcB</tech>
<tech>android.nfc.tech.NfcF</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.NfcV</tech>
<tech>android.nfc.tech.Ndef</tech>
<tech>android.nfc.tech.NdefFormatable</tech>
<tech>android.nfc.tech.MifareClassic</tech>
<tech>android.nfc.tech.MifareUltralight</tech>
</tech-list>
</resources>
在androidManifest文件中声明xml过滤的举例如下:
<activity>
<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" />
</activity>
import java.io.ByteArrayOutputStream;
import java.nio.charset.Charset;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import org.nfc.read.ParsedNdefRecord;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.DialogInterface;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.MifareClassic;
import android.nfc.tech.MifareUltralight;
import android.os.Bundle;
import android.os.Parcelable;
import android.provider.Settings;
import android.widget.TextView;
public class MainActivity extends Activity {
private static final DateFormat TIME_FORMAT = SimpleDateFormat
.getDateTimeInstance();
private NfcAdapter mAdapter;
private PendingIntent mPendingIntent;
private NdefMessage mNdefPushMessage;
private TextView promt;
private AlertDialog mDialog;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
promt = (TextView) findViewById(R.id.promt);
resolveIntent(getIntent());
mDialog = new AlertDialog.Builder(this).setNeutralButton("Ok", null)
.create();
// 获取默认的NFC控制器
mAdapter = NfcAdapter.getDefaultAdapter(this);
//拦截系统级的NFC扫描,例如扫描蓝牙
mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
mNdefPushMessage = new NdefMessage(new NdefRecord[] { newTextRecord("",
Locale.ENGLISH, true) });
}
@Override
protected void onResume() {
super.onResume();
if (mAdapter == null) {
if (!mAdapter.isEnabled()) {
showWirelessSettingsDialog();
}
showMessage(R.string.error, R.string.no_nfc);
promt.setText("设备不支持NFC!");
return;
}
if (!mAdapter.isEnabled()) {
promt.setText("请在系统设置中先启用NFC功能!");
return;
}
if (mAdapter != null) {
//隐式启动
mAdapter.enableForegroundDispatch(this, mPendingIntent, null, null);
mAdapter.enableForegroundNdefPush(this, mNdefPushMessage);
}
}
@Override
protected void onPause() {
super.onPause();
if (mAdapter != null) {
//隐式启动
mAdapter.disableForegroundDispatch(this);
mAdapter.disableForegroundNdefPush(this);
}
}
//16进制字符串转换为String
private String hexString = "0123456789ABCDEF";
public String decode(String bytes) {
if (bytes.length() != 30) {
return null;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream(
bytes.length() / 2);
// 将每2位16进制整数组装成一个字节
for (int i = 0; i < bytes.length(); i += 2)
baos.write((hexString.indexOf(bytes.charAt(i)) << 4 | hexString
.indexOf(bytes.charAt(i + 1))));
return new String(baos.toByteArray());
}
// 字符序列转换为16进制字符串
private static String bytesToHexString(byte[] src, boolean isPrefix) {
StringBuilder stringBuilder = new StringBuilder();
if (isPrefix == true) {
stringBuilder.append("0x");
}
if (src == null || src.length <= 0) {
return null;
}
char[] buffer = new char[2];
for (int i = 0; i < src.length; i++) {
buffer[0] = Character.toUpperCase(Character.forDigit(
(src[i] >>> 4) & 0x0F, 16));
buffer[1] = Character.toUpperCase(Character.forDigit(src[i] & 0x0F,
16));
System.out.println(buffer);
stringBuilder.append(buffer);
}
return stringBuilder.toString();
}
private void showMessage(int title, int message) {
mDialog.setTitle(title);
mDialog.setMessage(getText(message));
mDialog.show();
}
private NdefRecord newTextRecord(String text, Locale locale,
boolean encodeInUtf8) {
byte[] langBytes = locale.getLanguage().getBytes(
Charset.forName("US-ASCII"));
Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset
.forName("UTF-16");
byte[] textBytes = text.getBytes(utfEncoding);
int utfBit = encodeInUtf8 ? 0 : (1 << 7);
char status = (char) (utfBit + 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);
return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT,
new byte[0], data);
}
private void showWirelessSettingsDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.nfc_disabled);
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(
Settings.ACTION_WIRELESS_SETTINGS);
startActivity(intent);
}
});
builder.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {
finish();
}
});
builder.create().show();
return;
}
//初步判断是什么类型NFC卡
private void resolveIntent(Intent intent) {
String action = intent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
Parcelable[] rawMsgs = intent
.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage[] msgs;
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[0];
byte[] id = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
Parcelable tag = intent
.getParcelableExtra(NfcAdapter.EXTRA_TAG);
byte[] payload = dumpTagData(tag).getBytes();
NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN,
empty, id, payload);
NdefMessage msg = new NdefMessage(new NdefRecord[] { record });
msgs = new NdefMessage[] { msg };
}
// Setup the views
buildTagViews(msgs);
}
}
//一般公家卡,扫描的信息
private String dumpTagData(Parcelable p) {
StringBuilder sb = new StringBuilder();
Tag tag = (Tag) p;
byte[] id = tag.getId();
sb.append("Tag ID (hex): ").append(getHex(id)).append("\n");
sb.append("Tag ID (dec): ").append(getDec(id)).append("\n");
sb.append("ID (reversed): ").append(getReversed(id)).append("\n");
String prefix = "android.nfc.tech.";
sb.append("Technologies: ");
for (String tech : tag.getTechList()) {
sb.append(tech.substring(prefix.length()));
sb.append(", ");
}
sb.delete(sb.length() - 2, sb.length());
for (String tech : tag.getTechList()) {
if (tech.equals(MifareClassic.class.getName())) {
sb.append('\n');
MifareClassic mifareTag = MifareClassic.get(tag);
String type = "Unknown";
switch (mifareTag.getType()) {
case MifareClassic.TYPE_CLASSIC:
type = "Classic";
break;
case MifareClassic.TYPE_PLUS:
type = "Plus";
break;
case MifareClassic.TYPE_PRO:
type = "Pro";
break;
}
sb.append("Mifare Classic type: ");
sb.append(type);
sb.append('\n');
sb.append("Mifare size: ");
sb.append(mifareTag.getSize() + " bytes");
sb.append('\n');
sb.append("Mifare sectors: ");
sb.append(mifareTag.getSectorCount());
sb.append('\n');
sb.append("Mifare blocks: ");
sb.append(mifareTag.getBlockCount());
}
if (tech.equals(MifareUltralight.class.getName())) {
sb.append('\n');
MifareUltralight mifareUlTag = MifareUltralight.get(tag);
String type = "Unknown";
switch (mifareUlTag.getType()) {
case MifareUltralight.TYPE_ULTRALIGHT:
type = "Ultralight";
break;
case MifareUltralight.TYPE_ULTRALIGHT_C:
type = "Ultralight C";
break;
}
sb.append("Mifare Ultralight type: ");
sb.append(type);
}
}
return sb.toString();
}
private String getHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (int i = bytes.length - 1; i >= 0; --i) {
int b = bytes[i] & 0xff;
if (b < 0x10)
sb.append('0');
sb.append(Integer.toHexString(b));
if (i > 0) {
sb.append(" ");
}
}
return sb.toString();
}
private long getDec(byte[] bytes) {
long result = 0;
long factor = 1;
for (int i = 0; i < bytes.length; ++i) {
long value = bytes[i] & 0xffl;
result += value * factor;
factor *= 256l;
}
return result;
}
private long getReversed(byte[] bytes) {
long result = 0;
long factor = 1;
for (int i = bytes.length - 1; i >= 0; --i) {
long value = bytes[i] & 0xffl;
result += value * factor;
factor *= 256l;
}
return result;
}
//显示NFC扫描的数据
private void buildTagViews(NdefMessage[] msgs) {
if (msgs == null || msgs.length == 0) {
return;
}
// Parse the first message in the list
// Build views for all of the sub records
Date now = new Date();
List<ParsedNdefRecord> records = NdefMessageParser.parse(msgs[0]);
final int size = records.size();
for (int i = 0; i < size; i++) {
TextView timeView = new TextView(this);
timeView.setText(TIME_FORMAT.format(now));
ParsedNdefRecord record = records.get(i);
promt.append(record.getViewText());
}
}
//获取系统隐式启动的
@Override
public void onNewIntent(Intent intent) {
setIntent(intent);
resolveIntent(intent);
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.reno.Beam"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="16" />
<!-- 权限 -->
<uses-permission android:name="android.permission.NFC" />
<!-- 是否支持谷歌什么硬件一般可以忽略 -->
<uses-feature android:name="android.hardware.nfc" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="org.reno.Beam.MainActivity"
android:alwaysRetainTaskState="true"
android:label="@string/app_name"
android:launchMode="singleInstance"
android:screenOrientation="nosensor" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
<!-- 添加这一条默认设置,能拦截当前页面所有扫描NFC的配置 -->
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<!--
这个过滤条件我就没有使用了
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_tech_filter" />
-->
</activity>
</application>
</manifest>
本文的下载地址demo:http://download.csdn.net/detail/qq_16064871/9324211
本文的下载地址demo:http://download.csdn.net/detail/qq_16064871/9324211
一、NFC的配置总结
第一:屏幕没有锁住 。 第二:NFC功能已经在设置中打开当系统检测到一个NFC标签的时候,他会自动去寻找最合适的activity去处理这个intent.
NFC发出的这个Intent将会有三种action:
ACTION_NDEF_DISCOVERED:当系统检测到tag中含有NDEF格式的数据时,且系统中有activity声明可以接受包含NDEF数据的Intent的时候,系统会优先发出这个action的intent。
ACTION_TECH_DISCOVERED:当没有任何一个activity声明自己可以响应ACTION_NDEF_DISCOVERED时,系统会尝试发出TECH的intent.即便你的tag中所包含的数据是NDEF的,但是如果这个数据的MIMEtype或URI不能和任何一个activity所声明的想吻合,系统也一样会尝试发出tech格式的intent,而不是NDEF.
ACTION_TAG_DISCOVERED:当系统发现前两个intent在系统中无人会接受的时候,就只好发这个默认的TAG类型的
二、NFC相关androidManifest文件设置
首先是权限:<uses-permissionandroid:name="android.permission.NFC"/>
然后是sdk级别限制:我个人建议API11开始比较合适:
<uses-sdkandroid:minSdkVersion="11"/>
如果是API8,在代码中,nfc功能设置的代码会出错,要抛出
例如:
NfcAdapter mAdapter = NfcAdapter.getDefaultAdapter(this);
mAdapter.isEnabled()
接着是特殊功能限制:
<uses-featureandroid:name="android.hardware.nfc"android:required="true"/>这个生命可以让你的应用在googleplay上被声明使用者必须拥有nfc功能。
三、NFC标签过滤,也在androidManifest文件设置
在activity的intent过滤xml声明中,你可以同时声明过滤这三种action.但是由之前所说,你应该知道系统在发送intent的时候是有优先级的,所以你最好清楚自己最想处理哪个。1:过滤ACTION_TAG_DISCOVERED:
<intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter>这个最简单,也是最后一个被尝试接受intent的选项。
2:过滤ACTION_NDEF_DISCOVERED:
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain" /> </intent-filter>其中最重要的应该算是data的mimeType类型了,这个定义的越准确,intent指向你这个activity的成功率就越高,否则系统可能不会发出你想要的NDEF intent了。下面在讲如何使用NDEF写入NFC标签的时候会多举几个类型的例子。
3:过滤ACTION_TECH_DISCOVERED:
你首先需要在你的<project-path>/res/xml下面创建一个过滤规则文件。名字任取,比如可以叫做nfc_tech_filter.xml。这个里面定义的是nfc实现的各种标准,每一个nfc卡都会符合多个不同的标准,个人理解为这些标准有些相互之间也是兼容的。你可以在检测到nfc标签后使用getTechList()方法来查看你所检测的tag到底支持哪些nfc标准。一个nfc_tech_filter.xml中可以定义多个<tech-list>结构组。
<span style="font-size:18px;"><resources xmlns:xliff="urn:oasis:names:tc:xliff:documen</span>t:1.2">
<tech-list>
<tech>
android.nfc.tech.IsoDep</tech>
<tech>android.nfc.tech.NfcA</tech>
<tech>android.nfc.tech.NfcB</tech>
<tech>android.nfc.tech.NfcF</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.NfcV</tech>
<tech>android.nfc.tech.Ndef</tech>
<tech>android.nfc.tech.NdefFormatable</tech>
<tech>android.nfc.tech.MifareClassic</tech>
<tech>android.nfc.tech.MifareUltralight</tech>
</tech-list>
</resources>
在androidManifest文件中声明xml过滤的举例如下:
<activity>
<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" />
</activity>
四、看具体代码:
1、主要代码实现如下:
package org.reno.Beam;import java.io.ByteArrayOutputStream;
import java.nio.charset.Charset;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import org.nfc.read.ParsedNdefRecord;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.DialogInterface;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.MifareClassic;
import android.nfc.tech.MifareUltralight;
import android.os.Bundle;
import android.os.Parcelable;
import android.provider.Settings;
import android.widget.TextView;
public class MainActivity extends Activity {
private static final DateFormat TIME_FORMAT = SimpleDateFormat
.getDateTimeInstance();
private NfcAdapter mAdapter;
private PendingIntent mPendingIntent;
private NdefMessage mNdefPushMessage;
private TextView promt;
private AlertDialog mDialog;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
promt = (TextView) findViewById(R.id.promt);
resolveIntent(getIntent());
mDialog = new AlertDialog.Builder(this).setNeutralButton("Ok", null)
.create();
// 获取默认的NFC控制器
mAdapter = NfcAdapter.getDefaultAdapter(this);
//拦截系统级的NFC扫描,例如扫描蓝牙
mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
mNdefPushMessage = new NdefMessage(new NdefRecord[] { newTextRecord("",
Locale.ENGLISH, true) });
}
@Override
protected void onResume() {
super.onResume();
if (mAdapter == null) {
if (!mAdapter.isEnabled()) {
showWirelessSettingsDialog();
}
showMessage(R.string.error, R.string.no_nfc);
promt.setText("设备不支持NFC!");
return;
}
if (!mAdapter.isEnabled()) {
promt.setText("请在系统设置中先启用NFC功能!");
return;
}
if (mAdapter != null) {
//隐式启动
mAdapter.enableForegroundDispatch(this, mPendingIntent, null, null);
mAdapter.enableForegroundNdefPush(this, mNdefPushMessage);
}
}
@Override
protected void onPause() {
super.onPause();
if (mAdapter != null) {
//隐式启动
mAdapter.disableForegroundDispatch(this);
mAdapter.disableForegroundNdefPush(this);
}
}
//16进制字符串转换为String
private String hexString = "0123456789ABCDEF";
public String decode(String bytes) {
if (bytes.length() != 30) {
return null;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream(
bytes.length() / 2);
// 将每2位16进制整数组装成一个字节
for (int i = 0; i < bytes.length(); i += 2)
baos.write((hexString.indexOf(bytes.charAt(i)) << 4 | hexString
.indexOf(bytes.charAt(i + 1))));
return new String(baos.toByteArray());
}
// 字符序列转换为16进制字符串
private static String bytesToHexString(byte[] src, boolean isPrefix) {
StringBuilder stringBuilder = new StringBuilder();
if (isPrefix == true) {
stringBuilder.append("0x");
}
if (src == null || src.length <= 0) {
return null;
}
char[] buffer = new char[2];
for (int i = 0; i < src.length; i++) {
buffer[0] = Character.toUpperCase(Character.forDigit(
(src[i] >>> 4) & 0x0F, 16));
buffer[1] = Character.toUpperCase(Character.forDigit(src[i] & 0x0F,
16));
System.out.println(buffer);
stringBuilder.append(buffer);
}
return stringBuilder.toString();
}
private void showMessage(int title, int message) {
mDialog.setTitle(title);
mDialog.setMessage(getText(message));
mDialog.show();
}
private NdefRecord newTextRecord(String text, Locale locale,
boolean encodeInUtf8) {
byte[] langBytes = locale.getLanguage().getBytes(
Charset.forName("US-ASCII"));
Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset
.forName("UTF-16");
byte[] textBytes = text.getBytes(utfEncoding);
int utfBit = encodeInUtf8 ? 0 : (1 << 7);
char status = (char) (utfBit + 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);
return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT,
new byte[0], data);
}
private void showWirelessSettingsDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.nfc_disabled);
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(
Settings.ACTION_WIRELESS_SETTINGS);
startActivity(intent);
}
});
builder.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {
finish();
}
});
builder.create().show();
return;
}
//初步判断是什么类型NFC卡
private void resolveIntent(Intent intent) {
String action = intent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
Parcelable[] rawMsgs = intent
.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage[] msgs;
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[0];
byte[] id = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
Parcelable tag = intent
.getParcelableExtra(NfcAdapter.EXTRA_TAG);
byte[] payload = dumpTagData(tag).getBytes();
NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN,
empty, id, payload);
NdefMessage msg = new NdefMessage(new NdefRecord[] { record });
msgs = new NdefMessage[] { msg };
}
// Setup the views
buildTagViews(msgs);
}
}
//一般公家卡,扫描的信息
private String dumpTagData(Parcelable p) {
StringBuilder sb = new StringBuilder();
Tag tag = (Tag) p;
byte[] id = tag.getId();
sb.append("Tag ID (hex): ").append(getHex(id)).append("\n");
sb.append("Tag ID (dec): ").append(getDec(id)).append("\n");
sb.append("ID (reversed): ").append(getReversed(id)).append("\n");
String prefix = "android.nfc.tech.";
sb.append("Technologies: ");
for (String tech : tag.getTechList()) {
sb.append(tech.substring(prefix.length()));
sb.append(", ");
}
sb.delete(sb.length() - 2, sb.length());
for (String tech : tag.getTechList()) {
if (tech.equals(MifareClassic.class.getName())) {
sb.append('\n');
MifareClassic mifareTag = MifareClassic.get(tag);
String type = "Unknown";
switch (mifareTag.getType()) {
case MifareClassic.TYPE_CLASSIC:
type = "Classic";
break;
case MifareClassic.TYPE_PLUS:
type = "Plus";
break;
case MifareClassic.TYPE_PRO:
type = "Pro";
break;
}
sb.append("Mifare Classic type: ");
sb.append(type);
sb.append('\n');
sb.append("Mifare size: ");
sb.append(mifareTag.getSize() + " bytes");
sb.append('\n');
sb.append("Mifare sectors: ");
sb.append(mifareTag.getSectorCount());
sb.append('\n');
sb.append("Mifare blocks: ");
sb.append(mifareTag.getBlockCount());
}
if (tech.equals(MifareUltralight.class.getName())) {
sb.append('\n');
MifareUltralight mifareUlTag = MifareUltralight.get(tag);
String type = "Unknown";
switch (mifareUlTag.getType()) {
case MifareUltralight.TYPE_ULTRALIGHT:
type = "Ultralight";
break;
case MifareUltralight.TYPE_ULTRALIGHT_C:
type = "Ultralight C";
break;
}
sb.append("Mifare Ultralight type: ");
sb.append(type);
}
}
return sb.toString();
}
private String getHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (int i = bytes.length - 1; i >= 0; --i) {
int b = bytes[i] & 0xff;
if (b < 0x10)
sb.append('0');
sb.append(Integer.toHexString(b));
if (i > 0) {
sb.append(" ");
}
}
return sb.toString();
}
private long getDec(byte[] bytes) {
long result = 0;
long factor = 1;
for (int i = 0; i < bytes.length; ++i) {
long value = bytes[i] & 0xffl;
result += value * factor;
factor *= 256l;
}
return result;
}
private long getReversed(byte[] bytes) {
long result = 0;
long factor = 1;
for (int i = bytes.length - 1; i >= 0; --i) {
long value = bytes[i] & 0xffl;
result += value * factor;
factor *= 256l;
}
return result;
}
//显示NFC扫描的数据
private void buildTagViews(NdefMessage[] msgs) {
if (msgs == null || msgs.length == 0) {
return;
}
// Parse the first message in the list
// Build views for all of the sub records
Date now = new Date();
List<ParsedNdefRecord> records = NdefMessageParser.parse(msgs[0]);
final int size = records.size();
for (int i = 0; i < size; i++) {
TextView timeView = new TextView(this);
timeView.setText(TIME_FORMAT.format(now));
ParsedNdefRecord record = records.get(i);
promt.append(record.getViewText());
}
}
//获取系统隐式启动的
@Override
public void onNewIntent(Intent intent) {
setIntent(intent);
resolveIntent(intent);
}
}
2、androidManifest配置
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.reno.Beam"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="16" />
<!-- 权限 -->
<uses-permission android:name="android.permission.NFC" />
<!-- 是否支持谷歌什么硬件一般可以忽略 -->
<uses-feature android:name="android.hardware.nfc" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="org.reno.Beam.MainActivity"
android:alwaysRetainTaskState="true"
android:label="@string/app_name"
android:launchMode="singleInstance"
android:screenOrientation="nosensor" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
<!-- 添加这一条默认设置,能拦截当前页面所有扫描NFC的配置 -->
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<!--
这个过滤条件我就没有使用了
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_tech_filter" />
-->
</activity>
</application>
</manifest>
本文的下载地址demo:http://download.csdn.net/detail/qq_16064871/9324211
相关文章推荐
- android加载本地文件数据
- Android第三方开源FloatingActionButton(com.getbase.floatingactionbutton)【2】
- android 点击时背景图片 、 文字颜色变换
- Android基础之Activity系列 - Activity间的数据传递
- Android SDK 在线更新镜像服务器资源
- Android集成支付宝
- Android之mvp和mvc对比分析以及实际应用
- Android第三方开源FloatingActionButton(com.getbase.floatingactionbutton)【1】
- Android设置特定时间执行操作
- Android SurfaceView简介
- 短信发送器
- Android电话拨号器
- Intent的简介以及属性的详解
- Android SharedPreferences安全存储/AutoCompleteTextView使用/文件读写
- Activity的生命周期
- Android 手势控制解锁,滑动图片,照相,音乐切换,收音机换台,短信界面打电话
- Android作业分组与选题
- 用Intent调用系统中经常被用到的组件
- Android是否联网判断
- 设置ExpandableListView不显示分割线