Android上的NFC阅读器

时间:2014-07-11 09:17:34

标签: android android-intent nullpointerexception nfc ndef

嘿伙计我有问题,我不知道如何解决这个错误...

我关注了一个教程但是当我通过NFC卡时,我的应用程序崩溃了。

该应用程序通过了第一个if所以" Hello NFC!"屏幕上显示,但下一个if未通过,所以我试图用吐司找出来。

错误:

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)

我的应用:

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);
    }
}

我的清单:

<?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>

我的活动:

<?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>

我的目标是建立一个NFC阅读器,例如我通过NFC卡,我想显示该卡的现场数据。

1 个答案:

答案 0 :(得分:2)

如果您的NFC标签不包含NDEF消息,

intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)

将返回null。因此,messages将为null

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

执行。 (执行此操作无论如何都没有多大意义,因为此代码特定于NDEF消息处理。)

现在到你的NullPointerException:对于Toast,你正在使用:

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

由于messagesnull,您无法访问messages.toString()null引用没有方法toString()(或任何其他方法,因为它没有指向实际的对象实例)。所以这会导致异常。