Записи о кросс-платформенных запусках с дополнительными данными на Windows Phone и Android

Можно ли создать кросс-платформенное сообщение NDEF для запуска приложения на Android и Windows Phone с передачей дополнительных данных в приложение?

Что я пытаюсь сделать:

У меня установлено приложение на Android и Windows Phone. Должна быть возможность запускать приложения с тегом NFC, и мне нужно передать дополнительные данные из тега (любая строка) в мои приложения.

Чтобы запускать приложения с тегами NFC, я создал запись приложения LaunchApp для Windows Phone и запись приложения Android (AAR) и сохранил их в теге.

Windows Phone требует, чтобы запись LaunchApp была первой записью NDEF в сообщении NDEF. Таким образом, последовательность сообщения NDEF такова:

  1. Запись приложения для запуска Windows Phone
  2. Запись приложения Android

Чтобы передать дополнительные данные, я могу поместить некоторые аргументы в запись Windows Phone LaunchApp, так что это работает нормально. Но невозможно добавить некоторые дополнительные данные в запись приложения Android.

Я попытался добавить третью запись NDEF в сообщение, содержащее дополнительные данные для Android. Я создал внешнюю запись и добавил фильтр в свой манифест.

<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="vnd.android.nfc"
        android:host="ext"
        android:pathPrefix="/myapp.com:customtype"/>
</intent-filter>

Проблема заключается в последовательности сообщения NDEF:

Запись Windows Phone должна быть первой записью в сообщении, но дополнительная запись также должна быть первой записью, которая получит намерение на Android.

Сообщение NDEF:

  1. Внешняя запись и запись LaunchApp
  2. Запись приложения Android

Если у меня есть следующая последовательность записей, я получаю дополнительные данные на Android, и приложение запускается, но затем я не могу открыть приложение на Windows Phone, потому что запись является второй.

  1. Внешняя запись
  2. Приложение для запуска Windows Phone
  3. Запись приложения Android

Есть ли решение этой проблемы? Я что-то пропустил?


person user2048767    schedule 12.07.2015    source источник


Ответы (1)


Проблема здесь в следующем:

  • Windows требует, чтобы запись LaunchApp была первой записью сообщения NDEF в теге.
  • Android будет передавать обнаруженное сообщение NDEF/объект тега NFC в приложение только в том случае, если приложение имеет фильтр намерений для первой записи сообщения NDEF.
  • Запись LaunchApp не является допустимой записью NDEF (поскольку формат имени ее типа указывает на абсолютную запись URI, но ее тип ("windows.com/LaunchApp") не является допустимым абсолютным URI).

Как следствие, вы не можете легко сопоставить эту запись (запись LaunchApp) с фильтром намерений на Android (фильтры намерений URI совпадают в схеме порядка -> хост -> путь, но поскольку схемы нет, вы не можете сопоставить хост/ дорожка).

Хитрость заключается в использовании фильтра намерений, который соответствует любому URI с пустой схемой:

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

Теперь, если ваше сообщение NDEF

LaunchApp record | [optional other records] | Android Application record

ваше Android-приложение будет вызвано, и объект сообщения/тега NDEF будет передан в намерении NDEF_DISCOVERED в действие с указанным выше фильтром намерений.

К сожалению, этот фильтр намерений также будет активирован для любого другого тега, который содержит относительный URI/любой URI без схемы и не содержит AAR для другого приложения.


ОБНОВЛЕНИЕ

Код для создания моего тестового тега записи LaunchApp:

final Ndef ndefTag = Ndef.get(tag);

if (ndefTag != null) {
    try {
        ndefTag.connect();
        ndefTag.writeNdefMessage(new NdefMessage(new NdefRecord[] {
                    new NdefRecord(NdefRecord.TNF_ABSOLUTE_URI,
                                   "windows.com/LaunchApp".getBytes("US-ASCII"),
                                   null,
                                   "la:uz".getBytes("US-ASCII")),
                    NdefRecord.createApplicationRecord("at.mroland.launchrecordtest")
        }));
    } catch (Exception e) {
    } finally {
        try {
            ndefTag.close();
        } catch (Exception ee) {
        }
    }
}

