我正在开发NFC应用程序。 在标签上,我们有一个应用程序记录,什么是启动我们的应用程序,以及一个文本记录,什么有id。当我的应用程序正在阅读文本记录时,通过网络向我们的服务器发送请求,获取响应,并执行诸如显示按钮之类的操作并不重要。
当我开始学习android时,我了解到,使用通用引擎是件好事,对我自己有很多工具,所以当我需要一个新的应用程序时,我可以重用我的引擎功能。
所以,我已经将这个GameEngine类创建为一个独立的项目。 我没有使用TAG_DISCOVERED过滤器尝试过,当我给出的不是text / plain mime类型,而是我的应用程序时也尝试过。
package GameEngine;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public abstract class GameEngine extends Activity {
private final String TAG = "DH GAME ENGINE";
/**************************************************
* Here are the override methods
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "Engine constructor");
super.onCreate(savedInstanceState);
init();
}
public abstract void init();
//MORE overrides here...
}
在我的应用中,我有init功能。在这里我设置了布局,设置了一些标志。 在onNewIntent方法中,我有这段代码:
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
Log.d(TAG, "A tag was scanned!");
GEPhone.vibrate(this, 500);
tagSerial = GENFC.getTagId(getIntent());
}
它很棒。在此之后我读了我的id并解析它。我使用ndef-tools来解析NDEF消息,但我认为这没关系。
我的问题是,当我在主屏幕上,而我的应用程序没有运行时,当我第一次使用手机点击NFC时,我的应用程序正在启动,但遗憾的是,onNewIntent方法无法运行。
我试图搜索它,我知道,我不是第一个遇到这个问题的人,而且我到处读到,我应该向AndroidManifest.xml添加:
android:launchMode="singleTop"
没有变化。
现在,我还尝试了别的东西。我把整个东西从onNewIntent外包到一个handleIntent方法,所以我的onNewIntent现在看起来像这样:
@Override
public void onNewIntent(Intent intent) {
Log.d(TAG, "onNewIntent");
// Set the intent
setIntent(intent);
handleIntent(intent);
}
我也从init方法调用了这个handleIntent。 但结果是一样的。
如果我这样从init调用这个handlentent:
handleIntent(getIntent());
出于某种原因,这种情况将是错误的。
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
....
}
我错了什么?
PS:我的另一个问题是,我无法调试这一切,因为如果我在eclipse中单击调试按钮,它会启动应用程序,因此我无法模拟,会发生什么(使用断点),当应用程序启动是因为NFC标签启动它。Ps2:现在已经记录,启动应用程序时的操作是什么,它是: 主要活动(29861):行动是:android.intent.action.MAIN
更新 经过一番研究,并玩设置,现在我意识到以下几点: 如果我在清单中使用它: 机器人:launchMode = “singleTask”
和这个过滤器:
<category android:name="android.intent.category.DEFAULT" />
<!-- <data android:mimeType="*/*" /> -->
<data android:mimeType="application/hu.sma.htdalpha" />
</intent-filter>
和数据类型
*/*
,然后一切正常,除非所有TAG都打开我的应用程序,即使只有像“adsdasd”这样的文本。
如果我使用自己的软件包,则打开应用程序,操作将再次为android.intent.action.MAIN。
更新2 正如迈克尔所问,我在这里复制了AndroidManifest.xml。 上面的描述有点令人困惑。正如我读到的那样,问题的关键在于意图不好。包名是好的,但是每次,onCreate,onNewIntent,onStart,onResume,无处不在,如果i Log.d getIntent()。getAction(),将是android.intent.action.MAIN和android.nfc。 action.NDEF_DISCOVERED永远不会被触发。只有,如果应用程序启动一次。
NDEF看起来像这样(见图)
清单就是这样。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="hu.sma.htdalpha"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="16" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="hu.sma.htdalpha.MainActivity"
android:label="@string/app_name"
android:launchMode="singleTask" >
<!--
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/hu.sma.htdalpha" />
</intent-filter>
-->
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
答案 0 :(得分:1)
首先,如果您希望应用程序由您的代码启动并希望接收已解析的NDEF消息,那么您的代码应包含以下内容:
接下来,您必须为应接收标记dicovery事件的活动和触发它的NDEF消息创建适当的intent过滤器:
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
或者,如果您使用自定义NFC论坛外部类型:
<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="/yourdomain.com:yourtypename"/>
</intent-filter>
如果您的应用没有匹配的意图过滤器 和,您的标记包含Android应用记录,则清单中声明的第一个活动具有android.intent.action.MAIN
和android.intent.category.LAUNCHER
的意图过滤器的将会启动,因为它没有声明期望NFC意图它将通过android.intent.action.MAIN
。那就是你的情况。
接下来,在您的活动中,您可以在getIntent()
,onCreate()
等中收到NFC意图(onStart()
),并将其转发到您的handleIntent(...)
方法。当您过滤NDEF_DISCOVERED时,您将收到NDEF_DISCOVERED意图。因此你会使用这样的东西:
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
// do something
}
如果您希望在活动已经在前台时接收更多NFC意图,则可以在onNewIntent()
处理它们。只有在您的活动中添加了适当的launchMode
时,才会调用此方法。更好的是,您可以注册foreground dispatch,为您的活动优先接收NFC事件。
最后,您通常不应在清单中使用TAG_DISCOVERED
意图。此意图过滤器意味着后备(如果没有其他应用程序的NFC意图过滤器匹配)并且向后兼容NFC API的第一版(在Android 2.3中)。此外,它用于前台调度的全能版本。