Android NFC读写Tag快速框架

作者: fengmlo | 来源:发表于2016-09-01 10:17 被阅读3976次

    这篇文章只讲NFC读写非接卡、读写标签的方式,且这里只讲符合TypeA和IsoDep技术标准的Tag,其他类型的Tag框架类似,只是有些许差别

    添加权限

    AndroidManifests.xml中添加:

    <uses-permission android:name="android.permission.NFC"/>
    

    添加intent filter

    AndroidManifests.xml中添加:

    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:launchMode="singleTask"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="adjustUnspecified|stateHidden">
        <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"/>
        </intent-filter>
    
        <meta-data
            android:name="android.nfc.action.TECH_DISCOVERED"
            android:resource="@xml/nfc_tech_filter"/>
    </activity>
    

    添加过滤列表

    res/xml文件夹下新建nfc_tech_filter.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <tech-list>
            <tech>android.nfc.tech.IsoDep</tech>
        </tech-list>
        <tech-list>
            <tech>android.nfc.tech.NfcA</tech>
        </tech-list>
    </resources>
    

    Activity

    先直接贴代码:

    public class MainActivity extends AppCompatActivity {
    
        // NFC相关
        private NfcAdapter nfcAdapter;
        private PendingIntent pendingIntent;
        public static String[][] TECHLISTS; //NFC技术列表
        public static IntentFilter[] FILTERS; //过滤器
    
        static {
            try {
                TECHLISTS = new String[][] { { IsoDep.class.getName() }, { NfcA.class.getName() } };
    
                FILTERS = new IntentFilter[] { new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED, "*/*") };
            } catch (Exception ignored) {
            }
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            nfcAdapter = NfcAdapter.getDefaultAdapter(this);
    
            pendingIntent = PendingIntent.getActivity(this, 0,
                    new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
    
            onNewIntent(getIntent());
        }
    
    
        //处理NFC触发
        @Override
        protected void onNewIntent(Intent intent) {
            //从intent中获取标签信息
            Parcelable p = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
            if (p != null) {
                Tag tag = (Tag) p;
                isodep = IsoDep.get(tag);
                if (isodep != null){
                    isoDep.connect(); // 建立连接
    
                    byte[] data = new byte[20];
                    byte[] response = isoDep.transceive(data); // 传送消息
    
                    isoDep.close(); // 关闭连接
                }
            }
        }
    
        //程序恢复
        @Override
        protected void onResume() {
            super.onResume();
            if (nfcAdapter != null) {
                // 这行代码是添加调度,效果是读标签的时候不会弹出候选程序,直接用本程序处理
                nfcAdapter.enableForegroundDispatch(this, pendingIntent, FILTERS, TECHLISTS); 
            }
        }
    
        //程序暂停
        @Override
        protected void onPause() {
            if (nfcAdapter != null)
                nfcAdapter.disableForegroundDispatch(this); // 取消调度
        }
    
    }
    

    使用NFC读写Tag主要流程是:
    设置系统调度 -> 系统调用onNewIntent(Intent intent) -> 获取Tag -> 获取读写通道 -> 进行读写 -> 最后取消系统调度

    读写Tag流程:

    • 建立连接
    • 读写
    • 关闭连接

    需要注意的是有些卡片关闭连接后再次建立连接会重置内部状态,具体参照卡片特性来定具体的读写方式。

    附一张系统的调度图:


    nfc_tag_dispatch.png

    参考链接

    官方API 指南

    相关文章

      网友评论

        本文标题:Android NFC读写Tag快速框架

        本文链接:https://www.haomeiwen.com/subject/krucettx.html