2015-06-15 12 views
5

Tôi hiện đang làm việc trên một dự án Android cần tích hợp NFC. Bây giờ tôi muốn viết một số (j) kiểm tra đơn vị để xem ứng dụng có thể nhận được các ý định NFC (cụ thể là ACTION_TECH_DISCOVERED) và đặt thẻ đã cho (trong NfcAdapter.EXTRA_TAG) trên một hệ thống xe buýt hay không. Tuy nhiên với sự ngạc nhiên của tôi, tôi không thể tạo ra một cá thể Tag hoặc mô phỏng. Ai đó có thể giải thích cho tôi làm thế nào tôi có thể (đơn vị) thử nghiệm?Cách tạo đối tượng Thẻ NFC Android để kiểm tra đơn vị

Tại thời điểm này, tôi thậm chí sẽ chấp nhận một hình thức thử nghiệm tích hợp, quá trình:

  1. Detect NFC Ý định
  2. Lấy đối tượng Tag
  3. Đặt nó trên xe buýt bọc trong một CardDetectedEvent .

Tôi có điện thoại hỗ trợ NFC và một vài thẻ để thử nghiệm.

Android SDK phiên bản: 19
Libraries sử dụng: robolectric, junit và Mockito

Trả lời

7

Có thể tạo đối tượng thẻ mô phỏng bằng cách sử dụng phản chiếu (lưu ý rằng đây không phải là một phần của SDK Android công khai, do đó có thể không thành công cho các phiên bản Android trong tương lai).

  1. Lấy createMockTag() phương pháp mặc dù phản ánh:

    Class tagClass = Tag.class; 
    Method createMockTagMethod = tagClass.getMethod("createMockTag", byte[].class, int[].class, Bundle[].class); 
    
  2. Xác định một số hằng số để chuẩn bị thẻ dụ giả:

    final int TECH_NFC_A = 1; 
    final String EXTRA_NFC_A_SAK = "sak"; // short (SAK byte value) 
    final String EXTRA_NFC_A_ATQA = "atqa"; // byte[2] (ATQA value) 
    
    final int TECH_NFC_B = 2; 
    final String EXTRA_NFC_B_APPDATA = "appdata"; // byte[] (Application Data bytes from ATQB/SENSB_RES) 
    final String EXTRA_NFC_B_PROTINFO = "protinfo"; // byte[] (Protocol Info bytes from ATQB/SENSB_RES) 
    
    final int TECH_ISO_DEP = 3; 
    final String EXTRA_ISO_DEP_HI_LAYER_RESP = "hiresp"; // byte[] (null for NfcA) 
    final String EXTRA_ISO_DEP_HIST_BYTES = "histbytes"; // byte[] (null for NfcB) 
    
    final int TECH_NFC_F = 4; 
    final String EXTRA_NFC_F_SC = "systemcode"; // byte[] (system code) 
    final String EXTRA_NFC_F_PMM = "pmm";  // byte[] (manufacturer bytes) 
    
    final int TECH_NFC_V = 5; 
    final String EXTRA_NFC_V_RESP_FLAGS = "respflags"; // byte (Response Flag) 
    final String EXTRA_NFC_V_DSFID = "dsfid";   // byte (DSF ID) 
    
    final int TECH_NDEF = 6; 
    final String EXTRA_NDEF_MSG = "ndefmsg";    // NdefMessage (Parcelable) 
    final String EXTRA_NDEF_MAXLENGTH = "ndefmaxlength"; // int (result for getMaxSize()) 
    final String EXTRA_NDEF_CARDSTATE = "ndefcardstate"; // int (1: read-only, 2: read/write, 3: unknown) 
    final String EXTRA_NDEF_TYPE = "ndeftype";   // int (1: T1T, 2: T2T, 3: T3T, 4: T4T, 101: MF Classic, 102: ICODE) 
    
    final int TECH_NDEF_FORMATABLE = 7; 
    
    final int TECH_MIFARE_CLASSIC = 8; 
    
    final int TECH_MIFARE_ULTRALIGHT = 9; 
    final String EXTRA_MIFARE_ULTRALIGHT_IS_UL_C = "isulc"; // boolean (true: Ultralight C) 
    
    final int TECH_NFC_BARCODE = 10; 
    final String EXTRA_NFC_BARCODE_BARCODE_TYPE = "barcodetype"; // int (1: Kovio/ThinFilm) 
    
  3. Tạo bó tech-extras cho loại thẻ của bạn . Ví dụ, đối với một NFC Thẻ với một thông báo NDEF:

    Bundle nfcaBundle = new Bundle(); 
    nfcaBundle.putByteArray(EXTRA_NFC_A_ATQA, new byte[]{ (byte)0x44, (byte)0x00 }); //ATQA for Type 2 tag 
    nfcaBundle.putShort(EXTRA_NFC_A_SAK , (short)0x00); //SAK for Type 2 tag 
    
    Bundle ndefBundle = new Bundle(); 
    ndefBundle.putInt(EXTRA_NDEF_MAXLENGTH, 48); // maximum message length: 48 bytes 
    ndefBundle.putInt(EXTRA_NDEF_CARDSTATE, 1); // read-only 
    ndefBundle.putInt(EXTRA_NDEF_TYPE, 2); // Type 2 tag 
    NdefMessage myNdefMessage = ...; // create an NDEF message 
    ndefBundle.putParcelable(EXTRA_NDEF_MSG, myNdefMessage); // add an NDEF message 
    
  4. Chuẩn bị một định chống va chạm/UID cho thẻ của bạn (xem Tag.getId() phương pháp). Ví dụ. 7 byte-UID cho một thẻ Loại 2:

    byte[] tagId = new byte[] { (byte)0x3F, (byte)0x12, (byte)0x34, (byte)0x56, (byte)0x78, (byte)0x90, (byte)0xAB }; 
    
  5. Sau đó, bạn có thể tạo ra một phiên bản thẻ giả bằng cách gọi các createMockTag() phương pháp

    Tag mockTag = (Tag)createMockTagMethod.invoke(null, 
         tagId,          // tag UID/anti-collision identifier (see Tag.getId() method) 
         new int[] { TECH_NFC_A, TECH_NDEF },  // tech-list 
         new Bundle[] { nfcaBundle, ndefBundle }); // array of tech-extra bundles, each entry maps to an entry in the tech-list 
    

Khi bạn đã tạo mà đối tượng thẻ giả , bạn có thể gửi nó như một phần của ý định khám phá NFC. Ví dụ. cho một ý định TECH_DISCOVERED:

Intent techIntent = new Intent(NfcAdapter.ACTION_TECH_DISCOVERED); 
techIntent.putExtra(NfcAdapter.EXTRA_ID, tagId); 
techIntent.putExtra(NfcAdapter.EXTRA_TAG, mockTag); 
techIntent.putExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, new NdefMessage[]{ myNdefMessage }); // optionally add an NDEF message 

Sau đó bạn có thể gửi ý định này để hoạt động của bạn:

techIntent.setComponent(...); // or equivalent to optionally set an explicit receiver 
startActivity(techIntent); 

Người nhận thậm chí có thể sử dụng đối tượng thẻ giả để lấy trường hợp của các lớp học công nghệ.Tuy nhiên, bất kỳ phương thức nào yêu cầu thao tác IO sẽ thất bại.

0

Tôi không nghĩ rằng nó có thể để chế nhạo những ý đồ vì đây là những bị sa thải bởi NFCService và không có quyền hệ thống nó không thể bắn những ý định này và hiện tại không có hỗ trợ trong khung android để giả lập các thẻ nfc.

Các vấn đề liên quan