2011-05-28 93 views
2

我是開發android應用程序的新手。目前我正試圖開發自己的標籤閱讀器,可以閱讀MiFare Ultralight標籤。NFC讀取不起作用

BUt由於NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)始終返回false,因此未能讀取標記。有人能幫我嗎?

NfcReader.java

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    mText = (TextView) findViewById(R.id.text); 
    mText.setText("Scan a tag"); 

    mAdapter = NfcAdapter.getDefaultAdapter(); 

    // Create a generic PendingIntent that will be deliver to this activity. The NFC stack 
    // will fill in the intent with the details of the discovered tag before delivering to 
    // this activity. 
    mPendingIntent = PendingIntent.getActivity(this, 0, 
      new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); 

    // Setup an intent filter for all MIME based dispatches 
    IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED); 
    try { 
     ndef.addDataType("*/*"); 
    } catch (MalformedMimeTypeException e) { 
     throw new RuntimeException("fail", e); 
    } 
    mFilters = new IntentFilter[] { 
      ndef, 
    }; 

    // Setup a tech list for all NfcF tags 
    mTechLists = new String[][] { new String[] { NfcF.class.getName() } }; 

    Intent intent = getIntent(); 

    getNdefMessages(intent); 
} 

public void getNdefMessages(Intent intent) { 
    // Parse the intent 
    NdefMessage[] msgs = null; 
    String action = intent.getAction(); 
    if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) { 
     Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); 
     if (rawMsgs != null) { 
      msgs = new NdefMessage[rawMsgs.length]; 
      for (int i = 0; i < rawMsgs.length; i++) { 
       msgs[i] = (NdefMessage) rawMsgs[i]; 
      } 
     } 
     else { 
     // Unknown tag type 
      byte[] empty = new byte[] {}; 
      NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, empty, empty); 
      NdefMessage msg = new NdefMessage(new NdefRecord[] {record}); 
      msgs = new NdefMessage[] {msg}; 
     } 
    }   
    else { 
     //Log.e(TAG, "Unknown intent " + intent); 
     finish(); 
    } 
} 

@Override 
public void onResume() { 
    super.onResume(); 
    mAdapter.enableForegroundDispatch(this, mPendingIntent, mFilters, mTechLists); 
} 

@Override 
public void onNewIntent(Intent intent) { 
    Log.i("Foreground dispatch", "Discovered tag with intent: " + intent); 
    getNdefMessages(intent);    
} 

@Override 
public void onPause() { 
    super.onPause(); 
    //mAdapter.disableForegroundDispatch(this); 
    throw new RuntimeException("onPause not implemented to fix build"); 
} 

的Manifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
     package="com.nfc.reader" 
     android:versionCode="1" 
     android:versionName="1.0"> 

    <uses-permission android:name="android.permission.NFC" /> 
    <uses-sdk android:minSdkVersion="10"/> 
    <uses-feature android:name="android.hardware.nfc" android:required="true" /> 

    <application android:icon="@drawable/icon" android:label="@string/app_name"> 
     <activity android:name="NfcReader" 
      android:theme="@android:style/Theme.NoTitleBar"> 
      <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.TECH_DISCOVERED"/> 
       <data android:mimeType="text/plain" /> 
       <category android:name="android.intent.category.DEFAULT"/> 
      </intent-filter> 

      <meta-data android:name="android.nfc.action.TECH_DISCOVERED" 
       android:resource="@xml/nfctech" /> 
     </activity> 

    </application> 

</manifest> 

回答

0

在你的代碼是基於ACTION_TECH_DISCOVERED設置你的意圖過濾器,但你嘗試ndef.addDataType(/)這是您將爲ACTION_NDEF_DISCOVERED設置意圖過濾器的方式。相反,你可以簡單地做這樣的事情:

IntentFilter ntech = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED); 
mFilters = new IntentFilter[]{ ntech }; 

請確保您有nfc_tech_list.xml正確設置:

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> 
    <tech-list> 
     <tech>android.nfc.tech.NfcA</tech> 
     <tech>android.nfc.tech.MifareUltralight</tech> 
    </tech-list> 
</resources> 
1

當檢測到與NDEF消息的標籤,機器人看起來與任何應用意向過濾動作「android.nfc.action.NDEF_DISCOVERED」。如果兩個或多個應用程序可以處理此操作,則具有最精確過濾器的應用程序將收到該意圖。當找到具有相同過濾器的應用程序時,是誰選擇一個。因此,在您的AndroidManifest.xml中,您必須使用此操作來檢測NDEF格式化的標記。

如果你想讀取NDEF消息,不用擔心你正在閱讀哪種類型的標籤(Ultralight,Felica,Topaz,...)。 Android使用android.nfc.tech.Ndef用於分派NDEF格式化標籤。因此,對於獲得,當你的活動是在前臺的所有NdefMessages,您可以使用此代碼片段:如果你想讀的超輕標籤(或其他技術)

//Called in onCreate() 
private void nfcConfig() { 
    mAdapter = NfcAdapter.getDefaultAdapter(this); 
    pendingIntent = PendingIntent.getActivity(
      this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); 
    techListsArray = new String[][]{new String[]{ 
       Ndef.class.getName() 
      }};  
} 

@Override 
public void onResume() { 
    super.onResume(); 
    mAdapter.enableForegroundDispatch(this, pendingIntent, null, techListsArray); 
} 

@Override 
public void onPause() { 
    super.onPause(); 
    mAdapter.disableForegroundDispatch(this); 
} 

@Override 
public void onNewIntent(Intent intent) { 
    getNdefMessages(intent);    
} 

,應該是因爲你需要從原始數據標籤。它不能從主應用程序線程執行。例如:

private void nfcConfig(){ 
... 
//Mifare Ultralight filter 
techListsArray = new String[][]{new String[]{ 
      NfcA.class.getName(), 
      MifareUltralight.class.getName() 
     }}; 
... 
} 

@Override 
public void onNewIntent(Intent intent) { 
    getRawData(intent);    
} 

private void getRawData(Intent intent){ 
    final Tag tag = (Tag) intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); 
    MifareUltralight ulTag = MifareUltralight.getTag(); 
    new ReadMFULTask(ulTag).execute(); 
} 

private static class ReadMFULTask extends AsyncTask<Void, Void, Void> { 

    private Tag mTag; 

    public ReadMFULTask(Tag tag){ 
     mTag = tag; 
    } 

    @Override 
    protected Void doInBackground(Void... arg0) { 

    MifareUltralight ulTag = MifareUltralight.get(mTag); 
    try { 
     ulTag.connect(); 
      //Read all pages from an Ul tag 
      for(int i=0; i < 16; i=i+4){ 
      byte[] data = ulTag.readPages(i); 
       String dataString = HexUtilities.getHexString(data); 
       Log.d("RAW DATA", dataString); 
      } 
      ulTag.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 
}