2011-05-10 32 views
2

我完全不熟悉Android開發,必須編寫一個簡單的應用程序來讀取大學的nfc標籤(與nexus s)。Android NFC前臺調度問題

我的問題是,當nexus發現一個標籤時,我的應用沒有列在「選擇一個動作」 - popup中。其目的是在http://developer.android.com/guide/topics/nfc/index.htmlhttp://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundDispatch.html

描述閱讀使用前景分派方法的標籤,我認爲有什麼東西在清單中失蹤,但我不知道是什麼。 這裏的清單:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
package="com.iforge.android.nfc" 
> 
<uses-permission android:name="android.permission.INTERNET"></uses-permission> 
<uses-permission android:name="android.permission.NFC" /> 
<uses-permission android:name="android.permission.CALL_PHONE" /> 
<application 
    android:icon="@drawable/icon" 
    android:label="@string/app_name" 
> 
<activity android:name=".simulator.FakeTagsActivity" 
    android:theme="@android:style/Theme.NoTitleBar"> 
    <intent-filter> 
     <action android:name="android.intent.action.MAIN" /> 
     <category android:name="android.intent.category.LAUNCHER" /> 
    </intent-filter> 

</activity> 

    <activity android:name="TagViewer" 
     android:theme="@android:style/Theme.NoTitleBar" 
    > 
     <intent-filter> 
      <action android:name="android.nfc.action.NDEF_DISCOVERED"/> 
      <data android:mimeType="mime/type" /> 
     </intent-filter> 

     <intent-filter> 
      <action android:name="android.nfc.action.TECH_DISCOVERED"/> 

     </intent-filter> 

     <intent-filter> 
      <action android:name="android.nfc.action.TAG_DISCOVERED"/> 
     </intent-filter> 
    </activity> 
</application> 
<uses-sdk android:minSdkVersion="10" /> 
<uses-feature android:name="android.hardware.nfc" android:required="true" /> 

這裏是當標籤被發現,應該叫活動(這是打造出來的機器人NFCDemo的還有ForegroundDispatch-例子)的代碼:

public class TagViewer extends Activity 
{ 

WebView webView; 
private NfcAdapter mAdapter; 
private PendingIntent mPendingIntent; 
private IntentFilter[] mFilters; 
private String[][] mTechLists; 

@Override 
protected void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
    mAdapter = NfcAdapter.getDefaultAdapter(this); 
    mPendingIntent = PendingIntent.getActivity(
      this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); 

    IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); 
    try { 
     ndef.addDataType("*/*"); /* Handles all MIME based dispatches. 
             You should specify only the ones that you need. */ 
    } 
    catch (MalformedMimeTypeException e) { 
     throw new RuntimeException("fail", e); 
    } 

    mFilters = new IntentFilter[] { 
      ndef, 
    }; 

    mTechLists = new String[][] { new String[] { NfcF.class.getName() } }; 


    setContentView(R.layout.tag_viewer); 
    webView = (WebView) findViewById(R.id.webView1); 
    webView.getSettings().setJavaScriptEnabled(true); 
    webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(false); 
    webView.getSettings().setPluginsEnabled(false); 
    webView.getSettings().setSupportMultipleWindows(false); 
    webView.getSettings().setSupportZoom(false); 
    webView.setVerticalScrollBarEnabled(false); 
    webView.setHorizontalScrollBarEnabled(false); 

    resolveIntent(getIntent()); 
} 

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

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

void resolveIntent(Intent intent) 
{ 
    // Parse the intent 
    String action = intent.getAction(); 
    if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) 
    { 
     // When a tag is discovered we send it to the service to be save. We 
     // include a PendingIntent for the service to call back onto. This 
     // will cause this activity to be restarted with onNewIntent(). At 
     // that time we read it from the database and view it. 
     Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); 
     NdefMessage[] msgs; 
     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}; 
     } 
     // Setup the web-view 
     setUpWebView(msgs); 
    } 
    else 
    { 
     Log.e("ViewTag", "Unknown intent " + intent); 
     finish(); 
     return; 
    } 
} 

void setUpWebView(NdefMessage[] msgs) 
{ 
    if (msgs == null || msgs.length == 0) return; 

    String urlToLoad = MessageParser.parseMessage(msgs[0]); 
    if(!urlToLoad.matches("")) webView.loadUrl(urlToLoad); 

} 

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

