android NFC 开发学习笔记(1)
2015-12-04 14:32
417 查看
由于工作需求,最近在研究android nfc开发,借鉴了很对大神的文章在此记录自己的学习过程:
大家学习android开发建议首选android开发文档,该文档在你下载的sdk中,路径:/sdk/docs/index.html
目前NFC应用的大的框架上的理解:
我使用的API LEVEL是19,支持的API有三个:android.nfc,android.nfc.cardemulator,android.nfc.tech
NFC在手机上的应用大体分为两类:读卡器和卡
android.nfc.cardemulator接口是为NFC作为卡应用提供的接口,在较低版本的API上是没有的
android.nfc.tech,android.nfc接口是为NFC作为读卡器应用提供的接口
首先说作为卡,nfc有两种实现方式,一个是使用NFC芯片作为卡,另一个是使用SIM作为卡
Figure 1. NFC card emulation with a secure element.
至于从读卡器发送的指令到底是传递到NFC芯片还是SIM由NFC Controler控制,图中Secure Element是指SIM,Host-CPU指NFC芯片
android提供HostApduService用于NFC芯片,OffHostApduService用于SIM芯片,传递方向在res/xml文件中通过AID来控制
ps:Host-Based Card Emulator 简称为HCE
代码实现:
AndroidManifest.xml 中 配置service,因为作为卡实现的话,NFC功能是作为service存在的
<service android:name="com.shhic.nfcapp.NFCService" android:exported="true"
android:permission="android.permission.BIND_NFC_SERVICE">
<intent-filter>
<action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/>
</intent-filter>
<meta-data android:name="android.nfc.cardemulation.host_apdu_service"
android:resource="@xml/apduservice"/>
</service>
res/xml/apduservice.xml 中配置service响应的AID
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/servicedesc"
android:requireDeviceUnlock="false">
<aid-group android:description="@string/aiddescription"
android:category="other">
<aid-filter android:name="F0010203040506"/>
</aid-group>
</host-apdu-service>
配置文件完成后编写service的处理方法:
NFCService需要继承HostApduService,如果需要与Activity通信,建议采用广播方式
也可以自己实现观察者模式,只是这样就需要持有Activity的引用,感觉不太好
NFCService.java
public class NFCService extends HostApduService {
private Intent intent = new Intent("com.example.communication.RECEIVER");
@Override
public void onCreate()
{
//启动Acivity
Intent i = new Intent();
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//需要启动的Activity不是当前Activity的时候需要用FLAG_ACTIVITY_NEW_TASK
i.setAction("com.apdu.nfc");
getApplication().startActivity(i);
Toast.makeText(getApplicationContext(), "Service启动", Toast.LENGTH_LONG).show();
}
@Override
public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) {//当注册的AID被选中后,后续指令被分发到这个处理函数中
byte[] sw = new byte[]{(byte)0x90,(byte)0x00};
byte[] response = new byte[5];
if (commandApdu[0]==(byte)0x00 &&commandApdu[1]==(byte)0xA4&& commandApdu[2]==(byte)0x04
&& commandApdu[4]==(byte)0x07&& commandApdu[5]==(byte)0xF0)
{
return sw;
}
else
{
//apdu处理逻辑
switch(commandApdu[1])
{
case (byte)0xA8:
break;
case (byte)0xAE:
break;
default:
return sw;
}
}
intent.putExtra("command", commandApdu);
intent.putExtra("response", response);
sendBroadcast(intent); //利用广播与Activity通信
return response; //SW值需要包含在response中
}
@Override
public void onDeactivated(int reason) {
if (reason==HostApduService.DEACTIVATION_DESELECTED)
{
Toast.makeText(getApplicationContext(), "已选择其它应用", Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(getApplicationContext(), "连接断开", Toast.LENGTH_LONG).show();
}
}
@Override
public void onDestroy()
{
Toast.makeText(getApplicationContext(), "Service关闭", Toast.LENGTH_LONG).show();
super.onDestroy();
}
框架搭建好剩余的事情就很简单了,apdu的处理逻辑在processCommandApdu方法中实现即可
以上是Host-CPU方式的实现,SIM方式,API介绍中说该方式没有提供可供操作的API,也就是说Android不会监听SIM卡与读卡器之间的通信
所以NFCOffService 只需要实现onBind接口,这样绑定该Service的Activity可以对NFCOffService进行有限操作
public class NFCOffService extends OffHostApduService {
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
大家学习android开发建议首选android开发文档,该文档在你下载的sdk中,路径:/sdk/docs/index.html
目前NFC应用的大的框架上的理解:
我使用的API LEVEL是19,支持的API有三个:android.nfc,android.nfc.cardemulator,android.nfc.tech
NFC在手机上的应用大体分为两类:读卡器和卡
android.nfc.cardemulator接口是为NFC作为卡应用提供的接口,在较低版本的API上是没有的
android.nfc.tech,android.nfc接口是为NFC作为读卡器应用提供的接口
首先说作为卡,nfc有两种实现方式,一个是使用NFC芯片作为卡,另一个是使用SIM作为卡
Figure 1. NFC card emulation with a secure element.
至于从读卡器发送的指令到底是传递到NFC芯片还是SIM由NFC Controler控制,图中Secure Element是指SIM,Host-CPU指NFC芯片
android提供HostApduService用于NFC芯片,OffHostApduService用于SIM芯片,传递方向在res/xml文件中通过AID来控制
ps:Host-Based Card Emulator 简称为HCE
代码实现:
AndroidManifest.xml 中 配置service,因为作为卡实现的话,NFC功能是作为service存在的
<service android:name="com.shhic.nfcapp.NFCService" android:exported="true"
android:permission="android.permission.BIND_NFC_SERVICE">
<intent-filter>
<action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/>
</intent-filter>
<meta-data android:name="android.nfc.cardemulation.host_apdu_service"
android:resource="@xml/apduservice"/>
</service>
res/xml/apduservice.xml 中配置service响应的AID
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/servicedesc"
android:requireDeviceUnlock="false">
<aid-group android:description="@string/aiddescription"
android:category="other">
<aid-filter android:name="F0010203040506"/>
</aid-group>
</host-apdu-service>
配置文件完成后编写service的处理方法:
NFCService需要继承HostApduService,如果需要与Activity通信,建议采用广播方式
也可以自己实现观察者模式,只是这样就需要持有Activity的引用,感觉不太好
NFCService.java
public class NFCService extends HostApduService {
private Intent intent = new Intent("com.example.communication.RECEIVER");
@Override
public void onCreate()
{
//启动Acivity
Intent i = new Intent();
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//需要启动的Activity不是当前Activity的时候需要用FLAG_ACTIVITY_NEW_TASK
i.setAction("com.apdu.nfc");
getApplication().startActivity(i);
Toast.makeText(getApplicationContext(), "Service启动", Toast.LENGTH_LONG).show();
}
@Override
public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) {//当注册的AID被选中后,后续指令被分发到这个处理函数中
byte[] sw = new byte[]{(byte)0x90,(byte)0x00};
byte[] response = new byte[5];
if (commandApdu[0]==(byte)0x00 &&commandApdu[1]==(byte)0xA4&& commandApdu[2]==(byte)0x04
&& commandApdu[4]==(byte)0x07&& commandApdu[5]==(byte)0xF0)
{
return sw;
}
else
{
//apdu处理逻辑
switch(commandApdu[1])
{
case (byte)0xA8:
break;
case (byte)0xAE:
break;
default:
return sw;
}
}
intent.putExtra("command", commandApdu);
intent.putExtra("response", response);
sendBroadcast(intent); //利用广播与Activity通信
return response; //SW值需要包含在response中
}
@Override
public void onDeactivated(int reason) {
if (reason==HostApduService.DEACTIVATION_DESELECTED)
{
Toast.makeText(getApplicationContext(), "已选择其它应用", Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(getApplicationContext(), "连接断开", Toast.LENGTH_LONG).show();
}
}
@Override
public void onDestroy()
{
Toast.makeText(getApplicationContext(), "Service关闭", Toast.LENGTH_LONG).show();
super.onDestroy();
}
框架搭建好剩余的事情就很简单了,apdu的处理逻辑在processCommandApdu方法中实现即可
以上是Host-CPU方式的实现,SIM方式,API介绍中说该方式没有提供可供操作的API,也就是说Android不会监听SIM卡与读卡器之间的通信
所以NFCOffService 只需要实现onBind接口,这样绑定该Service的Activity可以对NFCOffService进行有限操作
public class NFCOffService extends OffHostApduService {
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories