欧美三级电影完整|亚洲一二三四久久|性爱视频精品一区二区免费在线观看|国产精品啪啪视频|婷婷六月综合操人妻视频网站|99爱免费视频在线观看|美女一级片在线观看|北京熟女88av|免费看黄色A级电影|欧美黄色毛片儿

Android NfcManager 之NFC接入與介紹

2023-04-12


NFC:全稱(chēng)是近場(chǎng)通信(Near Field Communication),是一種短距離無(wú)線技術(shù)


Android Beam是一個(gè)基于近場(chǎng)通信所做的新功能,這個(gè)功能可以為其他手機(jī)分享你正在使用的功能。 Android升級(jí)到4.1后,Android Beam現(xiàn)在可以在兩臺(tái)支持NFC的Android設(shè)備間分享照片和視頻,還可以與支持NFC的藍(lán)牙設(shè)備相連。


Android NFC同時(shí)支持三個(gè)主要的操作模式:

1.設(shè)備讀/寫(xiě)模式,允許NFC設(shè)備的讀/寫(xiě)NFC目標(biāo)設(shè)備;


2.P2P模式,使NFC設(shè)備與其他NFC節(jié)點(diǎn)交換數(shù)據(jù);這種運(yùn)作模式被使用在Android Beam中;


3/卡仿真模式,使NFC設(shè)備本身作為一個(gè)NFC卡。然后模擬NFC卡可以通過(guò)一個(gè)外部的NFC讀寫(xiě)訪問(wèn),如銷(xiāo)售終端NFC點(diǎn)。


4.NDEF數(shù)據(jù)

從NFC便簽讀取NDEF格式的數(shù)據(jù)
向NFC標(biāo)簽寫(xiě)入NDEF格式的數(shù)據(jù)
通過(guò)Android Beam技術(shù)將NDEF數(shù)據(jù)發(fā)送到另一部NFC設(shè)備


5.NFC的三重過(guò)濾機(jī)制intent-filter

兩個(gè)終端設(shè)備要想讀寫(xiě)數(shù)據(jù),會(huì)有個(gè)短暫配對(duì)的時(shí)間,數(shù)據(jù)接收端會(huì)根據(jù)具體的數(shù)據(jù)格式和標(biāo)簽類(lèi)型調(diào)用相應(yīng)的Activity(Tag Dispatch),這個(gè)activity需要定義一個(gè)intent filter中指定不同的過(guò)濾機(jī)制,分三個(gè)等級(jí),所以叫NFC的三重過(guò)濾機(jī)制


5.1NDEF_DISCOVERED

只過(guò)濾固定格式的NDEF數(shù)據(jù),比如純文本,指定協(xié)議(HTTP FTP SMB等)的URI


5.2TECH_DISCOVERED

當(dāng)ACTION_NDEF_DISCOVERED指定的過(guò)濾機(jī)制無(wú)法匹配Tag時(shí),就會(huì)使用這種過(guò)濾機(jī)制進(jìn)行匹配,這種過(guò)濾機(jī)制并不是通過(guò)Tag的數(shù)據(jù)進(jìn)行匹配的,而是根據(jù)Tag支持的數(shù)據(jù)存儲(chǔ)格式進(jìn)行匹配,因此這種機(jī)制使用范圍很廣


5.3TAG_DISCOVERED

這種機(jī)制用來(lái)處理未識(shí)別的Tag


接入流程:


1.首選NFC依賴(lài)硬件,這個(gè)就需要權(quán)限支持

外獲取NFC設(shè)備數(shù)據(jù)需要在內(nèi)添加如下內(nèi)容



    


nfc_tech_filter是在res/xml文件下的自定義xml文件:




    
        android.nfc.tech.IsoDep
    
    
        android.nfc.tech.NfcA
    

2.三種模式的Demo運(yùn)行


NFC的數(shù)據(jù)NfcAdapter來(lái)管理的,NfcAdapter有兩種途徑獲取



NfcManager manager=(NfcManager)getSystemService(Context.NFC_SERVICE);
NfcAdapter adapter=  manager.getDefaultAdapter();



這是通過(guò)NFCmanager獲取,



NfcManger的構(gòu)造器 也是通過(guò)NcfAdapter.getNfcAdapter(Context)獲取adapter的實(shí)例。


同理:我們也可以直接獲取NfcAdapter,不通過(guò)NfcManger來(lái)獲取。


NcfAdapter adapter=NfcAdapter.getDefaultAdapter(Context context)



這個(gè)adapter其實(shí)也是需要通過(guò)NfcManager來(lái)獲取,直接調(diào)用靜態(tài)方法,針對(duì)不熟悉getSystemService來(lái)說(shuō),可以直接使用封裝現(xiàn)成的。


adapter的內(nèi)部會(huì)有一個(gè):


static HashMap sNfcAdapters = new HashMap(); //guard by NfcAdapter.class


,所以NFC是獨(dú)立于Activity,因?yàn)閍dapter內(nèi)部有一個(gè)靜態(tài)變量,會(huì)把當(dāng)前山下文使用的nfcadapter緩存起來(lái)。


2.Tag接收頁(yè)面的啟動(dòng)模式


    
        AIN" />

        

        
    

    

launchMode:因?yàn)镹FC是一個(gè)獨(dú)立特性,所有頁(yè)面啟動(dòng)需要保持一個(gè),singleTask或者




singleTop




NdefMessage:

主要是描寫(xiě)敘述NDEF格式的信息


NdefRecord:

這個(gè)是秒速NDEF信息的一個(gè)信息段


這兩個(gè)都是Android NCF技術(shù)的核心類(lèi),不管是讀寫(xiě)NFC標(biāo)簽還是通過(guò)Android Beam技術(shù)傳遞數(shù)據(jù)都須要這兩個(gè)類(lèi)


小牛刀


1.獲取Tag對(duì)象

Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);


正常該intent通過(guò)Activity這個(gè)方法獲?。?/p>


protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    
}

因?yàn)槿魏雾?yè)面被打開(kāi)多少次,都會(huì)執(zhí)行onNewIntent方法


2.推斷NFC標(biāo)簽的數(shù)格式

Ndef ndef = Ndef.get(tag);


3.寫(xiě)入數(shù)據(jù)

ndef.wrriteNdefMessage(ndefMessage);


4.NdefRecord:NDEF格式數(shù)據(jù),創(chuàng)建對(duì)象提供如下

public static NdefRecord createApplicationRecord(String packageName)

public static NdefRecord createUri(Uri uri)

public static NdefRecord createUri(String uriString)

public static NdefRecord createMime(String mimeType, byte[] mimeData)

public static NdefRecord createExternal(String domain, String type, byte[] data) 

public static NdefRecord createTextRecord(String languageCode, String text) 

public NdefRecord(short tnf, byte[] type, byte[] id, byte[] payload)

public NdefRecord(byte[] data)
Uri支持格式如下:
private static final String[] URI_PREFIX_MAP = new String[] {
        "", // 0x00
        "http://www.", // 0x01
        "https://www.", // 0x02
        "http://", // 0x03
        "https://", // 0x04
        "tel:", // 0x05
        "mailto:", // 0x06
        "ftp://anonymous:anonymous@", // 0x07
        "ftp://ftp.", // 0x08
        "ftps://", // 0x09
        "sftp://", // 0x0A
        "smb://", // 0x0B
        "nfs://", // 0x0C
        "ftp://", // 0x0D
        "dav://", // 0x0E
        "news:", // 0x0F
        "telnet://", // 0x10
        "imap:", // 0x11
        "rtsp://", // 0x12
        "urn:", // 0x13
        "pop:", // 0x14
        "sip:", // 0x15
        "sips:", // 0x16
        "tftp:", // 0x17
        "btspp://", // 0x18
        "btl2cap://", // 0x19
        "btgoep://", // 0x1A
        "tcpobex://", // 0x1B
        "irdaobex://", // 0x1C
        "file://", // 0x1D
        "urn:epc:id:", // 0x1E
        "urn:epc:tag:", // 0x1F
        "urn:epc:pat:", // 0x20
        "urn:epc:raw:", // 0x21
        "urn:epc:", // 0x22
        "urn:nfc:", // 0x23
};

三、核心業(yè)務(wù)

1.action的校驗(yàn)

String action = intent.getAction();
        if (TextUtils.equals(action, NfcAdapter.ACTION_TAG_DISCOVERED)) {

            return true;
        }

2.讀

private void readNfcTag(Intent intent) {
    if (intent == null)
        return;
    Parcelable[] parcelables = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
    if (parcelables == null || parcelables.length == 0)
        return;
    NdefMessage mNdefMsg = (NdefMessage) parcelables[0];
    NdefRecord mNdefRecord = mNdefMsg.getRecords()[0];
    if (mNdefRecord != null) {

        try {
            String msg = new String(mNdefRecord.getPayload(), "utf-8");

        } catch (Exception e) {

        }

    }


}