我試了很多,但沒有任何工作。如果有人能告訴我我錯過了什麼,那將是非常棒的。我跑出來的時間:-(

感謝

回答

0

如果您啓動Activity並註冊foregroudn dispatch,必須做的是爲ACTION_TAG_DISCOVERED註冊一個意圖過濾器 - 這是最低的過濾器,並匹配所有發現的標籤。如果你想更具體一些,你可以爲標籤技術或者包含ndef的標籤註冊一個意圖過濾器。

但是,如果您想要使用水龍頭向標籤從主屏幕啓動應用程序,則必須以不同方式執行此操作。我成功地將一個MIME消息放到一個標籤上,並將該MIME類型註冊到我的活動中。另一種方法是將URL添加到標記中,然後註冊一個用來計算方案和主機的意圖過濾器。對於MIME,這是你所需要的:

爲了使這個比賽,該標籤需要的描述有一默默NDEF消息。

4

你的清單文件需要處理技術發現的意圖,在一個單獨的高科技過濾器的XML,像這樣:

<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"/> 
      </intent-filter> 
      <meta-data android:name="android.nfc.action.TECH_DISCOVERED" 
           android:resource="@xml/nfc_tech_filter" /> 
      <intent-filter> 
       <action android:name="android.nfc.action.TAG_DISCOVERED"/> 
      </intent-filter> 

然後你RES/XML/nfc_tech_filter.xml必須處理你想這樣的NFC科技股:

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

每個科技節點都像AND,而tech-list節點的作用類似於或。我建議您首先使用NFC標籤閱讀器等工具掃描您的標籤,以瞭解您的技術。像其他網站

然後在Java代碼中,您可以啓用/禁用前景調度系統已經科技股,我設置了相同的科技股,因爲我在XML中做這樣的:

private void setUpForegroundDispatchSystem() 
    { 
     this.nfcAdapter = NfcAdapter.getDefaultAdapter(this); 

     this.pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); 

     IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); 
     try { 
      ndef.addDataType("*/*"); /* Handles all MIME based dispatches. 
              You should specify only the ones that you need. */ 
      ndef.addDataScheme("http"); 
     } 
     catch (MalformedMimeTypeException e) { 
      throw new RuntimeException("fail", e); 
     } 
     this.intentFiltersArray = new IntentFilter[] {ndef}; 
     this.techListsArray = new String[][] { new String[] { MifareUltralight.class.getName(), Ndef.class.getName(), NfcA.class.getName()}, 
               new String[] { MifareClassic.class.getName(), Ndef.class.getName(), NfcA.class.getName()}}; 

    } 

您必須啓用和禁用此在暫停和恢復方法中。 希望這個信息可以幫助你。

+0

通過任何方式,有沒有辦法不添加我的技術列表在java文件中,並在發送掛起的意圖時引用我的xml? – Android 2013-10-07 06:48:26

+0

@matiasnj你確定你的'AndroidManifest.xml'和'res/xml/nfc_tech_filter.xml'代碼對於前臺調度是必要的嗎? – 2016-03-28 18:56:47

+0

老實說這個代碼是從5年前,我沒有嘗試在新的android開發平臺內​​。到了這個時候,當NFC越來越多時,答案是肯定的,你需要它們。 – matiasnj 2016-06-07 11:54:55

4

前臺調度明確要求使用正確配置的Activity:它看起來不像您可以在AndroidManifest.xml中使用IntentFilter設置前臺調度(您的應用程序實際上必須位於前臺,即運行)。下面的代碼似乎正常工作(我只是測試它)的情況下,你仍然有興趣(ACTION_TAG_DISCOVERED是我在看的):

private NfcAdapter mAdapter; 
    private PendingIntent pendingIntent; 
    private IntentFilter[] mFilters; 
    private String[][] mTechLists; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 

     setContentView(R.layout.main); 

     mAdapter = NfcAdapter.getDefaultAdapter(this); 
     pendingIntent = 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_NDEF_DISCOVERED); 
     try { 
      ndef.addDataType("*/*"); 
     } catch (MalformedMimeTypeException e) { 
      throw new RuntimeException("fail", e); 
     } 
     IntentFilter td = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED); 
     mFilters = new IntentFilter[] { 
       ndef, td 
     }; 

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

@Override 
    public void onResume() 
    { 
     super.onResume(); 

     mAdapter.enableForegroundDispatch(this, pendingIntent, mFilters, mTechLists); 
    } 

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

    @Override 
    public void onNewIntent(Intent intent){ 
     // fetch the tag from the intent 
     Tag t = (Tag)intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); 
     String tlist = getTechList(t); 
     android.util.Log.v("NFC", "Discovered tag ["+tlist+"]["+t+"] with intent: " + intent); 
     android.util.Log.v("NFC", "{"+t+"}"); 
} 
+0

它應該是'mTechLists = new String [] [] { new String [] {NfcF.class.getName()}, new String [] {NfcB.class.getName()}, new String [] { NfcA.class.getName()}, new String [] {NfcV.class.getName()}, };' – Jekton 2018-01-08 03:25:08