OnNewIntent通过外部类

时间:2014-06-04 13:51:14

标签: android nfc

我正在开发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看起来像这样(见图)

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>

1 个答案:

答案 0 :(得分:1)

首先,如果您希望应用程序由您的代码启动并希望接收已解析的NDEF消息,那么您的代码应包含以下内容:

  1. 您要在上过滤NDEF记录作为NDEF消息的第一条记录(您只能为NFC标记上的第一个NDEF记录创建intent-filters)。在您的情况下,这将是文本记录。但是,您可能需要考虑将NFC论坛外部类型记录与您的自定义应用程序特定类型名称一起使用(请参阅here。仅当文本记录包含人类可读的非解释时才应使用它文本
  2. 如果您想确保只有您的应用以标记启动,那么如果用户未安装该应用,您的应用的Play商店页面会自动开启,可以使用Android应用程序记录(AAR)。此记录应为NDEF消息中的最后记录。无论NDEF消息中的位置如何,AAR都将受到尊重。
  3. 接下来,您必须为应接收标记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.MAINandroid.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中)。此外,它用于前台调度的全能版本。