android NFC开发学习笔记(2)

上一篇笔记主要是研究了NFC芯片作为卡片的应用场景以及实现

上文没有提到的就是,如果你需要使用NFC,需要在Manifest中申请NFC权限:

    <uses-permission android:name="android.permission.NFC" />
    <uses-feature android:name="android.hardware.nfc" android:required="true" />

现在来说说NFC芯片作为读卡器的应用场景以及实现

android.nfc.tech,android.nfc接口是为NFC作为读卡器应用提供的接口

接口定义了三种Action Tags:ACTION_NDEF_DISCOVEREDACTION_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
            android:name="com.shhic.nfcapp.POSActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="com.nfc.pos" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.nfc.action.TECH_DISCOVERED" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <meta-data android:name="android.nfc.action.TECH_DISCOVERED"
                android:resource="@xml/nfc_tech_filter" />
            <intent-filter>
                <action android:name="android.nfc.action.TAG_DISCOVERED" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

TECH_DISCOVERED还需要配置meta-data,meta-data的作用相当于补充说明或者一些配置信息

nfc_tech_filter.xml

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">

    <tech-list>

        <tech>android.nfc.tech.IsoDep</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcA</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcB</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcF</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcV</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.Ndef</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NdefFormatable</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.MifareClassic</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.MifareUltralight</tech>
    </tech-list>

</resources>
当然API中说明你可以将多个tech写在一个tech-list中,我做了尝试,这样做会引出一个问题,在程序未启动的情况下当手机刷卡时不会自动打开程序

如果想要自动打开需要按照上面这种写法,tech的个数可以根据你想要支持的卡类型进行调整


配置完成后,可以开始编写自己的Activity的java代码了

在onCreate方法中,需要获取NfcAdapter的引用,从名字可以看出这是一个适配器

   NfcAdapter nfcAdapter;
    PendingIntent pendingIntent;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        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(R.id.communication4Financy);
        
        nfcAdapter=NfcAdapter.getDefaultAdapter(this);
        
        pendingIntent = PendingIntent.getActivity(
                this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        
        onNewIntent(getIntent());
    }

这里使用PendingIntent,该Intent与普通的Intent不同的是它是有一个延迟启动的功能,它启动时会回调onNewIntent函数,这样能够实现NFC与Activity的交互

pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);的含义是将Intent传递给this Activity

在onPause与onResume中需要添加代码

    public void onPause() {
        super.onPause();
        nfcAdapter.disableForegroundDispatch(this);
    }

    public void onResume() {
        super.onResume();
        nfcAdapter.enableForegroundDispatch(this, pendingIntent, FILTERS, TECHLISTS);
    }

enableForegroundDispatch的作用是,当NFC事件发生时如果当前Activity不是注册了NFC action-filter的Activity,手机会显示注册了NFC事件的Activity供用户选择

如果当前Activity注册了NFC action 则将事件优先交由当前Activity处理。

onNewIntent实现:

    @Override
    public void onNewIntent(Intent intent) {
        Parcelable p = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        if (p==null)
        {
            return;
        }
        Tag nfcTag = (Tag)p;
        final IsoDep isodep = IsoDep.get(nfcTag);
//        final NfcA isodep = NfcA.get(nfcTag);
        final byte[] cmd = { (byte) 0x00, // CLA Class
                (byte) 0xB4, // INS Instruction
                (byte) 0x04, // P1 Parameter 1
                (byte) 0x00, // P2 Parameter 2
                (byte) 0x00, // Le
        };
        try {
            isodep.connect();
            byte[] reaponse=null;
            
            logWindow.append("00B4040000"+'\n');
            try {
                reaponse = isodep.getHistoricalBytes();
                logWindow.append(Util.bytes2HexString(reaponse)+'\n');

                reaponse =isodep.transceive(cmd);
                logWindow.append(Util.bytes2HexString(reaponse)+'\n');
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }finally{
            try {
                isodep.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

首先需要获取Tag,Tag是操作NFC的基础

        Parcelable p = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        if (p==null)
        {
            return;
        }
        Tag nfcTag = (Tag)p;

再将tag转换成特定的通讯协议

final IsoDep isodep = IsoDep.get(nfcTag);

连接读卡器:

 isodep.connect();

获取历史字节:

reaponse = isodep.getHistoricalBytes();

响应指令:

 reaponse =isodep.transceive(cmd);

最后断开连接:(断开动作应该在Activity关闭或者pause的时候发生)

finally{
            try {
                isodep.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

onNewIntent里面可以实现业务逻辑的处理以及UI

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值