XJohnnyyyx
XJohnnyyyx

Reputation: 15

Android: Receiving and processing NDEF records

What I've been trying to do is send an integer and receive it and then take that integer and set it to the timer that's counting down. So far I am able to send the integer and have the application open on the other device, However when the device loads the activity, it opens the MainActivity and not the Newgame activity. I must admit at this point I'm not code smart and a bit of a novice but here is the extract of code which deals with NFC Communication, This extract is from the Newgame.java:

@Override
public NdefMessage createNdefMessage(NfcEvent event) {
    int time = bomb1.getTimer();
    String message = ( " " + time);
    NdefMessage msg = new NdefMessage(
            new NdefRecord[] { NdefRecord.createMime(
                    "application/vnd.com.Jhadwin.passthebomb.newgame" ,message.getBytes())
                    ,NdefRecord.createApplicationRecord("com.Jhadwin.passthebomb")
    });
    return msg;
}    
@Override
public void onResume() {
    super.onResume();
    // Check to see that the Activity started due to an Android Beam
    if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
        processIntent(getIntent());
    }
}

@Override
public void onNewIntent(Intent intent) {
    // onResume gets called after this to handle the intent
    setIntent(intent);
}

/**
 * Parses the NDEF Message from the intent and prints to the TextView
 */
 void processIntent(Intent intent) {
    Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
            NfcAdapter.EXTRA_NDEF_MESSAGES);
    // only one message sent during the beam
    NdefMessage msg = (NdefMessage) rawMsgs[0];
    // record 0 contains the MIME type, record 1 is the AAR, if present
    String newtimermsg = new String(msg.getRecords()[0].getPayload());
    timeremtextview.setText(newtimermsg);
    int newtimer = Integer.parseInt(newtimermsg);
    bomb1.setTimer(newtimer);
    bomb1.setState(true);
}

As you may notice this code is adapted from the NFC example on the Google website, any help may be appreciated.

Also included is the application part of the AndroidManifest.xml

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.Jhadwin.passthebomb.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>            
    </activity>
    <activity android:name="com.Jhadwin.passthebomb.newgame"/>
    <activity android:name="com.Jhadwin.passthebomb.About"/>
    <activity android:name="com.Jhadwin.passthebomb.Help"/>
</application>

Upvotes: 1

Views: 1789

Answers (1)

Michael Roland
Michael Roland

Reputation: 40831

If you use an Android Application Record (AAR) and do not specify an NDEF_DISCOVERED intent filter in your app's manifest, Android won't know that you app can handle an NFC intent upon launching. Consequently, it will open the first activity from your manifest that declares a MAIN intent filter with category LAUNCHER without passing the received NDEF message. So in your case, com.Jhadwin.passthebomb.MainActivity will be used.

In order to get Android to pass an NFC intent (including the received NDEF message) to your newgame activity, you would need to add a proper intent filter:

<activity android:name="com.Jhadwin.passthebomb.newgame">
    <intent-filter>
        <action android:name="android.nfc.action.NDEF_DISCOVERED" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="application/vnd.com.jhadwin.passthebomb.newgame" />
    </intent-filter>
</activity>

Note that intent filters in Android are CASE-SENSITIVE. In order to avoid issues with mixed-case types, Android automatically converts MIME types and NFC Forum external type names to LOWER-CASE (usually such type names would be case-insensitive). Therefore, you have to specify the MIME type as all lower-case to achieve a match.

Besides that these are a few more suggestions:

  1. Android package names (and in Java package names in general) should use lower-case letters only. Class names (including activities) should start with an upper-case letter.

  2. Instead of creating your custom application-specific MIME types, you should prefer NFC Forum external types:

    NdefMessage msg = new NdefMessage(new NdefRecord[] {
        NdefRecord.createExternal(
            "jhadwin.com",          // your domain name
            "passthebomb.newgame",  // your type name
            message.getBytes()),    // payload
            NdefRecord.createApplicationRecord("com.jhadwin.passthebomb")
    });
    

    In that case you could use an intent filter like this:

    <activity android:name="com.jhadwin.passthebomb.NewGame">
        <intent-filter>
            <action android:name="android.nfc.action.NDEF_DISCOVERED" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:scheme="vnd.android.nfc" android:host="ext"
                  android:pathPrefix="/jhadwin.com:passthebomb.newgame" />
        </intent-filter>
    </activity>
    

Upvotes: 1

Related Questions