android - 适用于安卓系统的 ID Blue RFID 阅读器

标签 android nfc android-bluetooth rfid

我有一个 IDBlue RFID 阅读器 (IDBLUE-HF-70F3)。我还使用他们的 SDK 下载了示例 android 应用程序。 http://idblue.com/support/drivers-software.I可以将我的手机与读卡器配对,我的办公室身份证中有 RFID,所以我想尝试使用此 IDBLUE 读卡器从我的身份证中获取一些详细信息。但它显示读取失败。

我也尝试过 playstore 和 itunes 的官方 IDBLUE 应用程序,他们也没有运气。我对此完全陌生,有人可以帮助我继续前进吗

public class AndroidTestAppActivity extends ListActivity  implements ISessionHandler 
{   
    private static final RfidTag blankRfidTag = RfidTag.fromString("0000000000000000", Endianness.Msb);
    private static final String blockData_Ascii = "Data";
    private static final String blockData_Hex = "FF01CB99";

    private static final String READ_TAG_ID_MODE = "Read Tag ID";
    private static final String WRITE_READ_MULTIPLE_BLOCKS_MODE = "Write/Read Multiple Blocks";
    private static final String WRITE_READ_SINGLE_BLOCK_MODE = "Write/Read Single Block";   
    private static String mode = READ_TAG_ID_MODE;

    private static Boolean isHF = false;

    @Override
    public boolean onContextItemSelected(MenuItem item) 
    {
        mode = (String) item.getTitle();        
        return super.onContextItemSelected(item);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) 
    {
        if(sdk().isSessionOpen())
        {
            menu.setHeaderTitle("Select Test Mode:");
            menu.add(READ_TAG_ID_MODE);
            if(isHF)
            {
                menu.add(WRITE_READ_SINGLE_BLOCK_MODE);
                menu.add(WRITE_READ_MULTIPLE_BLOCKS_MODE);
            }
        }
        super.onCreateContextMenu(menu, v, menuInfo);
    }

    /**
     *  ResponseProcessor illustrates how to handle RFID tag id responses from IDBLUE.
     *  
     */
    class ResponseProcessor extends IDBlueProcessor
    {       
        @Override
        public void getRfidProtocolResponse(IDBlueCommand command,
                RfidProtocolProperty response) 
        {
            if(response.value() != RfidProtocol.EPC_GEN2)
            {
                isHF = true;
            }
        }

        @Override
        public void buttonPressResponse(IDBlueResponse response) 
        {           
            if (!sdk().beginCommands().successful()) 
            {
                return;
            }

            if(mode == READ_TAG_ID_MODE)
            {
                if(!readTagId().successful())
                {
                    OnFailure(READ_TAG_ID_MODE);
                }
            }
            else if(mode == WRITE_READ_SINGLE_BLOCK_MODE)
            {
                CByteArray blockData = CByteArray.createFromAsciiString(blockData_Ascii);
                if(!sdk().writeBlock(blankRfidTag, (short) 0, 
                        blockData).successful())
                {
                    OnFailure(WRITE_READ_SINGLE_BLOCK_MODE);
                }
            }
            else if(mode == WRITE_READ_MULTIPLE_BLOCKS_MODE)
            {
                if(!sdk().writeBlocks(blankRfidTag, (short) 0, (short) 2, 
                        new CByteArray(blockData_Hex + blockData_Hex)).successful())
                {
                    OnFailure(WRITE_READ_MULTIPLE_BLOCKS_MODE);
                }
            }
            else
            {
                sdk().endCommands(false);
            }
        }

        private void OnFailure(String mode) 
        {
            sdk().endCommands(false);
            setStatus(mode + " Failed");
        }

        private void OnSuccess(String mode, String details) 
        {
            sdk().endCommands(true);    
            String status = mode + " Succeeded";
            if(details.length() > 0)
            {
                status = status + ('\n' + details);
            }           
            setStatus(status);
        }

        @Override
        public void readBlockResponse(IDBlueCommand command, ReadBlockResponse response) 
        {           
            if(response.blockIndex() != 0 || 
                    !Arrays.equals(response.blockData().data(), CByteArray.createFromAsciiString(blockData_Ascii).data()))
            {
                OnFailure(WRITE_READ_SINGLE_BLOCK_MODE);
            }   
            else
            {
                OnSuccess(WRITE_READ_SINGLE_BLOCK_MODE, "");
            }
        }

        @Override
        public void readBlockFailed(IDBlueCommand command, NackResponse response) 
        {
            OnFailure(WRITE_READ_SINGLE_BLOCK_MODE);
        }

