Android下NFC的简单使用
现在很多手机已经配备了NFC(Near Field Communication 近场通信)的功能,我就为此专门研究过,可以到本文末尾下载源代码。
Android官方资料:http://developer.android.com/guide/topics/connectivity/nfc/index.html
相关资料参考:http://blog.csdn.net/nicebooks/article/details/6223956
相关Android应用:https://play.google.com/store/apps/details?id=com.nxp.nfc.tagwriter
关于NFC的知识就不讲了,下面直接看代码,主要是读取、写入的功能。先自己新建一个Android工程,下面是用到的变量:
private NfcAdapter mNfcAdapter;//NFC适配器,就是那个NFC读卡器
PendingIntent mNfcPendingIntent;//用于截获系统Intent,因为系统检测到NFC卡片时会选择程序去响应
IntentFilter[] mWriteTagFilters;//IntentFilter表示满足本程序响应的条件
private boolean mWriteMode = false;//控制读写模式切换
还是建议看看官方资料,这样才能明白某些函数的意思。接下来,在onCreate函数里检测NFC:
//获取默认NFC设备
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (mNfcAdapter == null) {
Toast.makeText(this, "该设备不支持NFC!", Toast.LENGTH_LONG).show();
finish();
return;
}
//查看NFC是否开启
if (!mNfcAdapter.isEnabled()){
Toast.makeText(this, "请在系统设置中先启用NFC功能", Toast.LENGTH_LONG).show();
finish();
return;
}
mNfcPendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
IntentFilter ndefDetected = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
try {
ndefDetected.addDataType("text/plain");
} catch (MalformedMimeTypeException e) {
e.printStackTrace();
}
mWriteTagFilters = new IntentFilter[] { ndefDetected };
这里先检测手机是否支持NFC,finish()表示退出程序。最后,给上面变量赋值,添加截获的NFC数据类型为"text/plain",表示纯文本。
所以,如果NFC卡片存的是URL地址,我们的程序将无法截获,系统会用浏览器打开。当我们按下Home键,这时就无需截获系统Intent了,添加如下代码:
@Override
protected void onResume()
{
super.onResume();
mNfcAdapter.enableForegroundDispatch(this, mNfcPendingIntent, mWriteTagFilters, null);
}
@Override
protected void onPause()
{
super.onPause();
mNfcAdapter.disableForegroundNdefPush(this);
}
手机发现了NFC Tag,如果我们已经添加了PendingIntent,并且满足我们的IntentFilter条件,就会触发一个如下事件:
//必须的函数,截获系统itent,然后触发读取和写入操作
@Override
protected void onNewIntent(Intent intent)
{
if (!mWriteMode && NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()))
{
NdefMessage[] msgs = getNdefMessages(intent);
String body = new String(msgs[0].getRecords()[0].getPayload());
System.out.println("***读取数据***" + body);
tagInfo.setText(body);
}
if (mWriteMode && NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()))
{
Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
boolean writesuccess = writeTag(getNoteAsNdef(), detectedTag);
System.out.println("***写入数据***");
if (writesuccess){
Toast.makeText(this, "写入成功", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(this, "写入失败!", Toast.LENGTH_SHORT).show();
}
}
}
系统检测到Tag时,会将其所有信息封装到Intent中,我们截获了它就可以读取了。如果要写入,需要构造NdefMessage信息才行。
上面代码中的getNoteAsNdef用来根据输入构造NdefMessage:
//从输入框获取信息,然后构造NdefMessage用于写入
private NdefMessage getNoteAsNdef()
{
byte[] textBytes = (inputText.getText().toString()).getBytes();
NdefRecord textRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA, "text/plain".getBytes(), new byte[] {}, textBytes);
return new NdefMessage(new NdefRecord[] { textRecord });
}
实际读取数据部分如下:
//实际读取数据部分
private NdefMessage[] getNdefMessages(Intent intent)
{
NdefMessage[] msgs = null;
String action = intent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action) || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action))
{
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];
}
} else
{
// Unknown tag type
byte[] empty = new byte[] {};
NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, empty, empty);
NdefMessage msg = new NdefMessage(new NdefRecord[] { record });
msgs = new NdefMessage[] { msg };
}
} else
{
// Log.d(TAG, "Unknown intent.");
finish();
}
return msgs;
}
实际写入部分如下:
//实际写入数据部分
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())
{
System.out.println("Tag is read-only.");
return false;
}
if (ndef.getMaxSize() < size)
{
System.out.println("Tag capacity is " + ndef.getMaxSize() + " bytes, message is " + size + " bytes.");
return false;
}
ndef.writeNdefMessage(message);
System.out.println("****写入数据成功***");
return true;
} else
{
NdefFormatable format = NdefFormatable.get(tag);
if (format != null)
{
try
{
format.connect();
format.format(message);
System.out.println("**Formatted tag and wrote message**");
return true;
} catch (IOException e)
{
System.out.println("==Failed to format tag.==");
return false;
}
} else
{
System.out.println("Tag doesn't support NDEF.");
return false;
}
}
} catch (Exception e)
{
System.out.println("!!写入数据失败!!");
}
return false;
}
上面的写入、读取部分都不是很简洁,因为要兼容到android 2.3(API 10)的版本,Android 4.0以上提供了比较简单的读写方式,可以参考下面的文章:
http://shanetully.com/2012/12/writing-custom-data-to-nfc-tags-with-android-example/
如果你需要这样的功能,比如检测到文本时便启动你的程序,你可以在配置文件里设置,查看官方文档即可,我这里没有这样的需求。
最后,打开AndroidManifest.xml文件,添加如下代码用于开启NFC权限。注意,我的源代码。
<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="14" />
<uses-permission android:name="android.permission.NFC" />
Android下NFC的简单使用的更多相关文章
- Android下实现一个简单的计算器源码
下面的内容是关于Android下实现一个简单的计算器的内容. import android.app.Activity; import android.os.Bundle;import android. ...
- Android训练课程(Android Training) - NFC基础
NFC 基础 本文档介绍了在Android上的基本的NFC任务.它说明了如何发送和接收的NDEF消息(NDEF messages)的形式的表单里包含的NFC数据(NFC data),并介绍Androi ...
- Android下利用Bitmap切割图片
在自己自定义的一个组件中由于需要用图片显示数字编号,而当前图片就只有一张,上面有0-9是个数字,于是不得不考虑将其中一个个的数字切割下来,需要显示什么数字,只需要组合一下就好了. 下面是程序的关键代码 ...
- android 下滤镜效果的实现
android 下滤镜效果的实现 滤镜过滤颜色已实现,简单版本可通过下面代码的3个参数实现黑白.红.绿...等7种过滤(RGB的7种组合). 理论上讲可以过滤为任意颜色.调整混合结果的比值就行了. p ...
- android下的数据存储
android下数据存储的几种方式:(简单讨论) 1.文件 举例:登陆时“记住密码” 因为是基于Linux系统,直接建文件,文件会出现在项目工程:而手机登陆时,应该把文件放在手机里,通常数据放在dat ...
- android下身份验证方式调用webservice
在企业开发领域,webservice还是经常被用到的服务体系,因为他对安全事务支持都比较好. 有时候,我们就需要在android下调用后端的webservice服务,因为在内部网络环境下,所有需要ba ...
- [原创]Android中LocationManager的简单使用,获取当前位置
Android中LocationManager的提供了一系列方法来地理位置相关的问题,包括查询上一个已知位置:注册/注销来自某个 LocationProvider的周期性的位置更新:以及注册/注销接近 ...
- Android 下用 Pull 解析和生成 XML
Java 中是可以用 SAX 和 DOM 解析 XML 的,虽然在 Android 下也可以用这2中方式,但是还是推荐用 Pull.Pull 使用简单,效率相对高,Android 下是集成了 Pul ...
- Android下Affinities和Task
源文链接:http://appmem.com/archives/405 本文参考了官方Dev Guide文档,简单介绍Android下的affinities和任务(task). 1.Activity和 ...
随机推荐
- [Oracle]any, all解析
因为很少用到, 所以几乎忘记了这几个函数, 不过它们还是很有用的使用它们可以大大简化一些SQL文的语法, 至于效率问题, 如CCW所说它们和EXISTS, IN 之类没有什么差别, 而且要具体问题具体 ...
- UINavigationController使用详解
UINavigationController使用详解 有一阵子没有写随笔,感觉有点儿手生.一个多月以后终于又一次坐下来静下心写随笔,记录自己的学习笔记,也希望能够帮到大家. 废话少说回到正题,UINa ...
- ios loading视图动画(模仿58同城)
最近看了58同城的加载视图,感觉很不错,如下图: 所以想模仿写一个,下载58同城的app,解压,发现它用的是图片来实现的动画效果, 并不是绘制出来的,所以这就相对简单些了,其实整个动画的逻辑不复杂,无 ...
- Android:控件布局(单帧布局)FrameLayout
FrameLayout:所有控件位于左上角,并且直接覆盖前面的子元素. 在最上方显示的层加上: android:clickable="true" 可以避免点击上层触发底层. 实例: ...
- 功能齐全、效率一流的免费开源数据库导入导出工具(c#开发,支持SQL server、SQLite、ACCESS三种数据库),每月借此处理数据5G以上
软件名:DataPie 功能:支持SQL server.SQLite.ACCESS数据库的导入.导出.存储过程调用,支持EXCEL2007.EXCEL2003.ACCESS2007. CSV文件导入数 ...
- Flex Array内置排序方法的使用
在Array类中,提供内置的排序方法.排序是在软件开发的过程中,经常遇到的问题.通过这些内置的方法,可以快速轻便的进行排序操作. Array类提供sort方法对Array实例进行排序.sort方法没有 ...
- Ubuntu 12.04上编译Vim7.4的时候遇到“no terminal library found”问题
错误如下: no terminal library foundchecking for tgetent()... configure: error: NOT FOUND! You need ...
- 将OutLook.exe注册为服务,让其一直保持开启状态
类似于TaobaoProtect.exe是由TBSecSvc服务启动的 http://stackoverflow.com/questions/3582108/create-windows-servic ...
- oh my zsh命令
打开某个文件夹地址,输入 cdf 命令,会自动进入这个文件夹命令行 open ./ 打开当前命令行所在目录的文件夹
- ToString() 格式化字符串
例如i=: i.ToString().PadLeft(,'); 固定长度为10,左不足补0,结果为0000000001: