安卓NFC开发学习笔记讲述Word文档下载推荐.docx
- 文档编号:21843920
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:11
- 大小:87.13KB
安卓NFC开发学习笔记讲述Word文档下载推荐.docx
《安卓NFC开发学习笔记讲述Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《安卓NFC开发学习笔记讲述Word文档下载推荐.docx(11页珍藏版)》请在冰豆网上搜索。
exported="
true"
android:
permission="
android.permission.BIND_NFC_SERVICE"
>
intent-filter>
<
actionandroid:
android.nfc.cardemulation.action.HOST_APDU_SERVICE"
/>
/intent-filter>
meta-dataandroid:
android.nfc.cardemulation.host_apdu_service"
resource="
@xml/apduservice"
/service>
res/xml/apduservice.xml中配置service响应的AID
host-apdu-servicexmlns:
android="
description="
@string/servicedesc"
requireDeviceUnlock="
false"
aid-groupandroid:
@string/aiddescription"
category="
other"
aid-filterandroid:
F0010203040506"
/aid-group>
/host-apdu-service>
配置文件完成后编写service的处理方法:
NFCService需要继承HostApduService,如果需要与Activity通信,建议采用广播方式
也可以自己实现观察者模式,只是这样就需要持有Activity的引用,感觉不太好
NFCService.java
publicclassNFCServiceextendsHostApduService{
privateIntentintent=newIntent("
munication.RECEIVER"
);
@Override
publicvoidonCreate()
{
//启动Acivity
Intenti=newIntent();
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();
}
publicbyte[]processCommandApdu(byte[]commandApdu,Bundleextras){//当注册的AID被选中后,后续指令被分发到这个处理函数中
byte[]sw=newbyte[]{(byte)0x90,(byte)0x00};
byte[]response=newbyte[5];
if(commandApdu[0]==(byte)0x00&
&
commandApdu[1]==(byte)0xA4&
commandApdu[2]==(byte)0x04
commandApdu[4]==(byte)0x07&
commandApdu[5]==(byte)0xF0)
returnsw;
else
//apdu处理逻辑
switch(commandApdu[1])
case(byte)0xA8:
break;
case(byte)0xAE:
default:
intent.putExtra("
command"
commandApdu);
response"
response);
sendBroadcast(intent);
//利用广播与Activity通信
returnresponse;
//SW值需要包含在response中
publicvoidonDeactivated(intreason){
if(reason==HostApduService.DEACTIVATION_DESELECTED)
已选择其它应用"
连接断开"
@Override
publicvoidonDestroy()
{
Service关闭"
super.onDestroy();
}
框架搭建好剩余的事情就很简单了,apdu的处理逻辑在processCommandApdu方法中实现即可
以上是Host-CPU方式的实现,SIM方式,API介绍中说该方式没有提供可供操作的API,也就是说Android不会监听SIM卡与读卡器之间的通信
所以NFCOffService只需要实现onBind接口,这样绑定该Service的Activity可以对NFCOffService进行有限操作
publicclassNFCOffServiceextendsOffHostApduService{
publicIBinderonBind(Intentintent){
//TODOAuto-generatedmethodstub
returnnull;
上面没有提到的就是,如果你需要使用NFC,需要在Manifest中申请NFC权限:
uses-permissionandroid:
android.permission.NFC"
/>
uses-featureandroid:
android.hardware.nfc"
required="
现在来说说NFC芯片作为读卡器的应用场景以及实现
接口定义了三种ActionTags:
ACTION_NDEF_DISCOVERED,ACTION_TECH_DISCOVERED,ACTION_TAG_DISCOVERED。
当你在Manifest文件中将Activity的action-filter设置为这三个Tag中的一种或几种时,NFC响应事件会按照如图流程处理
我的理解是ACTION_NDEF_DISCOVERED是用于两台NFC手机之间传输文件的
ACTION_TECH_DISCOVERED,ACTION_TAG_DISCOVERED才是用于NFC与卡进行通讯的
所以开发第一步是在Manifest中配置你的Action:
activity
com.shhic.nfcapp.POSActivity"
label="
@string/app_name"
>
com.nfc.pos"
categoryandroid:
android.intent.category.DEFAULT"
android.nfc.action.TECH_DISCOVERED"
@xml/nfc_tech_filter"
android.nfc.action.TAG_DISCOVERED"
/activity>
TECH_DISCOVERED还需要配置meta-data,meta-data的作用相当于补充说明或者一些配置信息
nfc_tech_filter.xml
resourcesxmlns:
xliff="
urn:
oasis:
names:
tc:
xliff:
document:
1.2"
tech-list>
tech>
android.nfc.tech.IsoDep<
/tech>
/tech-list>
android.nfc.tech.NfcA<
android.nfc.tech.NfcB<
android.nfc.tech.NfcF<
android.nfc.tech.NfcV<
android.nfc.tech.Ndef<
android.nfc.tech.NdefFormatable<
android.nfc.tech.MifareClassic<
android.nfc.tech.MifareUltralight<
/resources>
当然API中说明你可以将多个tech写在一个tech-list中,我做了尝试,这样做会引出一个问题,在程序未启动的情况下当手机刷卡时不会自动打开程序
如果想要自动打开需要按照上面这种写法,tech的个数可以根据你想要支持的卡类型进行调整
配置完成后,可以开始编写自己的Activity的java代码了
在onCreate方法中,需要获取NfcAdapter的引用,从名字可以看出这是一个适配器
NfcAdapternfcAdapter;
PendingIntentpendingIntent;
@Override
protectedvoidonCreate(BundlesavedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.pos_main);
dc=(Button)findViewById(R.id.button4DC);
ecc=(Button)findViewById(R.id.button4ECC);
qpboc=(Button)findViewById(R.id.button4QPBOC);
logWindow=(TextView)findViewById(Rmunication4Financy);
nfcAdapter=NfcAdapter.getDefaultAdapter(this);
pendingIntent=PendingIntent.getActivity(
this,0,newIntent(this,getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),0);
onNewIntent(getIntent());
这里使用PendingIntent,该Intent与普通的Intent不同的是它是有一个延迟启动的功能,它启动时会回调onNewIntent函数,这样能够实现NFC与Activity的交互
pendingIntent=PendingIntent.getActivity(this,0,newIntent(this,getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),0);
的含义是将Intent传递给thisActivity
在onPause与onResume中需要添加代码
publicvoidonPause(){
super.onPause();
nfcAdapter.disableForegroundDispatch(this);
publicvoidonResume(){
super.onResume();
nfcAdapter.enableForegroundDispatch(this,pendingIntent,FILTERS,TECHLISTS);
enableForegroundDispatch的作用是,当NFC事件发生时如果当前Activity不是注册了NFCaction-filter的Activity,手机会显示注册了NFC事件的Activity供用户选择
如果当前Activity注册了NFCaction则将事件优先交由当前Activity处理。
onNewIntent实现:
publicvoidonNewIntent(Intentintent){
Parcelablep=intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
if(p==null)
return;
TagnfcTag=(Tag)p;
finalIsoDepisodep=IsoDep.get(nfcTag);
//
finalNfcAisodep=NfcA.get(nfcTag);
finalbyte[]cmd={(byte)0x00,//CLAClass
(byte)0xB4,//INSInstruction
(byte)0x04,//P1Parameter1
(byte)0x00,//P2Parameter2
(byte)0x00,//Le
};
try{
isodep.connect();
byte[]reaponse=null;
logWindow.append("
00B4040000"
+'
\n'
reaponse=isodep.getHistoricalBytes();
logWindow.append(Util.bytes2HexString(reaponse)+'
reaponse=isodep.transceive(cmd);
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(IOExceptione1){
e1.printStackTrace();
}finally{
isodep.close();
首先需要获取Tag,Tag是操作NFC的基础
Parcelablep=intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
再将tag转换成特定的通讯协议
连接读卡器:
获取历史字节:
rea
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- NFC 开发 学习 笔记 讲述