1

我想從我的應用程序中讀取NFC標籤,但我每次掃描標籤,即會打開一個默認的應用程序(我認爲這是Android的默認的...)閱讀NFC標籤專門從當前應用

我想阻止任何標籤在我的應用程序打開時被讀取。 我該怎麼做到這一點?

ScanNFC.java(活動讀取NFC數據):

public class ScanNFC extends AppCompatActivity { 


public static final String MIME_TEXT_PLAIN = "text/plain"; 
public static final String TAG = "NfcDemo"; 

private NfcAdapter mNfcAdapter; 

private TextView mTextView; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 

    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_scan_nfc); 
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    if (toolbar != null) 
    { 
     setSupportActionBar(toolbar); 
     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
    } 


    mTextView = (TextView) findViewById(R.id.tvTapNFC); 
    mNfcAdapter = NfcAdapter.getDefaultAdapter(this); 


    if (mNfcAdapter != null) { 
     mTextView.setText("Read an NFC tag"); 
    } else { 
     mTextView.setText("This phone is not NFC enabled."); 
    } 


    handleIntent(getIntent()); 
} 


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

    setupForegroundDispatch(this, mNfcAdapter); 
} 

@Override 
protected void onPause() { 

    stopForegroundDispatch(this, mNfcAdapter); 

    super.onPause(); 
} 

@Override 
protected void onNewIntent(Intent intent) { 

    handleIntent(intent); 
} 


private void handleIntent(Intent intent) 
{ 
    String action = intent.getAction(); 


    if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) { 

     String type = intent.getType(); 
     if (MIME_TEXT_PLAIN.equals(type)) { 

      Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); 
      new AsyncNdefReaderTask().execute(tag); 

     } else { 
      Log.d(TAG, "Wrong mime type: " + type); 
     } 
    } else if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) { 

     Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); 
     String[] techList = tag.getTechList(); 
     String searchedTech = Ndef.class.getName(); 

     for (String tech : techList) { 
      if (searchedTech.equals(tech)) { 
       new AsyncNdefReaderTask().execute(tag); 
       break; 
      } 
     } 
    } 
} 


private class AsyncNdefReaderTask extends NdefReaderTask 
{ 
    @Override 
    protected void onPostExecute(String result) { 

     Log.d("onPostExecute", "onPostExecute"); 

     if (result != null) { 
      mTextView.setText("Read content: " + result); 
     } 
    } 
} 


public static void setupForegroundDispatch(final Activity activity, NfcAdapter adapter) 
{ 
    final Intent intent = new Intent(activity.getApplicationContext(), activity.getClass()); 
    intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); 

    final PendingIntent pendingIntent = PendingIntent.getActivity(activity.getApplicationContext(), 0, intent, 0); 

    IntentFilter[] filters = new IntentFilter[1]; 
    String[][] techList = new String[][]{}; 

    filters[0] = new IntentFilter(); 
    filters[0].addAction(NfcAdapter.ACTION_NDEF_DISCOVERED); 
    filters[0].addCategory(Intent.CATEGORY_DEFAULT); 
    try { 
     filters[0].addDataType(MIME_TEXT_PLAIN); 
    } catch (IntentFilter.MalformedMimeTypeException e) { 
     throw new RuntimeException("Check your mime type."); 
    } 

    adapter.enableForegroundDispatch(activity, pendingIntent, filters, techList); 
} 


public static void stopForegroundDispatch(final Activity activity, NfcAdapter adapter) { 
    adapter.disableForegroundDispatch(activity); 
} 

} 

的AndroidManifest.xml:

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


<application 
    android:name=".MyApplication" 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme"> 

    <activity 
     android:name=".ScanNFC" 
     android:label="@string/title_activity_scan_nfc" 
     android:theme="@style/AppTheme.NoActionBar"> 

     <intent-filter> 
      <action android:name="android.nfc.action.NDEF_DISCOVERED"/> 
      <category android:name="android.intent.category.DEFAULT"/> 
      <data android:mimeType="text/plain" /> 
      <data android:scheme="http" /> 
     </intent-filter> 

    </activity> 
</application> 

如何防止其他應用程序讀取NFC標籤我的應用程序運行時?

+1

參見:http://stackoverflow.com/questions/11074812/android-nfc-intents-are-not-開始我的活動 –

+1

@Hafenkranich它可以完成,[NFC工具](https://play.google.com/store/apps/details?id=com.wakdev.wdnfc&hl=en)就是一個很好的例子。 – Ricky

+0

感謝@Morrison_Chang指出了這一點。你是對的,它似乎可以實際完成:https://developer.android.com/guide/topics/connectivity/nfc/advanced-nfc.html#foreground-dispatch – Hafenkranich

回答

3

關鍵是要使用前臺調度系統(NfcAdapter.enableForegroundDispatch())或讀取器模式API(NfcAdapter.enableReaderMode())。請注意,後者只適用於Android 4.4+。

您已經嘗試在代碼中使用前臺調度系統。但是,您目前只能註冊一個非常特殊的標籤類型(這可能不符合你的標籤):

public static void setupForegroundDispatch(final Activity activity, NfcAdapter adapter) { 
    final Intent intent = new Intent(activity.getApplicationContext(), activity.getClass()); 
    intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); 

    final PendingIntent pendingIntent = PendingIntent.getActivity(activity.getApplicationContext(), 0, intent, 0); 

    IntentFilter[] filters = new IntentFilter[1]; 
    String[][] techList = new String[][]{}; 

    filters[0] = new IntentFilter(); 
    filters[0].addAction(NfcAdapter.ACTION_NDEF_DISCOVERED); 
    filters[0].addCategory(Intent.CATEGORY_DEFAULT); 
    try { 
     filters[0].addDataType(MIME_TEXT_PLAIN); 
    } catch (IntentFilter.MalformedMimeTypeException e) { 
     throw new RuntimeException("Check your mime type."); 
    } 

    adapter.enableForegroundDispatch(activity, pendingIntent, filters, techList); 
} 

與該代碼您註冊只接收事件包含的NDEF文字記錄標籤(或文本/普通的MIME類型記錄)。

您可以改爲登記通知的任何標籤簡單地使用:

public static void setupForegroundDispatch(final Activity activity, NfcAdapter adapter) { 
    final Intent intent = new Intent(activity, activity.getClass()); 
    intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); 

    final PendingIntent pendingIntent = PendingIntent.getActivity(activity, 0, intent, 0); 

    adapter.enableForegroundDispatch(activity, pendingIntent, null, null); 
} 
+0

現貨!它的工作就像一個魅力:) – Ricky