        @Override
        public void readBlocksResponse(IDBlueCommand command, ReadBlocksResponse response)
        {           
            if(response.blockIndex() != 0 || response.blockCount() != 2 ||
                    !Arrays.equals(response.blockData().data(), new CByteArray(blockData_Hex + blockData_Hex).data()))
            {
                OnFailure(WRITE_READ_MULTIPLE_BLOCKS_MODE);
            }   
            else
            {
                OnSuccess(WRITE_READ_MULTIPLE_BLOCKS_MODE, "");
            }
        }

        @Override
        public void readBlocksFailed(IDBlueCommand command, NackResponse response) 
        {
            OnFailure(WRITE_READ_MULTIPLE_BLOCKS_MODE);
        }







        /**
         * Callback method that is called when an RFID tag was successfully read by IDBLUE.
         * If a request was sent to IDBLUE to read the tag, then the response is said
         * to be synchronous. If however, the front button of IDBLUE is pressed, IDBLUE 
         * will send the tag id asynchronously (or async for short).
         */
        @Override
        public void readTagIdResponse(IDBlueCommand command, ReadTagIdResponse response) 
        {               
            // response.async() indicates whether the tag scan resulted from
            // a button press of IDBLUE (async), or from a call to readTagId (sync).
            String async = response.async() ? "Async Tag ID" : "Sync Tag ID";

            RfidTag tag = response.rfidTag();
            IDBlueTimestamp scanTime = response.timestamp();

            String tagId = tag.toString();
            String ts = scanTime.toString();

            OnSuccess(READ_TAG_ID_MODE, String.format("%s: %s, Timestamp: %s.", async, tagId, ts));         
        }

        /**
         * Callback method that is called when IDBLUE cannot find an RFID tag is response
         * to a synchronous read tag id request. readTagIdFailed will never be called
         * asynchronously since IDBLUE does not notify of asynchronous tag scan failures.
         *  
         */
        @Override
        public void readTagIdFailed(IDBlueCommand command, NackResponse response) 
        {  if(command!=null) {
            Log.e("readTagIdFailed", ""+command.message());
            Log.e("readTagIdFailed",  ""+command.name);
            Log.e("readTagIdFailed",  ""+command.toStringReversed());
            Log.e("readTagIdFailed", ""+ String.valueOf(command.info()));
            Log.e("readTagIdFailed", ""+ String.valueOf(command.status()));
            Log.e("readTagIdFailed",  ""+String.valueOf(command.successful()));
        }else {
            Log.e("command null","command null");
        }
            Log.e("********************************","&&&&&&&&&&&&&&&&&&&");
            if(response!=null) {
                Log.e("readTagIdFailed", ""+ String.valueOf(response.successful()));
                Log.e("readTagIdFailed", ""+ String.valueOf(response.failedCommand()));
                Log.e("readTagIdFailed", ""+ String.valueOf(response.info()));
                Log.e("readTagIdFailed",  ""+String.valueOf(response.infoLen()));
                Log.e("readTagIdFailed", ""+ String.valueOf(response.message()));
            }else
            {
                Log.e("response null","response null");
            }



            OnFailure(READ_TAG_ID_MODE);
        }

        @Override
        public void writeBlockResponse(IDBlueCommand command, WriteBlockResponse response) 
        {           
            if(response.blockIndex() != 0 || 
                    !sdk().readBlock(blankRfidTag, (short) 0).successful())
            {
                OnFailure(WRITE_READ_SINGLE_BLOCK_MODE);
            }           
        }

        @Override
        public void writeBlockFailed(IDBlueCommand command, NackResponse response) 
        {
            OnFailure(WRITE_READ_SINGLE_BLOCK_MODE);
        }

        @Override
        public void writeBlocksResponse(IDBlueCommand command, WriteBlocksResponse response)
        {                               
            if(response.blockIndex() != 0 || response.blockCount() != 2 || 
                    !sdk().readBlocks(blankRfidTag, (short) 0, (short) 2).successful())
            {
                OnFailure(WRITE_READ_MULTIPLE_BLOCKS_MODE);
            }   
        }

        @Override
        public void writeBlocksFailed(IDBlueCommand command, NackResponse response) 
        {
            OnFailure(WRITE_READ_MULTIPLE_BLOCKS_MODE);
        }       
    }

    /**
     * Updates the status label
     * @param status The test to assign to the status label
     */
    private void setStatus(String status) {
        // Display data/text of the item/row clicked
        Toast.makeText(this, status, Toast.LENGTH_SHORT).show();
    }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        BluetoothDevice[] devices = this.getPairedDevices();
        ArrayAdapter<BluetoothDevice> adapter = new ArrayAdapter<BluetoothDevice>(this,android.R.layout.simple_list_item_single_choice,devices);
        // Get the activity's ListView and set its choice mode as single choice
        getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        setListAdapter(adapter);
        registerForContextMenu(getListView());
        // Set the current TestAppActivity to listen for session events 
        sdk().addSessionHandler(this);

