简体   繁体   中英

NFC Reader on Android

Hey guys I have a problem, I don't know how to fix this error...

I'm following a tutorial but when I pass a NFC card my app crashes.

The app passes the first if so the "Hello NFC!" appears on the screen but the next if is not passed, so I'm, trying to figure out with a Toast.

The error:

3341-3341/appnfc.francisco.discovertag E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: appnfc.francisco.discovertag, PID: 3341
java.lang.NullPointerException
at appnfc.francisco.discovertag.MyActivity.onNewIntent(MyActivity.java:70)
at android.app.Instrumentation.callActivityOnNewIntent(Instrumentation.java:1161)
at android.app.ActivityThread.deliverNewIntents(ActivityThread.java:2367)
at android.app.ActivityThread.performNewIntents(ActivityThread.java:2380)
at android.app.ActivityThread.handleNewIntent(ActivityThread.java:2389)
at android.app.ActivityThread.access$1600(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1317)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:212)
at android.app.ActivityThread.main(ActivityThread.java:5151)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:877)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
at dalvik.system.NativeStart.main(Native Method)

My app:

package appnfc.francisco.discovertag;

import java.util.List;

import org.ndeftools.Message;
import org.ndeftools.Record;
import org.ndeftools.externaltype.AndroidApplicationRecord;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.Vibrator;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;


public class MyActivity extends Activity
{

    private static final String TAG = MyActivity.class.getName();

    protected NfcAdapter nfcAdapter;
    protected PendingIntent nfcPendingIntent;

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

        // initialize NFC
        nfcAdapter = NfcAdapter.getDefaultAdapter(this);
        nfcPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, this.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
    }

    public void enableForegroundMode()
    {
        Log.d(TAG, "enableForegroundMode");

        IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED); // filter for all
        IntentFilter[] writeTagFilters = new IntentFilter[] {tagDetected};
        nfcAdapter.enableForegroundDispatch(this, nfcPendingIntent, writeTagFilters, null);
    }

    public void disableForegroundMode()
    {
        Log.d(TAG, "disableForegroundMode");

        nfcAdapter.disableForegroundDispatch(this);
    }

    @Override

    public void onNewIntent(Intent intent) {
        Log.d(TAG, "onNewIntent");

        if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction()))
        {

        TextView textView = (TextView) findViewById(R.id.title);

        textView.setText("Hello NFC!");

        Parcelable[]messages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
                Toast.makeText(getApplicationContext(),messages.toString(),Toast.LENGTH_SHORT).show();

            if (messages != null)
            {
                Log.d(TAG, "Found " + messages.length + " NDEF messages"); // is almost always just one

                vibrate(); // signal found messages :-)

                // parse to records
                for (int i = 0; i < messages.length; i++) {
                    try {
                        List<Record> records = new Message((NdefMessage)messages[i]);

                        Log.d(TAG, "Found " + records.size() + " records in message " + i);

                        for(int k = 0; k < records.size(); k++)
                        {
                            Log.d(TAG, " Record #" + k + " is of class " + records.get(k).getClass().getSimpleName());

                            Record record = records.get(k);

                            if(record instanceof AndroidApplicationRecord)
                            {
                             AndroidApplicationRecord aar =(AndroidApplicationRecord)record;
                             Log.d(TAG, "Package is " + aar.getDomain() + " " + aar.getType());
                            }

                        }
                    } catch (Exception e) {
                        Log.e(TAG, "Problem parsing message", e);
                    }

                }
            }
        } else {
            // ignore
        }
    }

    @Override
    protected void onResume()
    {
        Log.d(TAG, "onResume");

        super.onResume();

        enableForegroundMode();
    }

    @Override
    protected void onPause()
    {
        Log.d(TAG, "onPause");

        super.onPause();

        disableForegroundMode();
    }

    private void vibrate()
    {
        Log.d(TAG, "vibrate");

        Vibrator vibe = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE) ;

        vibe.vibrate(500);
    }
}

My manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="appnfc.francisco.discovertag"
        android:versionCode="1"
        android:versionName="1.0" >
    <uses-sdk android:minSdkVersion="14" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <!-- Near field communications permissions -->
    <uses-permission android:name="android.permission.NFC" />
    <uses-feature android:name="android.hardware.nfc" android:required="true" />
    <application
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name" >
        <activity
            android:name=".MyActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <data android:scheme="vnd.android.nfc" />
            </intent-filter>
        </activity>
    </application>
</manifest>

My activity:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        android:weightSum="1">
    <TextView
            android:id="@+id/title"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/hello" />
    <TextView
            android:id="@+id/teste"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/teste"
            android:layout_weight="0.15" />
</LinearLayout>

My target is to build an NFC reader, for example I pass the NFC card and I want to show on a field data from that card.

If your NFC tag does not contain an NDEF message,

intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)

will return null . Consequently, messages will be null and

if (messages != null) {
    ...
}

will not be executed. (Executing this would not make much sense anyways, as this code is specific to NDEF message processing.)

Now to your NullPointerException : For the Toast, you are using:

Toast.makeText(
    getApplicationContext(),
    messages.toString(),
    Toast.LENGTH_SHORT).show();

As messages is null , you cannot access messages.toString() . The null reference does not have a method toString() (or any other method as it's not pointing to an actual object instance). So this causes the exception.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM