2017-03-22 12 views
0

私はAndroidスタジオでNFCタグ、特にMifareクラシックタグを読み書きするアプリケーションを開発しています。私は2016年初頭(1年前)にスマートフォン(S.O.KitKat)で開発してテストしました。ヌルオブジェクト参照で仮想メソッド 'void android.nfc.tech.MifareClassic.connect()'を呼び出そうとしています

私が言及したように、アプリケーションを脇に置いて、アンドロイドスタジオのバージョンを更新した後、SDKとS.O.私のスマートフォンからMarshMallowまで、このエラーはラベルに書き込もうとしているときに表示されます: "java.lang.NullPointerException:nullオブジェクトリファレンスで仮想メソッド 'void android.nfc.tech.MifareClassic.connect()'を呼び出そうとしています。

このエラーは、MifareClassicタグに接続しようとすると明らかに生成されます。

私の活動のコードは、私が考慮していないものと置き換えていくつかの部分を置き換えたものです。あなたがやっているとき

import android.annotation.SuppressLint; 
import android.app.Activity; 

import android.app.PendingIntent; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.nfc.FormatException; 
import android.nfc.NdefMessage; 
import android.nfc.NdefRecord; 
import android.nfc.NfcAdapter; 
import android.nfc.Tag; 
import android.nfc.tech.MifareClassic; 
import android.nfc.tech.Ndef; 
import android.nfc.tech.NdefFormatable; 
import android.os.Bundle; 
import android.view.View.OnClickListener; 
... 

import java.io.IOException; 
import java.io.UnsupportedEncodingException; 

@SuppressLint("Escribir") 
public class escribir extends Activity { 
    NfcAdapter adapter; 
    PendingIntent pendingIntent; 
    IntentFilter writeTagFilters[]; 
    boolean writeMode; 
    Tag myTag; 
    MifareClassic mfc; 
    Context context; 
    ... 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.activity_datospropietario); 
     context = this; 
     ... 

     Button btnWrite = (Button)findViewById(R.id.button); 
     final String b = getIntent().getExtras().getString("datos"); 

     btnWrite.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 

       final String mensaje = (b + ...); 

       if (first.getText().toString().isEmpty()) { 
        Toast.makeText(context, context.getString(R.string.missing_fields), Toast.LENGTH_SHORT).show(); 
       } else { 
        if (myTag == null) { 
         Toast.makeText(context, context.getString(R.string.error_notag), Toast.LENGTH_LONG).show(); 
        } else { 
        MifareClassic tmpMFC = null; 
        try { 
         tmpMFC = MifareClassic.get(myTag); 
        } catch (Exception e) { 
         Toast.makeText(context, context.getString(R.string.error_notag), Toast.LENGTH_LONG).show(); 
         e.printStackTrace(); 
        } 
        mfc = tmpMFC; 

        int sect; 
        if (mfc != null) { 
         sect = mfc.getSectorCount(); 
        } 
        try { 
         mfc.connect(); 
         ... 
        } catch (IOException e) { 
         Toast.makeText(context, context.getString(R.string.error_notag), Toast.LENGTH_LONG).show(); 
         e.printStackTrace(); 
         myTag = null; 
        } 
       } 
      } 
     }); 

     adapter = NfcAdapter.getDefaultAdapter(this); 
     pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); 
     IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED); 
     tagDetected.addCategory(Intent.CATEGORY_DEFAULT); 
     writeTagFilters = new IntentFilter[]{tagDetected}; 
    } 

    private void write(String text, Tag tag, int sector) throws IOException, FormatException { 

     NdefRecord[] records = {createRecord(text), NdefRecord.createApplicationRecord("my_app")}; 
     NdefMessage mensaje = new NdefMessage(records); 

     NdefFormatable formatable = NdefFormatable.get(tag); 

     if (formatable != null) { 
      formatable.connect(); 
      formatable.format(mensaje); 
      formatable.close(); 
     } else { 
      Ndef ndef = Ndef.get(tag); 
      ndef.connect(); 
      ndef.writeNdefMessage(mensaje); 
      ndef.close(); 
     } 

     MifareClassic mfc = MifareClassic.get(tag); 
     ... 
    } 

    @SuppressLint("Escribir") private NdefRecord createRecord(String text) throws UnsupportedEncodingException{ 
     String lang = "es"; 
     byte[] textBytes = text.getBytes(); 
     byte[] langBytes = lang.getBytes("US-ASCII"); 
     int langLength = langBytes.length; 
     int textLength = textBytes.length; 
     byte[] payLoad = new byte[1 + langLength + textLength]; 

     payLoad[0] = (byte) langLength; 

     System.arraycopy(langBytes, 0, payLoad, 1, langLength); 
     System.arraycopy(textBytes, 0, payLoad, 1 + langLength, textLength); 

     return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], payLoad); 
    } 

    @SuppressLint("Escribir") protected void onNewIntent(Intent intent){ 
     if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) { 
      myTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); 
     } 
    } 

    public void onPause(){ 
     super.onPause(); 
     WriteModeOff(); 
    } 
    public void onResume(){ 
     super.onResume(); 
     WriteModeOn(); 
    } 

    @SuppressLint("Escribir") private void WriteModeOn(){ 
     writeMode = true; 
     adapter.enableForegroundDispatch(this, pendingIntent, writeTagFilters, null); 
    } 

    @SuppressLint("Escribir") private void WriteModeOff(){ 
     writeMode = false; 
     adapter.disableForegroundDispatch(this); 
    } 
} 
+0

