1

Ich versuche, ein NFC-Tag aus meiner app zu lesen, aber jedesmal, wenn ich den Tag scannen öffnet sich ein Standard-App (ich glaube, es ist Standard-Android-one ...)Lesen NFC Tag ausschließlich aus Current App

Ich möchte verhindern, dass ein Tag außerhalb meiner App gelesen wird, wenn es geöffnet ist. Wie kann ich das erreichen?

ScanNFC.java (Aktivität lesen NFC Data):

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> 

Wie kann ich verhindern, dass andere Anwendungen aus dem Lesen NFC-Tags, wenn mein app läuft?

+1

See: http://stackoverflow.com/questions/11074812/android-nfc-intents-are-not- start-my-activity –

+1

@Hafenkranich kann getan werden, [NFC Tools] (https://play.google.com/store/apps/details?id=com.wakdev.wdnfc&hl=de) ist ein perfektes Beispiel. – Ricky

+0

Danke @Morrison_Chang für das hinweisend. Sie haben recht, es scheint, als könnte es tatsächlich getan werden: https://developer.android.com/guide/topics/connectivity/nfc/advanced-nfc.html#foreground-dispatch – Hafenkranich

Antwort

3

Der Schlüssel dazu ist, entweder das Vordergrund-Dispatch-System (NfcAdapter.enableForegroundDispatch()) oder die Reader-Mode-API (NfcAdapter.enableReaderMode()) zu verwenden. Beachten Sie, dass Letzteres nur mit Android 4.4+ funktioniert.

Sie versuchen bereits, das Vordergrund-Dispatch-System in Ihrem Code zu verwenden. Sie jedoch zur Zeit registrieren nur für einen ganz bestimmten Tag-Typen (was wahrscheinlich nicht Ihren Tag paßt):

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

Mit diesem Code können Sie sich registrieren, um nur Ereignisse für Tags zu erhalten, die einen NDEF Text Datensatz (oder einen Text enthalten/plain MIME-Typ Datensatz).

Sie könnten stattdessen registrieren für jeden Tag, indem einfach benachrichtigt werden:

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

Spot on! es funktioniert wie ein Charme :) – Ricky