        // Hook up an async response processor, to process tag scans
        // from IDBLUE as a result of the front button being pressed.
        //
        // If you register a response handler, it will also receive 
        // synchronous responses. Be careful that you don't process
        // the same response multiple times. In this example, we'll
        // specify ASYNC_ONLY so that the TagIdProcessor registered
        // with addResponseHandler is listens for asynchronous responses,
        // and ignores synchronous responses.

        sdk().addResponseHandler(new ResponseProcessor());
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);

        // Get the data associated with selected item
        Object item = l.getItemAtPosition(position);

        // Display data/text of the item/row clicked
        setStatus("Selection: " + item.toString());

        BluetoothDevice device = (BluetoothDevice) item;
        close();

        Log.e("IDBLUE","onListItemClick: " +open(device));
    }

    /**
     * Get the instance of the IDBlueSdk that is used to communicate
     * with IDBLUE devices.
     * @return The one and only instance of IDBlueSdk
     */
    private IDBlueSdk sdk() {
        return IDBlueSdk.getInstance();
    }

    /**
     * Gets the list of all Bluetooth Devices that are paired with
     * the Android OS (via the Bluetooth Settings of the Android Device).
     * @return An array of Bluetooth Devices that are paired with the Android Device
     */
    private BluetoothDevice[] getPairedDevices() {
        return sdk().getPairedDevices();
    }

    /**
     * Get the IDBLUE device that's selected in the List View
     * @return The BluetoothDevice that's selected, null if no
     * deivce is selected
     */
    private BluetoothDevice selectedIDBlueDevice() {

        ListView list = this.getListView();
        View row;
        BluetoothDevice device;

        int count = list.getChildCount();
        for (int i = 0; i < count; i++) {

            row = (View)list.getChildAt(i);
            Object obj = row.getTag();
            if (obj instanceof BluetoothDevice) {
                device = (BluetoothDevice)obj;
                return device;
            }
        }

        return null;
    }

    /**
     * Open a session to the selected IDBLUE device
     * @return true if the session was opened, false otherwise
     */
    private boolean open() {
        return open(selectedIDBlueDevice());
    }

    /**
     * Open a session to the given IDBLUE device
     * @return true if the session was opened, false otherwise
     */
    private boolean open(BluetoothDevice device) {
        return sdk().open(device);
    }

    /**
     * Close the current session to IDBLUE
     * @return True if the session was closed, false otherwise
     */
    private boolean close() {
        sdk().setConnectedMode(ConnectedMode.TAGID);
        return sdk().close();
    }

    /**
     * Requests IDBLUE to scan for an RFID tag.
     * A few seconds later, IDBLUE will notify you of the results of the
     * tag scan via the readTagIdResponse, or the readTagIdFailed methods
     * of the registered TagIdProcessor
     * @return a SendStatus indicating whether the request was sent to IDBLUE
     */
    private SendStatus readTagId() {
        return sdk().readTagId();
    }

    /**
     * Requests IDBLUE to scan for an RFID tag.
     * A few seconds later, IDBLUE will notify you of the results of the
     * tag scan via the readTagIdResponse, or the readTagIdFailed methods
     * of the registered TagIdProcessor
     * @param processor An IDBlueProcessor object that will be notified of
     * once the RFID read tag id operation completes
     * @return a SendStatus indicating whether the request was sent to IDBLUE
     */
    private SendStatus readTagId(IDBlueProcessor processor ) {
        return sdk().readTagId(processor);
    }

    /**
     * onSessionCloseFailed is a method of ISessionHandler
     * that is called when closing of a session to an IDBLUE device fails. 
     */
    public void onSessionCloseFailed(IDBlueSession session) {   
    }

    /**
     * onSessionClosed is a method of ISessionHandler
     * that is called when a session to an IDBLUE device is closed. 
     */
    public void onSessionClosed(IDBlueSession session) {
        System.out.println("IDBLUE session closed");
    }

    /**
     * onSessionClosing is a method of ISessionHandler
     * that is called when a session to an IDBLUE device is closing. 
     */
    public void onSessionClosing(IDBlueSession session) {   
    }

    /**
     * onSessionOpenFailed is a method of ISessionHandler
     * that is called when opening of a session to an IDBLUE device fails. 
     */
    public void onSessionOpenFailed(IDBlueSession session) {
    }

    /**
     * onSessionOpenFailed is a method of ISessionHandler
     * that is called when a session to an IDBLUE device is opened successfully. 
     */
    public void onSessionOpened(IDBlueSession session) {
    System.out.println(String.format("Session to %s is now open", sdk().device().Name));
    isHF = false;
    sdk().getRfidProtocol();
    sdk().setConnectedMode(ConnectedMode.REACTIVE);
}

    /**
     * onSessionOpening is a method of ISessionHandler
     * that is called when a session to an IDBLUE device is opening. 
     */
    public void onSessionOpening(IDBlueSession session) {
    }



}