Манифест для принимающего приложения:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="at.mroland.launchrecordtest"
          android:versionCode="1"
          android:versionName="1.0">
    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.NFC" />
    <uses-feature android:name="android.hardware.nfc" android:required="true" />
    <application android:label="@string/app_name"
                 android:icon="@drawable/ic_launcher">
        <activity android:name=".LaunchRecordTest"
                  android:label="LaunchRecordTest">
            <intent-filter>
                <action android:name="android.nfc.action.NDEF_DISCOVERED" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="" />
            </intent-filter>
        </activity>
    </application>
</manifest>

В onCreate() я использовал getIntent() для получения намерения.

person Michael Roland    schedule 14.07.2015
comment
Спасибо, Майкл Роланд за эту информацию. Это значит, что андроид приложение будет открываться для каждого тега с любым URI без схемы? - person user2048767; 14.07.2015
comment
Правильный. (Хотя, за исключением других тегов с записями LaunchApp, такие теги должны быть довольно редкими.) - person Michael Roland; 14.07.2015
comment
Ок, прекрасно. Большое спасибо! - person user2048767; 14.07.2015
comment
Снова один вопрос. Я попытался реализовать ваше предложение с фильтром намерений пустой схемы. Я никогда не получаю намерения с сообщением ndef. Методы onNewIntent или onCreate не получат записи. - person user2048767; 14.07.2015
comment
Только что протестировано (Android 4.4.4) и работает, когда активность запускается тегом. Однако получение намерения в onNewIntent(), когда ваша активность уже запущена, — это совсем другая история. - person Michael Roland; 14.07.2015
comment
Ok. Спасибо. Не могли бы вы поделиться кодом или, может быть, записями? Я написал 1) LaunchApp Record, 2) необязательную запись и 3) AAR, но я могу получить обнаруженное намерение NDEF в onCreate(). - person user2048767; 14.07.2015
comment
Давайте продолжим обсуждение в чате. - person user2048767; 15.07.2015
comment
@MichaelRoland - есть ли шанс, что вы могли бы опубликовать окончательное решение или указать мне на какие-либо сообщения в блоге, пожалуйста? У меня точно такая же проблема, как описано выше. У меня написан токен, у меня работает WP, но на андроиде он только запускает приложение, и я не получаю запись NDEF. Я знаю, что он есть, так как у меня есть отдельный код для чтения всего тега. - person Steve Goodman; 08.04.2016
comment
@SteveGoodman Я не уверен, что вы имеете в виду под окончательным решением. Все описано в моем ответе выше. Это протестировано для работы по крайней мере на Android 4.4.4, если вы не используете аннотации Xamarin (они называются аннотациями?) для создания фильтров намерений. - person Michael Roland; 08.04.2016
comment
@MichaelRoland спасибо за очень быстрый ответ, просто пользователь 2048767 продолжил обсуждение в чате - однако вы, возможно, частично ответили на мой вопрос. Есть ли проблема с использованием аннотаций Xamarin? У меня есть: ‹code›[Activity(Label = NFCFormsSample, Icon = @drawable/icon, MainLauncher = false, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)] [IntentFilter(new[] {NfcAdapter.ActionNdefDiscovered}, Categories = new [] { Intent.CategoryDefault }, DataScheme = )] [MetaData(NfcAdapter.ActionNdefDiscovered, Resource = @xml/nfc)]‹/code› - person Steve Goodman; 10.04.2016
comment
@SteveGoodman Я не уверен, что с ними что-то не так или проблема, которую мы обнаружили тогда, все еще существует (но я так предполагаю). В то время проблема заключалась просто в том, что пустую схему нельзя было смоделировать с помощью аннотации Xamarin (т. е. DataScheme = не создает правильный фильтр намерений). - person Michael Roland; 11.04.2016
comment
@MichaelRoland - Спасибо. проблема все еще существует, вам нужно отредактировать файл Properties\AndroidManifest.xml. Вы можете увидеть результат в файле obj/Debug/android/AndroidManifest.xml. Все работает сейчас. - person Steve Goodman; 25.04.2016