NFC and MIME TYPE case sensitive

2019-06-27 22:56发布

问题:

I'm attempting just the basic version of NFC, but then I discovered that MIME TYPE is case sensitive. The package name for my app has one capital letter.

Package name: com.example.Main_Activity

<intent-filter>
  <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
  <category android:name="android.intent.category.DEFAULT"/>
  <data android:mimeType="application/com.example.Main_Activity"/>
</intent-filter>

Does anyone know a way around it?

Thanks

回答1:

MIME types are case-insensitive as per the RFC. However, Android's intent filter matiching is case-sensitive. In order to overcome this problem you should always use lower-case MIME types only.

Specifically with the Android NFC API's MIME type record helper methods, MIME types will automatically be converted to lower-case letters only. So calling the method NdefRecord.createMime() with a mixed-case type name will always result into the creation of a lower-case only MIME type name. E.g.

NdefRecord r1 = NdefRecord.createMime("text/ThisIsMyMIMEType", ...);
NdefRecord r2 = NdefRecord.createMime("text/tHISiSmYmimetYPE", ...);
NdefRecord r3 = NdefRecord.createMime("text/THISISMYMIMETYPE", ...);
NdefRecord r4 = NdefRecord.createMime("text/thisismymimetype", ...);

will all result into the creation of the same MIME type record type:

+----------------------------------------------------------+
| MIME:text/thisismymimetype | ...                         |
+----------------------------------------------------------+

So your intent filter will also need to be all-lower-case letters:

<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="text/thisismymimetype" />
</intent-filter>


回答2:

It drove me insane for a week. I finally got it. Even though my package name has capital letter in it. You must write your MIME TYPE in small letters in your codes and in your intent filter. I know in realty they're not the same package however MIME TYPE in NFC will still recognize your app. Just make sure to write the correct package when you create application record. If you notice i had to use the correct package name which include CAPS. Otherwise your application won't be found.

Hope this help others.

public NdefMessage createNdefMessage(NfcEvent event) {
        String text = ("Beam me up, Android!\n\n" +
                "Beam Time: " + System.currentTimeMillis());
        NdefMessage msg = new NdefMessage(
                new NdefRecord[] { NdefRecord.createMime(
                        "application/com.example.main_activity", text.getBytes())
         /**
          * The Android Application Record (AAR) is commented out. When a device
          * receives a push with an AAR in it, the application specified in the AAR
          * is guaranteed to run. The AAR overrides the tag dispatch system.
          * You can add it back in to guarantee that this
          * activity starts when receiving a beamed message. For now, this code
          * uses the tag dispatch system.
          */
          ,NdefRecord.createApplicationRecord("com.example.Main_Activity")
        });
        return msg;
    }
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="application/com.example.main_activity"/>
</intent-filter>