附上我收到读取失败消息后得到的日志

04-02 13:13:37.268    2087-2087/coders.com.idblue I/System.out﹕ TRACE: Received 1 bytes: 70
04-02 13:13:37.274    2087-2087/coders.com.idblue I/System.out﹕ TRACE: Received 7 bytes: 000070ff0000ff
04-02 13:13:37.274    2087-2087/coders.com.idblue I/System.out﹕ TRACE: Processed response: 70000070
04-02 13:13:37.275    2087-2087/coders.com.idblue I/System.out﹕ TRACE: Processed response: ff0000ff
04-02 13:13:37.275    2087-2087/coders.com.idblue I/System.out﹕ TRACE: Sent 80 command (80000080)
04-02 13:13:37.276    2087-2087/coders.com.idblue I/System.out﹕ TRACE: Sent 01 command (01000001)
04-02 13:13:37.392    2087-2087/coders.com.idblue I/System.out﹕ TRACE: Received 4 bytes: 80000080
04-02 13:13:37.392    2087-2087/coders.com.idblue I/System.out﹕ TRACE: Processed response: 80000080
04-02 13:13:41.537    2087-2087/coders.com.idblue I/System.out﹕ TRACE: Received 5 bytes: 1f00080104
04-02 13:13:41.544    2087-2087/coders.com.idblue I/System.out﹕ TRACE: Received 7 bytes: 2c010100023a06
04-02 13:13:41.545    2087-2087/coders.com.idblue I/System.out﹕ TRACE: Processed response: 1f000801042c010100023a06
04-02 13:13:41.546    2087-2087/coders.com.idblue E/readTagIdFailed﹕ null
04-02 13:13:41.546    2087-2087/coders.com.idblue E/readTagIdFailed﹕ Read Tag ID
04-02 13:13:41.546    2087-2087/coders.com.idblue E/readTagIdFailed﹕ 01000001
04-02 13:13:41.546    2087-2087/coders.com.idblue E/readTagIdFailed﹕ null
04-02 13:13:41.546    2087-2087/coders.com.idblue E/readTagIdFailed﹕ 0
04-02 13:13:41.546    2087-2087/coders.com.idblue E/readTagIdFailed﹕ true
04-02 13:13:41.547    2087-2087/coders.com.idblue E/********************************﹕ &&&&&&&&&&&&&&&&&&&
04-02 13:13:41.547    2087-2087/coders.com.idblue E/readTagIdFailed﹕ false
04-02 13:13:41.549    2087-2087/coders.com.idblue E/readTagIdFailed﹕ 1
04-02 13:13:41.550    2087-2087/coders.com.idblue E/readTagIdFailed﹕ 2c010100023a
04-02 13:13:41.550    2087-2087/coders.com.idblue E/readTagIdFailed﹕ 6
04-02 13:13:41.550    2087-2087/coders.com.idblue E/readTagIdFailed﹕ null
04-02 13:13:41.556    2087-2087/coders.com.idblue I/System.out﹕ TRACE: Sent 88 command (8800010089)
04-02 13:13:41.933    2087-2087/coders.com.idblue I/System.out﹕ TRACE: Received 4 bytes: 88000088
04-02 13:13:41.934    2087-2087/coders.com.idblue I/System.out﹕ TRACE: Processed response: 88000088

最佳答案

我查看了 IDBlue HF/UHF 数据表。它列出了支持的 RFid 标准,ISO 14443 不在其中。您办公室的 ID 卡很可能遵循该标准,所以这可能就是 IDBlue 读卡器无法检测到它的原因。 如果你有一部支持 NFC 的 Android 手机,很容易确认:安装一个 NFC 诊断应用程序(我通常使用 NXP TagInfo,https://play.google.com/store/apps/details?id=com.nxp.taginfolite&hl=en)并用它来验证你的办公室 ID 卡的技术。

关于android - 适用于安卓系统的 ID Blue RFID 阅读器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29407668/

相关文章:

java - 无法将空 subview 添加到 ViewGroup,尽管已为 'child view' 提供了一个值

android - 如何通过 NFC 将文本字符串发送到另一台设备?

java - 在 Android 中发现标签时如何识别 mifare classic 和 mifare ultralight

delphi - MIFARE DESFire EV1 身份验证问题

android - 我可以知道制造商配对的蓝牙设备型号吗?

android - 删除 jetpack compose 文本字段上的默认填充

java - Android TabLayout 崩溃

java - SQLite 与列表

android - 什么是蓝牙?

bluetooth-lowenergy - 通过 BLE 传输大数据 block 的最佳方法