Question

I have an app with 2 classes, I need my app to open the second class CardActivity when the NFC tag tapped/swiped. The app opens fine, but MainActivity is run, instead of CardActivity.

I would hazard a guess that this is an issue with my manifest, but it looks correct. Here it is regardless:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.spotsofmagic.spotsofmagic"
    android:versionCode="1"
    android:versionName="1.0" android:installLocation="auto">

    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="14" />

    <uses-permission android:name="android.permission.NFC" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-feature android:name="android.hardware.nfc" android:required="true" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >

        <activity
            android:name=".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=".CardActivity"
            android:label="@string/app_name" >

            <!-- Handle a collectable card NDEF record -->
            <intent-filter>
                <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
                <data android:mimeType="application/vnd.spotsofmagic.spotsofmagic"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
         </activity>

    </application>

</manifest>

I'm confident the tag itself is correct, as I have opened it in another app to view it's contents.

Below are the two classes.

CardActivity:

package com.spotsofmagic.spotsofmagic;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.bluetooth.*;

public class CardActivity extends Activity implements OnClickListener {

    private static final String TAG = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.card_activity);

        // see if app was started from a tag and show game console
        Intent intent = getIntent();

        Log.e(TAG, "Hello world.  Intent Type: "+ intent.getType());

        if(intent.getType() != null && intent.getType().equals(MimeType.NFC_DEMO)) {
            Parcelable[] rawMsgs = getIntent().getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
            NdefMessage msg = (NdefMessage) rawMsgs[0];
            NdefRecord cardRecord = msg.getRecords()[0];
            String payload = new String(cardRecord.getPayload());
            turnBluetoothOn(payload);
        }
    }

    private void turnBluetoothOn(String payload) {

        final AlertDialog.Builder builder=new AlertDialog.Builder(this);
        builder.setTitle("Alert Dialog");
        builder.setMessage(payload);
        builder.setIcon(android.R.drawable.ic_dialog_alert);


        BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter == null) {
            // Device does not support Bluetooth
        }
        if (!mBluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, 1);
        }
        android.os.Process.killProcess(android.os.Process.myPid());

    }

    public void onClick(DialogInterface dialog, int which) {
        // TODO Auto-generated method stub

    }
}

MainActivity:

package com.spotsofmagic.spotsofmagic;

import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.widget.TextView;


public class MainActivity extends Activity implements OnClickListener {
    private static final String TAG = "Activity...";
    private NfcAdapter mAdapter;
    private TextView mTextView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);

        // grab our NFC Adapter
        mAdapter = NfcAdapter.getDefaultAdapter(this);

        // TextView that we'll use to output messages to screen
        mTextView = (TextView)findViewById(R.id.text_view);

        displayMessage("Loading payload...");

    }

    private void displayMessage(String message) {
        mTextView.setText(message);
    }

    public void onClick(DialogInterface arg0, int arg1) {
        // TODO Auto-generated method stub

    }
}

Here is the code I used to write the tag. This is done on a different app incidentally:

NdefRecord appRecord = NdefRecord.createApplicationRecord("com.spotsofmagic.spotsofmagic");

        // record that contains our custom "retro console" game data, using custom MIME_TYPE
        byte[] payload = getPayload().getBytes();
        byte[] mimeBytes = MimeType.NFC_DEMO.getBytes(Charset.forName("US-ASCII"));
        NdefRecord cardRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA, mimeBytes, 
                                                new byte[0], payload);
        NdefMessage message = new NdefMessage(new NdefRecord[] { cardRecord, appRecord});

// Some code here removed for readability


 Ndef ndef = Ndef.get(tag);
    if (ndef != null) {
        ndef.connect();
        ndef.writeNdefMessage(message);
Was it helpful?

Solution

Does the NDEF message on the tag contain an Android Application Record? That could explain how MainActivity is launched. However, that can only be the cause if the AAR is the first record of the NDEF message on the tag or if the first record does not match the intent filter.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top