【问题标题】:Android / NFC: Get Tag in onCreate() without new IntentAndroid / NFC:在没有新意图的情况下在 onCreate() 中获取标签
【发布时间】:2014-01-16 15:48:36
【问题描述】:

我正在开发一个 NFC 应用程序。 为了启动我的应用程序,我使用了一个带有 AAR NDEF 记录的 NDEF 标记。

这很好用。但现在我想直接用应用程序读取标签内容。 我怎样才能做到这一点?

(已经可以了,当我从手机上取下标签并再次触摸它时,但我想省略这一步。)

更新:更多细节 好的,为了更清楚,这是我当前代码的一些部分。

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-NDEF-Record,可以通过以下方式创建: NdefRecord ndr = NdefRecord.createApplicationRecord("com.example.something");

所以我想要的是:在应用程序未启动时触摸标签使应用程序启动(已经工作),然后它应该直接读取标签,而无需将手机从标签上移开并再次触摸它。

【问题讨论】:

  • 如果您发布一些当前代码会很有帮助,也许您所说的 onCreate() 方法已经有效。谢谢

标签: android android-intent nfc ndef android-applicationrecord


【解决方案1】:

如果您想在 Activity 开始时接收 NDEF 发现 Intent,则需要在应用程序清单中添加一个触发标签的 NDEF 消息的 Intent 过滤器:

<activity ... >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

我猜你已经有了上面的内容,所以你需要添加一个 NDEF 意图过滤器:

    <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" />

或者,如果您想接收仅包含 AAR 的标签的 NDEF 发现意图(我不得不承认我从未对此进行过测试,所以我只假设这应该有效):

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

但你必须使用其中之一。 (至少在大多数设备上你必须这样做。一些设备/Android 版本即使没有 data 元素也会接受意图过滤器。)

    </intent-filter>
</activity>

然后,您可以使用getIntent() 方法在onCreate()onStart()onResume() 或您想要阅读的任何地方获取意图。

请注意,如果您没有将 NDEF_DISCOVERED 的意图过滤器添加到您的清单中,带有 AAR 的应用程序的 NDEF 消息将导致意图操作 MAIN 与类别 LAUNCHER 传递到您的first 声明此类意图过滤器的活动。在这种情况下,您将不会收到 NDEF 消息。因此,如果您想要接收 NDEF 消息,您必须NDEF_DISCOVERED 声明一个意图过滤器。在这种情况下,您可以通过为特定活动设置 NDEF_DISCOVERED 意图过滤器来选择由 AAR 启动的活动。

【讨论】:

  • 这是否意味着 AAR 没有解决方案?
  • 您的意思是单独使用 AAR?通常,您会将 AAR 用作 NDEF 消息的最后一条记录,并在它之前使用一些其他记录。因此,使用上述意图过滤器,您将触发该消息中的第一条记录(也包含 AAR 作为其最后一条记录的一条记录)。 AAR 仍将确保 NDEF 发现的意图仅传递给您的应用程序。如果您真的希望 AAR 成为您消息中的唯一记录,请参阅更新后的答案(尽管这通常没有多大意义,因为在这种情况下您不会传递任何数据)。
  • 仅供参考:它适用于纯 AAR 解决方案。非常感谢 Roland 博士! :)
  • 我现在也尝试将 AAR 作为附加记录(在另一个 ndef 记录之后)。但这不会使我的应用程序自动启动(即使在 mainfest 中指定)。我的第一个记录的 TNF 是“未知”(0x05)(因为它只是二进制数据)。这是一个问题吗(也许是它无法启动的原因)?
  • 意图过滤器仅适用于 NDEF 消息中的第一条记录。 从不对任何记录使用 TNF unknown(这意味着记录的有效负载不是二进制数据,而是记录本身由于任何原因都不可解析/可解释。)使用NFC 论坛外部类型名称(TNF=external + 类型名称遵循 NFC 论坛的 RTD 规范)。然后,您可以将您的意图过滤器设置为触发该记录类型名称。
【解决方案2】:

您需要使用文档中讨论的 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 OP 的前台调度方法与您的方法一样工作。由于使用了挂起的结果 (createPendingResult),将调用 onActivityResult 方法而不是 onNewIntent 方法。
猜你喜欢
  • 2020-04-04
  • 1970-01-01
  • 2012-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-23
相关资源
最近更新 更多