2

Я работаю над NFC-приложением. Чтобы запустить приложение, я использую NDEF-тег с записью AAR NDEF внутри.Android/NFC: получить тег в onCreate() без нового намерения

Это прекрасно работает. Но теперь я хочу напрямую прочитать содержимое тега с помощью приложения. Как я могу это сделать?

(. Он уже работает, когда я удалить тег из телефона и прикоснуться к ней снова, но я хочу, чтобы устранить этот шаг)

Update: Некоторые подробности Ok, чтобы сделать его более ясным , вот некоторые части моего текущего кода.

private NfcAdapter nfcAdapter; 
private static final int PENDING_INTENT_TECH_DISCOVERED = 1; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_l); 
    text_output = (TextView) findViewById(R.id.textView2); 

    NfcAdapter adapter = ((NfcManager) getSystemService(Context.NFC_SERVICE)) 
      .getDefaultAdapter();  
} 

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

    nfcAdapter = ((NfcManager) this.getSystemService(Context.NFC_SERVICE)) 
      .getDefaultAdapter(); 

    PendingIntent pi = createPendingResult(PENDING_INTENT_TECH_DISCOVERED, 
      new Intent(), 0); 

    nfcAdapter.enableForegroundDispatch(this, pi, 
      new IntentFilter[] { new IntentFilter(
        NfcAdapter.ACTION_TECH_DISCOVERED) }, new String[][] { 
        new String[] { "android.nfc.tech.NdefFormatable" }, 
        new String[] { "android.nfc.tech.Ndef" } }); 
} 

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

@Override 
protected void onActivityResult(int requestCode, int resultCode, 
     final Intent data) { 
    switch (requestCode) { 
    case PENDING_INTENT_TECH_DISCOVERED: 
     Runnable runnable = new Runnable() { 
      @Override 
      public void run() { 
       doTagOperation(data); 
      } 
     }; 
     new Thread(runnable).start(); 

     break; 
    } 
} 

private void doTagOperation(Intent data) { 

    try {   
     String action = data.getAction(); 
     if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) { 

      Tag tag = data.getParcelableExtra(NfcAdapter.EXTRA_TAG);         
      Ndef ndefTag = Ndef.get(tag); 
     } 
    } catch (Exception ex) { 
       ... 
    } 
} 

Чтобы запустить приложение я использую AAR-ЦНК-запись на бирке, которая может быть создана таким образом: NdefRecord NDR = NdefRecord.createApplicationRecord ("com.example.something");

Так что я хочу: коснитесь тега, когда приложение не запущено, приложение начинает (работает уже), а затем оно должно непосредственно читать тег без необходимости отводить телефон от тега и снова коснуться его ,

+0

Было бы полезно, если бы вы разместили часть своего текущего кода, возможно, метод ** onCreate() **, который, как вы говорите, уже работает. Спасибо – brwngrldev

ответ

4

Если вы хотите получить обнаружения намерения ЦНК после начала вашей деятельности, вам необходимо добавить фильтр намерений, который запускает на ЦНК сообщение тега в приложение манифеста:

<activity ... > 
    <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.NDEF_DISCOVERED" /> 
     <category android:name="android.intent.category.DEFAULT" /> 

Вы можете использовать либо триггер на основе URI:

 <data android:scheme="http" android:host="mroland.at" android:pathPrefix="/test" /> 

Или схему на основе MIME:

 <data android:mimeType="application/vnd.mroland.test" /> 

Или, если вы хотите получить NDEF обнаружил намерение для тега, который содержит только AAR (я должен признать, что я никогда не испытывал этого, так что я только предположить, что это должно работать):

 <data android:scheme="vnd.android.nfc" android:host="ext" 
       android:pathPrefix="/android.com:pkg" /> 

Но вы должны используйте один из них. (По крайней мере, на большинстве устройств вы должны. Некоторые устройства/Android версии будут принимать фильтр намерений даже без data элемента.)

</intent-filter> 
</activity> 

Вы можете получить намерение в onCreate(), onStart(), onResume() или туда, куда вы хотите для его чтения с использованием метода getIntent().

Обратите внимание, что если вы не добавить фильтр намерений для NDEF_DISCOVERED в манифест, сообщение ЦНКА с AAR для вашего приложения будет вызвать пристальное действие MAIN с категорией LAUNCHER быть передан на ваш первой деятельности, объявляет такой фильтр намерения. В этом случае вы не получите сообщение NDEF. Так что если вы хотите получить сообщение NDEF вы должны, чтобы объявить намеренный фильтр для . В этом случае вы можете выбрать, какое действие запускается AAR, установив фильтр намерений NDEF_DISCOVERED для этой конкретной активности.

+0

Означает ли это, что нет решения с AAR? – Manuel

+1

Вы имеете в виду только AAR? Как правило, вы должны использовать AAR в качестве последней записи сообщения NDEF и использовать перед этим некоторые другие записи. Таким образом, с вышеупомянутым фильтром намерений вы активируете первую запись в этом сообщении (тот, который также содержит AAR в качестве последней записи). AAR по-прежнему гарантирует, что обнаруженное NDEF намерение передается только вашему приложению. Если вы действительно хотите, чтобы AAR была единственной записью в вашем сообщении, см. Обновленный ответ (хотя это, как правило, не имеет большого смысла, поскольку в этом случае вы не будете передавать какие-либо данные). –

+0

FYI: Он работает с чистым AAR-решением. Большое спасибо д-р Роланд! :) – Manuel

-1

Вам необходимо использовать метод onNewIntent(), как описано в документации. Метод onCreate() должен содержать код установки, который у вас есть в onResume(). Это заставит приложение работать во всех случаях.

Из Android документации (http://developer.android.com/guide/topics/connectivity/nfc/advanced-nfc.html):

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

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

public void onNewIntent(Intent intent) { 
    Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); 
    //do something with tagFromIntent 
} 
+1

-1 Подход переднего плана от OP работает так же, как ваш подход. Вместо метода onNewIntent будет вызываться метод onActivityResult из-за использования ожидающего результата (createPendingResult). –