title: Android HCE issue
body: <p>I'm working on my NFC-HCE project for Android. I stuck into a problem that my app doesn't recognize APDU SELECT Query.</p>
  
  <p>I'm using ACL122U reader powered by chrome-nfc with Forum Type 4 support and APDU_SELECT query goes like <em>00A4040007F039414848483500</em>. I checked it many time, there can't be error in AID. I tried to change several times, I found the working app on the Net which was working when I changed AID in my chrome-nfc. I guess there is something about manifest problem or service launching problem. I will appreciate any help.</p>
  
  <p><strong>AndroidManifest.xml</strong> </p>
  
  <pre><code>&lt;service android:name=".myHostApduService" 
                   android:exported="true"
                   android:permission="android.permission.BIND_NFC_SERVICE"&gt;
              &lt;intent-filter&gt;
                  &lt;action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/&gt;
              &lt;/intent-filter&gt;
              &lt;meta-data android:name="android.nfc.cardemulation.host_apdu_service"
                         android:resource="@xml/apduservice"/&gt;
          &lt;/service&gt;
  </code></pre>
  
  <p><strong>ApduService.xml</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
      android:description="@string/servicedesc"
      android:requireDeviceUnlock="false"&gt;
      &lt;aid-group android:description="@string/aiddescription"
          android:category="other"&gt;
  
          &lt;aid-filter android:name="F0394148484835"/&gt;
      &lt;/aid-group&gt;
  &lt;/host-apdu-service&gt;
  </code></pre>
  
  <p><strong>myHostApduService.java</strong></p>
  
  <pre><code>public class myHostApduService extends HostApduService {
  
      private static final String TAG = "myHostApduService";
  
  
      //
      private static final byte[] APDU_SELECT = {
              (byte)0x00, // CLA  - Class - Class of instruction
              (byte)0xA4, // INS  - Instruction - Instruction code
              (byte)0x04, // P1   - Parameter 1 - Instruction parameter 1
              (byte)0x00, // P2   - Parameter 2 - Instruction parameter 2
              (byte)0x07, // Lc field - Number of bytes present in the data field of the command
              (byte)0xF0, (byte)0x39, (byte)0x41, (byte)0x48, (byte)0x48, (byte)0x48, (byte)0x35, // NDEF Tag Application name
              (byte)0x00  // Le field - Maximum number of bytes expected in the data field of the response to the command
      };
  
      private static final byte[] CAPABILITY_CONTAINER = {
              (byte)0x00, // CLA  - Class - Class of instruction
              (byte)0xa4, // INS  - Instruction - Instruction code
              (byte)0x00, // P1   - Parameter 1 - Instruction parameter 1
              (byte)0x0c, // P2   - Parameter 2 - Instruction parameter 2
              (byte)0x02, // Lc field - Number of bytes present in the data field of the command
              (byte)0xe1, (byte)0x03 // file identifier of the CC file
      };
  
      private static final byte[] READ_CAPABILITY_CONTAINER = {
              (byte)0x00, // CLA  - Class - Class of instruction
              (byte)0xb0, // INS  - Instruction - Instruction code
              (byte)0x00, // P1   - Parameter 1 - Instruction parameter 1
              (byte)0x00, // P2   - Parameter 2 - Instruction parameter 2
              (byte)0x0f  // Lc field - Number of bytes present in the data field of the command
      };
  
      // In the scenario that we have done a CC read, the same byte[] match
      // for ReadBinary would trigger and we don't want that in succession
      private boolean READ_CAPABILITY_CONTAINER_CHECK = false;
  
      private static final byte[] READ_CAPABILITY_CONTAINER_RESPONSE = {
              (byte)0x00, (byte)0x0F, // CCLEN length of the CC file
              (byte)0x20, // Mapping Version 2.0
              (byte)0x00, (byte)0x3B, // MLe maximum 59 bytes R-APDU data size
              (byte)0x00, (byte)0x34, // MLc maximum 52 bytes C-APDU data size
              (byte)0x04, // T field of the NDEF File Control TLV
              (byte)0x06, // L field of the NDEF File Control TLV
              (byte)0xE1, (byte)0x04, // File Identifier of NDEF file
              (byte)0x00, (byte)0x32, // Maximum NDEF file size of 50 bytes
              (byte)0x00, // Read access without any security
              (byte)0x00, // Write access without any security
              (byte)0x90, (byte)0x00 // A_OKAY
      };
  
      private static final byte[] NDEF_SELECT = {
              (byte)0x00, // CLA  - Class - Class of instruction
              (byte)0xa4, // Instruction byte (INS) for Select command
              (byte)0x00, // Parameter byte (P1), select by identifier
              (byte)0x0c, // Parameter byte (P1), select by identifier
              (byte)0x02, // Lc field - Number of bytes present in the data field of the command
              (byte)0xE1, (byte)0x04 // file identifier of the NDEF file retrieved from the CC file
      };
  
      private static final byte[] NDEF_READ_BINARY_NLEN = {
              (byte)0x00, // Class byte (CLA)
              (byte)0xb0, // Instruction byte (INS) for ReadBinary command
              (byte)0x00, (byte)0x00, // Parameter byte (P1, P2), offset inside the CC file
              (byte)0x02  // Le field
      };
  
      private static final byte[] NDEF_READ_BINARY_GET_NDEF = {
              (byte)0x00, // Class byte (CLA)
              (byte)0xb0, // Instruction byte (INS) for ReadBinary command
              (byte)0x00, (byte)0x00, // Parameter byte (P1, P2), offset inside the CC file
              (byte)0x0f  //  Le field
      };
  
      private static final byte[] A_OKAY = {
              (byte)0x90,  // SW1 Status byte 1 - Command processing status
              (byte)0x00   // SW2 Status byte 2 - Command processing qualifier
      };
  
      private static final byte[] NDEF_ID = {
              (byte)0xE1,
              (byte)0x04
      };
  
      private NdefRecord NDEF_URI = new NdefRecord(
              NdefRecord.TNF_WELL_KNOWN,
              NdefRecord.RTD_TEXT,
              NDEF_ID,
              "Hello world, bitch!".getBytes(Charset.forName("UTF-8"))
      );
      private byte[] NDEF_URI_BYTES = NDEF_URI.toByteArray();
      private byte[] NDEF_URI_LEN = BigInteger.valueOf(NDEF_URI_BYTES.length).toByteArray();
  
      @Override
      public int onStartCommand(Intent intent, int flags, int startId) {
  
          if (intent.hasExtra("ndefMessage")) {
              NDEF_URI = new NdefRecord(
                      NdefRecord.TNF_WELL_KNOWN,
                      NdefRecord.RTD_TEXT,
                      NDEF_ID,
                      intent.getStringExtra("ndefMessage").getBytes(Charset.forName("UTF-8"))
              );
  
              NDEF_URI_BYTES = NDEF_URI.toByteArray();
              NDEF_URI_LEN = BigInteger.valueOf(NDEF_URI_BYTES.length).toByteArray();
  
              Context context = getApplicationContext();
              CharSequence text = "Your NDEF text has been set!";
              int duration = Toast.LENGTH_SHORT;
              Toast toast = Toast.makeText(context, text, duration);
              toast.setGravity(Gravity.CENTER, 0, 0);
              toast.show();
          }
  
          Log.i(TAG, "onStartCommand() | NDEF" + NDEF_URI.toString());
  
          return 0;
      }
  
      @Override
      public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) {
  
          //
          // The following flow is based on Appendix E "Example of Mapping Version 2.0 Command Flow"
          // in the NFC Forum specification
          //
          Log.i(TAG, "processCommandApdu() | incoming commandApdu: " + utils.bytesToHex(commandApdu));
  
          //
          // First command: NDEF Tag Application select (Section 5.5.2 in NFC Forum spec)
          //
          if (utils.isEqual(APDU_SELECT, commandApdu)) {
              Log.i(TAG, "APDU_SELECT triggered. Our Response: " + utils.bytesToHex(A_OKAY));
              return A_OKAY;
          }
  
          //
          // Second command: Capability Container select (Section 5.5.3 in NFC Forum spec)
          //
          if (utils.isEqual(CAPABILITY_CONTAINER, commandApdu)) {
              Log.i(TAG, "CAPABILITY_CONTAINER triggered. Our Response: " + utils.bytesToHex(A_OKAY));
              return A_OKAY;
          }
  
          //
          // Third command: ReadBinary data from CC file (Section 5.5.4 in NFC Forum spec)
          //
          if (utils.isEqual(READ_CAPABILITY_CONTAINER, commandApdu) &amp;&amp; !READ_CAPABILITY_CONTAINER_CHECK) {
              Log.i(TAG, "READ_CAPABILITY_CONTAINER triggered. Our Response: " + utils.bytesToHex(READ_CAPABILITY_CONTAINER_RESPONSE));
              READ_CAPABILITY_CONTAINER_CHECK = true;
              return READ_CAPABILITY_CONTAINER_RESPONSE;
          }
  
          //
          // Fourth command: NDEF Select command (Section 5.5.5 in NFC Forum spec)
          //
          if (utils.isEqual(NDEF_SELECT, commandApdu)) {
              Log.i(TAG, "NDEF_SELECT triggered. Our Response: " + utils.bytesToHex(A_OKAY));
              return A_OKAY;
          }
  
          //
          // Fifth command:  ReadBinary, read NLEN field
          //
          if (utils.isEqual(NDEF_READ_BINARY_NLEN, commandApdu)) {
  
              byte[] start = {
                      (byte)0x00
              };
  
              // Build our response
              byte[] response = new byte[start.length + NDEF_URI_LEN.length + A_OKAY.length];
  
              System.arraycopy(start, 0, response, 0, start.length);
              System.arraycopy(NDEF_URI_LEN, 0, response, start.length, NDEF_URI_LEN.length);
              System.arraycopy(A_OKAY, 0, response, start.length + NDEF_URI_LEN.length, A_OKAY.length);
  
              Log.i(TAG, response.toString());
              Log.i(TAG, "NDEF_READ_BINARY_NLEN triggered. Our Response: " + utils.bytesToHex(response));
  
              return response;
          }
  
          //
          // Sixth command: ReadBinary, get NDEF data
          //
          if (utils.isEqual(NDEF_READ_BINARY_GET_NDEF, commandApdu)) {
              Log.i(TAG, "processCommandApdu() | NDEF_READ_BINARY_GET_NDEF triggered");
  
              byte[] start = {
                      (byte)0x00
              };
  
              // Build our response
              byte[] response = new byte[start.length + NDEF_URI_LEN.length + NDEF_URI_BYTES.length + A_OKAY.length];
  
              System.arraycopy(start, 0, response, 0, start.length);
              System.arraycopy(NDEF_URI_LEN, 0, response, start.length, NDEF_URI_LEN.length);
              System.arraycopy(NDEF_URI_BYTES, 0, response, start.length + NDEF_URI_LEN.length, NDEF_URI_BYTES.length);
              System.arraycopy(A_OKAY, 0, response, start.length + NDEF_URI_LEN.length + NDEF_URI_BYTES.length, A_OKAY.length);
  
              Log.i(TAG, NDEF_URI.toString());
              Log.i(TAG, "NDEF_READ_BINARY_GET_NDEF triggered. Our Response: " + utils.bytesToHex(response));
  
              Context context = getApplicationContext();
              CharSequence text = "NDEF text has been sent to the reader!";
              int duration = Toast.LENGTH_SHORT;
              Toast toast = Toast.makeText(context, text, duration);
              toast.setGravity(Gravity.CENTER, 0, 0);
              toast.show();
  
              READ_CAPABILITY_CONTAINER_CHECK = false;
              return response;
          }
  
          //
          // We're doing something outside our scope
          //
          Log.wtf(TAG, "processCommandApdu() | I don't know what's going on!!!.");
          return "Can I help you?".getBytes();
      }
  
      @Override
      public void onDeactivated(int reason) {
          Log.i(TAG, "onDeactivated() Fired! Reason: " + reason);
      }
  }
  </code></pre>
  
  <p><strong>sendOverNfcActivity.java</strong></p>
  
  <pre><code>public class sendOverNFCActivity extends Activity{
  
      private static final String TAG = "sendOverNFCActivity";
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.sendnfc);
  
  
  
  
  
  
          Button setNdef = (Button) findViewById(R.id.set_ndef_button);
          setNdef.setOnClickListener(new View.OnClickListener() {
                                         @Override
                                         public void onClick(View view) {
  
                                             //
                                             // Technically, if this is past our byte limit,
                                             // it will cause issues.
                                             //
                                             // TODO: add validation
                                             //
                                             TextView getNdefString = (TextView) findViewById(R.id.ndef_text);
                                             String test = getNdefString.getText().toString();
  
                                             Intent intent = new Intent(getApplicationContext(), myHostApduService.class);
                                             intent.putExtra("ndefMessage", test);
                                             startService(intent);
                                         }
                                     }
          );
      }
  
      @Override
      public void onResume() {
          super.onResume();
      }
  
      @Override
      public void onPause() {
          super.onPause();
      }
  
      @Override
      public void onStop() {
          super.onStop();
      }
  
      @Override
      public void onDestroy() {
          super.onDestroy();
      }
  </code></pre>
  
  <p>The problem is that <code>public byte[] processCommandApdu(byte[] commandApdu, Bundle extras)</code> never runs and app sending 6a82 every time in response that mean file/app was not found. I totally can't understand why this happens even if AID is correct.</p>