Чтение тегов NFC из-за пределов приложения не возвращает данных

У меня есть приложение xamarin, которое читает теги NFC. Он отлично работает, когда приложение открыто, но если приложение находится в фоновом режиме или закрыто, оно не может прочитать данные из тега.

Мой фильтр намерений:

[IntentFilter(
     new[] {"android.nfc.action.NDEF_DISCOVERED", "android.intent.action.VIEW", "android.intent.action.MAIN"},
     Categories =
         new[]
         {
             "android.intent.category.DEFAULT", "android.intent.category.BROWSABLE",
             "android.intent.category.LAUNCHER"
         },
     DataScheme = "http", DataHost = "app.myDomain.com")]

И в моем OnNewIntent мое намерение. Данные всегда возвращаются как нулевые при сканировании извне приложения. Есть какие-нибудь мысли о том, где может быть моя проблема?

OnResume:

nfcAdapter.EnableForegroundDispatch(this, nfcPendingIntent, nfcIntentFiltersArray, null);

Онневинтент:

protected override void OnNewIntent(Intent intent)
{            
if (AndroidNFCHelper.isNfcIntent(intent))
{
    DisplayMessage("And it is an NFC intent");
}

var tag = intent.GetParcelableExtra(NfcAdapter.ExtraTag) as Tag;

if (tag == null)
{
    Debug.WriteLine("tag is null");
    return;
}

//rest of OnNewIntent code...
}

Итак, что интересно, при сканировании вне приложения AndroidNFCHelper.isNfcIntent возвращается как ложное. Когда та же метка NFC сканируется в приложении, она возвращается как истинная. Продолжая, тег заканчивается как null и просто попадает в оператор return. При сканировании в приложении тег не является нулевым и продолжается.

PrepareForegroundNFCHandling - вызывается в OnCreate():

private void PrepareForegroundNFCHandling()
{

var tagDetected = new IntentFilter(NfcAdapter.ActionTagDiscovered);
var ndefDetected = new IntentFilter(NfcAdapter.ActionNdefDiscovered);

nfcIntentFiltersArray = new[] { ndefDetected, tagDetected};

var intent = new Intent(this, GetType()).AddFlags(ActivityFlags.SingleTop | ActivityFlags.BroughtToFront);
nfcPendingIntent = PendingIntent.GetActivity(this, 0, intent, 0);

nfcAdapter = NfcAdapter.GetDefaultAdapter(Application.ApplicationContext);            
}

person Arthurdent510    schedule 29.11.2016    source источник
comment
Какие данные (сообщение NDEF) вы сохранили на метке? Приводит ли нажатие тега, когда ваше приложение закрыто (или в фоновом режиме), открывается ваша активность? Какой код у вас есть в OnCreate(), OnStart(), OnResume()? Какое намерение.Действие вы видите в OnNewIntent()?   -  person Michael Roland    schedule 07.12.2016
comment
Это просто URL... что-то вроде app.myDomain.com/p/9. Нажатие при закрытом приложении открывает приложение, но поскольку объект тега в конечном итоге возвращается нулевым, ничего не происходит. Я обновлю пост с другим кодом   -  person Arthurdent510    schedule 07.12.2016
comment
Вы вызываете OnNewIntent() из любого места кода? Вы уверены, что ваш тег содержит только одну запись NDEF с URL-адресом и что он не содержит запись приложения Android с названием пакета вашего приложения?   -  person Michael Roland    schedule 07.12.2016
comment
Итак, я смог это исправить... В итоге мои теги nfc были закодированы с именем пакета как запись 0 и URL-адресом как запись 1. Я перевернул их, и это волшебным образом начало работать...   -  person Arthurdent510    schedule 07.12.2016


Ответы (1)


Намерение NDEF_DISCOVERED фильтрует только тип первой записи в сообщении NDEF тега.

Поскольку ваше приложение запускается с действием намерения MAIN (AndroidNFCHelper.isNfcIntent(intent) равно false) и без какого-либо объекта Tag в дополнительных намерениях (intent.GetParcelableExtra(NfcAdapter.ExtraTag) равно null), ваше сообщение NDEF, вероятно, содержит запись приложения Android, помимо URL-адреса.

Причина, по которой ваше приложение запускается, даже если сообщение NDEF (читается как «первая запись») не соответствует вашему фильтру намерений, заключается в том, что AAR вернется к запуску вашего приложения, как если бы был щелкнут значок запуска (т.е. действие MAIN, категория LAUNCHER), если нет соответствующего фильтра намерений NFC.

Таким образом, ваше сообщение NDEF, вероятно, выглядит примерно так:

+----------------------------------------------+
| SOME RECORD                                  |
+----------------------------------------------+
| WKT: URI | http://app.mydomain.com/p/9       |
+----------------------------------------------+
| EXTERNAL: android.com:pkg | com.mydomain.app |
+----------------------------------------------+

Или просто так:

+----------------------------------------------+
| EXTERNAL: android.com:pkg | com.mydomain.app |
+----------------------------------------------+
| WKT: URI | http://app.mydomain.com/p/9       |
+----------------------------------------------+

В первом случае вам нужно будет изменить фильтр намерений, чтобы он соответствовал вашей записи «НЕКОТОРАЯ ЗАПИСЬ». В последнем случае вам нужно будет изменить свой фильтр намерений, чтобы он соответствовал внешнему типу «android: com: pkg»:

DataScheme = "vnd.android.nfc", DataHost = "ext", DataPathPrefix = "/android.com:pkg"

Или, что еще лучше, вы перемещаете свой URL-адрес в начало сообщения NDEF, а AAR — в конец сообщения NDEF:

+----------------------------------------------+
| WKT: URI | http://app.mydomain.com/p/9       |
+----------------------------------------------+
| EXTERNAL: android.com:pkg | com.mydomain.app |
+----------------------------------------------+
person Michael Roland    schedule 08.12.2016