3.寫(xiě)

//NFC寫(xiě)入
    private void writeNFC(Tag tag) {
        //null不執(zhí)行操作,強(qiáng)調(diào)敲代碼的邏輯性
        if (tag == null) {
            return;
        }

        NdefMessage ndefMessage = new NdefMessage(new NdefRecord[]{NdefRecord.createApplicationRecord(mPackNmae)});

        //獲得寫(xiě)入大小
        int size = ndefMessage.toByteArray().length;
        //2.推斷是否是NDEF標(biāo)簽
        try {
            Ndef ndef = Ndef.get(tag);
            if (ndef != null) {
                //說(shuō)明是NDEF標(biāo)簽,開(kāi)始連接
                ndef.connect();
                //推斷是否可寫(xiě)
                if (!ndef.isWritable()) {
                    showToast("當(dāng)前設(shè)備不支持寫(xiě)入");
                    return;
                }
                //推斷大小
                if (ndef.getMaxSize() < size) {
                    showToast("容量太小了");
                    return;
                }
                //寫(xiě)入
                ndef.writeNdefMessage(ndefMessage);

                showToast("寫(xiě)入成功");

            }
        } catch (Exception e) {
            e.printStackTrace();

        }
    }

加密卡芯片的讀寫(xiě)MifareClassic


MifareClassic:


“MIFARE Classic是恩智浦半導(dǎo)體開(kāi)發(fā)的可用于非接觸式智能卡,符合ISO/IEC 14443 A類(lèi)標(biāo)準(zhǔn)。用于公共交通票證等應(yīng)用,還可用于各類(lèi)其他應(yīng)用有S20,S50(M1),S70幾種規(guī)格,主要是根據(jù)存儲(chǔ)器容量劃分,存儲(chǔ)器容量分別有320B,1K,4K


這種卡和其他的不同,是有密碼校驗(yàn),不同廠家可以定制不同的密碼和數(shù)據(jù)格式,簡(jiǎn)單的介紹如下


Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        MifareClassic mifareClassic = MifareClassic.get(tag);
        try {
            boolean connected = mifareClassic.isConnected();
            if (connected) {
                int count = mifareClassic.getSectorCount();

                for (int index = 0; index < count; index++) {
                    //獲取善區(qū)數(shù)

                    boolean keyAopen = mifareClassic.authenticateSectorWithKeyA(index, MifareClassic.KEY_DEFAULT);
                    if (keyAopen) {
                        //獲取扇區(qū)里面塊的數(shù)量
                        int bCount = mifareClassic.getBlockCountInSector(index);
                        int bIndex = mifareClassic.sectorToBlock(index);
                        for (int position = 0; position < bCount; position++) {
                            byte[] data = mifareClassic.readBlock(bIndex + position);//進(jìn)行了讀卡
                            msgBuffer.append("塊" + (bIndex + position) + "數(shù)據(jù):").append(ByteArrayToHexString(data)).append("\r\n");

                            //修改KeyA和KeyB
                            if ((bIndex + position) == (4 * index + 3)) {
                                //將所有扇區(qū)的最后一個(gè)Block修改為111111111111ff078069111111111111
                                mifareClassic.writeBlock(bIndex + position, new byte[]{(byte) 0x11, (byte) 0x11, (byte) 0x11, (byte) 0x11, (byte) 0x11, (byte) 0x11, (byte) 0xff, 0x07, (byte) 0x80, (byte) 0x69, (byte) 0x11, (byte) 0x11, (byte) 0x11, (byte) 0x11, (byte) 0x11, (byte) 0x11});
//                                Log.e("onNewIntent:",(bIndex+position)+"塊加密成功");

                            }


                        }

                    }


                }

            }

        } catch (Exception e) {

        }

關(guān)于Mifare Classic也是用的比較多的地方,暫時(shí)先寫(xiě)到這,以后將會(huì)整理一份詳細(xì)的介紹。


本文僅代表作者觀點(diǎn),版權(quán)歸原創(chuàng)者所有,如需轉(zhuǎn)載請(qǐng)?jiān)谖闹凶⒚鱽?lái)源及作者名字。

免責(zé)聲明:本文系轉(zhuǎn)載編輯文章,僅作分享之用。如分享內(nèi)容、圖片侵犯到您的版權(quán)或非授權(quán)發(fā)布,請(qǐng)及時(shí)與我們聯(lián)系進(jìn)行審核處理或刪除,您可以發(fā)送材料至郵箱:service@tojoy.com