あなたは全体のエラーを投稿できますか?コードが完全に一致していないか、まったく間違っている呼び出しがあります。 – Olaia

+0

あなたの完全なstacktraceを投稿してください。あなたのコードに 'getShort'を呼び出す必要はありません。これは基本的なNPEのように見えるので、問題の内容を正確に示すために詳細情報を投稿しない限り、典型的なNPEの問題の重複として閉じられる可能性があります。 – njzk2

+0

こんにちは、私は答えとコメントがすぐに来るとは思わなかった。 私は、MifareClassicインスタンスからオブジェクトを初期化し、それをtry-catchステートメントで割り当てることによってコードを修正しました。また、mfcがnullでないことを保証するためにif-elseブロックに配置しました。 これで私はこのエラーを取り除きましたが、コードの後半で新しいtry-catch文の中でmfc.connectを作成しようとすると別の問題が発生しました。新しいエラーは次のとおりです。** nullオブジェクトリファレンスで仮想メソッド 'void android.nfc.tech.MifareClassic.connect()'を呼び出そうとしています** –

答えて

1

を行った後、ヌルであるかもしれないので、私が発見しましたHTCやSony Xperiaモデルなど、さまざまなデバイスでNFCタグの書き込み問題が発表されました。これらの問題は、AndroidバージョンをSDK 5.1(Lollipop)にアップグレードした後に表示されました。

この問題は、TechExtrasを要求してSAKがnullまたは間違った値を返したときに、異なるタグタイプが見つかったスタック順序を変更したために発生しました。次のように

私はこの見つかり詳細な説明は次のとおりです。

HTCワン:それはそうです、このバグの理由はNFCAのTechExtrasがnullです。 ただし、TechListにはMifareClassicが含まれています。

ソニーのXperia Z3(+ emmulated MIFAREクラシックタグ):バギータグが異なるSAK値(第2 NFCAの追加を伴う)MifareClassicとTechList二つNFCAを有しています。 2番目のNfcAとMifareClassicの両方のテクニックは、0x20のSAKを持っています。 MIFAREタグを識別するNXPのガイドライン(ページ11)に従って、これはMIFARE PlusまたはMIFARE DESFireタグです。このメソッドは、NfcAオカレンスの両方のSAK値をORDed(NXPのMIFAREタイプ識別プロシージャガイドで説明したとおり)して新しいエクストラを作成し、最初のNfcAのエクストラを新しいものに置き換えます。詳細については

https://github.com/ikarus23/MifareClassicTool/issues/52

を参照してください。そして、私の問題を修正bildinユーザーによって提案されたパッチください

public Tag patchTag(Tag oTag) 
{ 
    if (oTag == null) 
     return null; 

    String[] sTechList = oTag.getTechList(); 

    Parcel oParcel, nParcel; 

    oParcel = Parcel.obtain(); 
    oTag.writeToParcel(oParcel, 0); 
    oParcel.setDataPosition(0); 

    int len = oParcel.readInt(); 
    byte[] id = null; 
    if (len >= 0) 
    { 
     id = new byte[len]; 
     oParcel.readByteArray(id); 
    } 
    int[] oTechList = new int[oParcel.readInt()]; 
    oParcel.readIntArray(oTechList); 
    Bundle[] oTechExtras = oParcel.createTypedArray(Bundle.CREATOR); 
    int serviceHandle = oParcel.readInt(); 
    int isMock = oParcel.readInt(); 
    IBinder tagService; 
    if (isMock == 0) 
    { 
     tagService = oParcel.readStrongBinder(); 
    } 
    else 
    { 
     tagService = null; 
    } 
    oParcel.recycle(); 

    int nfca_idx=-1; 
    int mc_idx=-1; 

    for(int idx = 0; idx < sTechList.length; idx++) 
    { 
     if(sTechList[idx] == NfcA.class.getName()) 
     { 
      nfca_idx = idx; 
     } 
     else if(sTechList[idx] == MifareClassic.class.getName()) 
     { 
      mc_idx = idx; 
     } 
    } 

    if(nfca_idx>=0&&mc_idx>=0&&oTechExtras[mc_idx]==null) 
    { 
     oTechExtras[mc_idx] = oTechExtras[nfca_idx]; 
    } 
    else 
    { 
     return oTag; 
    } 

    nParcel = Parcel.obtain(); 
    nParcel.writeInt(id.length); 
    nParcel.writeByteArray(id); 
    nParcel.writeInt(oTechList.length); 
    nParcel.writeIntArray(oTechList); 
    nParcel.writeTypedArray(oTechExtras,0); 
    nParcel.writeInt(serviceHandle); 
    nParcel.writeInt(isMock); 
    if(isMock==0) 
    { 
     nParcel.writeStrongBinder(tagService); 
    } 
    nParcel.setDataPosition(0); 

    Tag nTag = Tag.CREATOR.createFromParcel(nParcel); 

    nParcel.recycle(); 

    return nTag; 
} 

は、このパッチは(https://github.com/bildin)をbildinによって提供されました。

私がテストしたデバイスは以前のブランドではありませんでしたが、このパッチはMoto X(第1世代)で修正されたROMマシュマロで完璧に機能しました。したがって、広範囲のデバイスThe NXP chip with PN544

0

誤りがあるかもしれない:

int sect = mfc.getSectorCount();

mfcはこの問題について、インターネットを調査した結果

MifareClassic mfc = MifareClassic.get(myTag); 
関連する問題