NFC标签的检测并没有叫onNewIntent,它的启动从主要活动 [英] NFC tag detection is not calling onNewIntent and it's Launching From Main Activity

查看:196
本文介绍了NFC标签的检测并没有叫onNewIntent,它的启动从主要活动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新来的NFC。我试图从一个设备连接到NFC和共享文本数据到另一个设备。

我在搜索的论坛,但它不可能解决我的问题,所以任何一个可以帮助我在此。如何做,所有的。

我安装我的应用程序同时在设备和一个设备,我打开我的应用程序,我开始窃听设备在另一台设备。它打开我用默认的主操作不与TAG_DISCOvered或其他应用程序。每次都做同样的事情。这不是调用 onNewIntent()。 (我试过的OnCreate 致电 onNewIntent ,但行动是只有主要不是其他。所以,可以请你告诉我,我做错什么了?)

在此code,我不共享数据。我只是需要先标记。

感谢您

清单

 <活动
  机器人:名称=com.framentos.hellonfc.MainActivity
        机器人:clearTaskOnLaunch =真
        机器人:标签=@字符串/ APP_NAME
        机器人:launchMode =singleTop
        机器人:screenOrientation =画像>
        <意向滤光器>
            <作用机器人:名称=android.nfc.action.NDEF_DISCOVERED/>

            <类机器人:名称=android.intent.category.DEFAULT/>
        &所述; /意图滤光器>
        <意向滤光器>
            <作用机器人:名称=android.nfc.action.TECH_DISCOVERED/>

            <类机器人:名称=android.intent.category.DEFAULT/>
        &所述; /意图滤光器>
        <意向滤光器>
            <作用机器人:名称=android.nfc.action.TAG_DISCOVERED/>

            <类机器人:名称=android.intent.category.DEFAULT/>
        &所述; /意图滤光器>
        <意向滤光器>
            <作用机器人:名称=android.intent.action.MAIN/>

            <类机器人:名称=android.intent.category.LAUNCHER/>
        &所述; /意图滤光器>

        &所述;元数据
            机器人:名称=android.nfc.action.TECH_DISCOVERED
            机器人:资源=@ XML / nfc_tech_filter/>
    < /活性GT;
 

在我的Java code

  @覆盖
公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.main);
    CTX =这一点;
    // startHandler();
    _handler =新的处理程序();
    按钮btnWrite =(按钮)findViewById(R.id.button);
    消息=(TextView中)findViewById(R.id.nfcwriteTag);
    btnWrite.setOnClickListener(新View.OnClickListener(){
        @覆盖
        公共无效的onClick(视图v){

        }
    });
    适配器= NfcAdapter.getDefaultAdapter(本);
    如果(适配器== NULL){
        message.setText(NFC不支持此设备上。);
    }
    如果(adapter.isEnabled()){
        message.setText(NFC启用该设备上。);
    } 其他 {
        message.setText(请启用NFC进行通信。);
    }
    pendingIntent = PendingIntent.getActivity(此,0,新的意向(这一点,
            。的getClass())addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),0);
    IntentFilter的tagDetected =新的IntentFilter(
            NfcAdapter.ACTION_NDEF_DISCOVERED);
    tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
    IntentFilter的tagTech =新的IntentFilter(
            NfcAdapter.ACTION_TECH_DISCOVERED);
    tagTech.addCategory(Intent.CATEGORY_DEFAULT);
    IntentFilter的tagDetect =新的IntentFilter(
            NfcAdapter.ACTION_TAG_DISCOVERED);
    tagDetect.addCategory(Intent.CATEGORY_DEFAULT);
    writeTagFilters =新的IntentFilter [] {tagDetected,tagTech,tagDetect};
    // handleIntent(getIntent());
}


    @覆盖
保护无效onNewIntent(意向意图){
    super.onNewIntent(意向);
    Log.i(getPackageName(),新来的目的是叫......!);
    handleIntent(getIntent());
}
 

公共无效的onPause(){         super.onPause();         WriteModeOff();     }

  @覆盖
公共无效onResume(){
    super.onResume();
    WriteModeOn();
}

私人无效WriteModeOn(){
    writeMode = TRUE;
    adapter.enableForegroundDispatch(这一点,pendingIntent,writeTagFilters,
            空值);
}

私人无效WriteModeOff(){
    writeMode = FALSE;
    adapter.disableForegroundDispatch(本);
}
 

解决方案

从你张贴在你的问题中code,我假设你没有注册你的应用程序发送一个特定的NDEF消息。在这种情况下,如果你的应用程序是一个设备,Android将自动束包含与您的应用程序的Play商店的链接和一个Android应用程序记录(AAR),另一台设备的URI纪录的NDEF消息。

开放

所以你的第二个设备将收到以下NDEF消息:

<$p$p><$c$c>+-----------------------------------------------------------------------------------------+ | WKT:URI | http://play.google.com/store/apps/details?id=your.package.name&feature=beam | + ------------------------------------------------- ---------------------------------------- + | EXT:机器人:COM:PKG | your.package.name | + ------------------------------------------------- ---------------------------------------- +

现在会发生什么,如果您的应用程序尚未打开第二设备,该Android应用程序记录(第二个记录)将迫使的的应用程序来启动。不过,看你的表现,你没有一个意图过滤器,这NDEF消息的第一条记录(Play商店中的URL)匹配。因此,Android的认为,你不要指望一个NDEF消息,并使用标准的 android.intent.action.MAIN (与类别 android.intent.category .LAUNCHER ),开始您的应用程序(或者说你的应用程序中,有一个意图过滤器采取行动的第一个活动与类别 LAUNCHER )。

为了共同接受的NFC意图在您的应用程序的整个NDEF消息,你需要定义一个适当的意图过滤器,在上面的NDEF消息相匹配的第一个记录:

 &LT;意向滤光器&gt;
    &lt;作用机器人:名称=android.nfc.action.NDEF_DISCOVERED/&GT;
    &LT;类机器人:名称=android.intent.category.DEFAULT/&GT;
    &lt;数据机器人:计划=HTTP
          机器人:主机=play.google.com
          机器人:路径preFIX =?/存储/应用程序/详细信息ID = your.package.name/&GT;
&所述; /意图滤光器&gt;
 

现在,Android将认识到,你的应用程序/活动准备接收的NFC意图和 NDEF_DISCOVERED 的意图传递给你的活动。请注意,您仍然不会通过 onNewIntent收到的意图()如果您的应用程序没有运行。相反,你可以得到你开始与活动活动的 getIntent()法的意图。例如。在的onCreate / ONSTART / onResume ,你可以使用

 意向意图= getIntent();
如果(NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())){
    NdefMessage ndefMessage = NULL;
    Parcelable [] rawMessages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
    如果((rawMessages =空)及!及(rawMessages.length大于0)){
        ndefMessage =(NdefMessage)rawMessages [0];
    }

    // TODO:做一些与接收NDEF消息
}
 

要获得意图和NDEF消息。

关于意图过滤器,你已经在你的清单:

  1. NDEF_DISCOVERED

     &LT;意向滤光器&gt;
        &lt;作用机器人:名称=android.nfc.action.NDEF_DISCOVERED/&GT;
        &LT;类机器人:名称=android.intent.category.DEFAULT/&GT;
    &所述; /意图滤光器&gt;
     

    这是 NDEF_DISCOVERED 没有&LT意图过滤器;数据... /&GT; 标签将许多从未触发NFC设备。你应该总是定义你期望什么具体的数据是present在发射NDEF记录。

  2. TECH_DISCOVERED

     &LT;意向滤光器&gt;
        &lt;作用机器人:名称=android.nfc.action.TECH_DISCOVERED/&GT;
        &LT;类机器人:名称=android.intent.category.DEFAULT/&GT;
    &所述; /意图滤光器&gt;
    &LT;元数据的android:NAME =android.nfc.action.TECH_DISCOVERED
               机器人:资源=@ XML / nfc_tech_filter/&GT;
     

    如果你wan't你的应用程序在检测到一定的NFC标签技术(定义在 nfc_tech_filter.xml 文件为您的光束的情况下,你不会使用这样的意图过滤器顺便说一句的&LT;类...&GT; 标记不使用此意图过滤器

  3. TAG_DISCOVERED

     &LT;意向滤光器&gt;
        &lt;作用机器人:名称=android.nfc.action.TAG_DISCOVERED/&GT;
        &LT;类机器人:名称=android.intent.category.DEFAULT/&GT;
    &所述; /意图滤光器&gt;
     

    这个意图过滤器通常不应在清单中。这意味着作为后备触发,如果没有其他的应用程序可能可能处理检测到NFC标签。使用这会导致糟糕的用户体验(正在启动比如你的应用程序里,标签不能或实际上并不想处理)。它主要适用于符合API 9级(?)的向后兼容性。

为了还搭上了NFC的意图,如果你的活动已经启动,你可以报名参加前景派遣这样的(在 onResume 法):

  PendingIntent pendingIntent = PendingIntent.getActivity(此,0,新的意向(这一点,的getClass())addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),0);
nfcAdapter.enableForegroundDispatch(这一点,pendingIntent,NULL,NULL);
 

这样的话,你会收到,而你的活动是在您的活动的 onNewIntent 法的前景出现的任何NFC发现事件。他们将通过 ACTION_TAG_DISCOVERED 意图出动。

I am new to NFC. I tried to connect to NFC and share the text data from a device to another device.

I searched in forum but it could not solved my issue so any one help me on this. How to do and all.

I installed my application on both the devices and in one device I opened my application and I started tapping the device in another device. It's opening my application with default main action not with the TAG_DISCOvered or something else. Every time it does the same thing. It's not calling the onNewIntent(). (I tried in oncreate to call the onNewIntent, but the action is MAIN only not the other. So can you please tell me where did I go wrong?)

In this code I am not sharing the data. I just need the tag first.

Thank you

Manifest

 <    activity    
  android:name="com.framentos.hellonfc.MainActivity"
        android:clearTaskOnLaunch="true"
        android:label="@string/app_name"
        android:launchMode="singleTop"
        android:screenOrientation="portrait" >
        <intent-filter>
            <action android:name="android.nfc.action.NDEF_DISCOVERED" />

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

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

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

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

        <meta-data
            android:name="android.nfc.action.TECH_DISCOVERED"
            android:resource="@xml/nfc_tech_filter" />
    </activity>

in My Java code

     @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    ctx = this;
    // startHandler();
    _handler = new Handler();
    Button btnWrite = (Button) findViewById(R.id.button);
    message = (TextView) findViewById(R.id.nfcwriteTag);
    btnWrite.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

        }
    });
    adapter = NfcAdapter.getDefaultAdapter(this);
    if (adapter == null) {
        message.setText("NFC is not supported on this device.");
    }
    if (adapter.isEnabled()) {
        message.setText("NFC is Enabled on this device.");
    } else {
        message.setText("Please enable NFC to communicate.");
    }
    pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
            getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
    IntentFilter tagDetected = new IntentFilter(
            NfcAdapter.ACTION_NDEF_DISCOVERED);
    tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
    IntentFilter tagTech = new IntentFilter(
            NfcAdapter.ACTION_TECH_DISCOVERED);
    tagTech.addCategory(Intent.CATEGORY_DEFAULT);
    IntentFilter tagDetect = new IntentFilter(
            NfcAdapter.ACTION_TAG_DISCOVERED);
    tagDetect.addCategory(Intent.CATEGORY_DEFAULT);
    writeTagFilters = new IntentFilter[] { tagDetected, tagTech ,tagDetect};
    // handleIntent(getIntent());
}


    @Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    Log.i(getPackageName(), "on New Intent is called...!");
    handleIntent(getIntent());
}

public void onPause() { super.onPause(); WriteModeOff(); }

@Override
public void onResume() {
    super.onResume();
    WriteModeOn();
}

private void WriteModeOn() {
    writeMode = true;
    adapter.enableForegroundDispatch(this, pendingIntent, writeTagFilters,
            null);
}

private void WriteModeOff() {
    writeMode = false;
    adapter.disableForegroundDispatch(this);
}

解决方案

From the code that you posted in your question, I assume that you did not register your application to send a specific NDEF message. In that case, if your app is open on one device, Android will automatically Beam an NDEF message containing a URI record with the Play Store link of your app and an Android Application Record (AAR) to the other device.

So your second device will receive the following NDEF message:

+-----------------------------------------------------------------------------------------+
| WKT:URI | http://play.google.com/store/apps/details?id=your.package.name&feature=beam |
+-----------------------------------------------------------------------------------------+
| EXT:android:com:pkg | your.package.name                                               |
+-----------------------------------------------------------------------------------------+

What happens now if your app is not already open on the second device is, that the Android Application Record (second record) will force your app to be started. However, looking at your manifest, you do not have an intent filter that matches the first record of this NDEF message (the Play Store URL). Consequently, Android thinks that you do not expect an NDEF message and uses the standard android.intent.action.MAIN (with category android.intent.category.LAUNCHER) to start your app (or rather the first activity of your app that has an intent filter for action MAIN with category LAUNCHER).

In order to receive an NFC intent together with the whole NDEF message in your app, you would need to define a proper intent filter that matches the first record in the above NDEF message:

<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="http"
          android:host="play.google.com"
          android:pathPrefix="/store/apps/details?id=your.package.name" />
</intent-filter>

Now, Android will recognize that your app/activity is ready to receive an NFC intent and pass the NDEF_DISCOVEREDintent to your activity. Note that you still won't receive that intent through onNewIntent() if your app is not already running. Instead you can get the intent that started your activity with the activity's getIntent() method. E.g. in onCreate/onStart/onResume, you could use

Intent intent = getIntent();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
    NdefMessage ndefMessage = null;
    Parcelable[] rawMessages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
    if ((rawMessages != null) && (rawMessages.length > 0)) {
        ndefMessage = (NdefMessage)rawMessages[0];
    }

    // TODO: do something with the received NDEF message
}

to get the intent and the NDEF message.

Regarding the intent filters you already have in your manifest:

  1. NDEF_DISCOVERED:

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

    An NDEF_DISCOVERED intent filter without a <data ... /> tag will never trigger on many NFC devices. You should always define what specific data you expect to be present in the launching NDEF record.

  2. TECH_DISCOVERED:

    <intent-filter>
        <action android:name="android.nfc.action.TECH_DISCOVERED" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
    <meta-data android:name="android.nfc.action.TECH_DISCOVERED"
               android:resource="@xml/nfc_tech_filter" />
    

    You should only use this intent filter if you wan't you application to be started upon detection of a certain NFC tag technology (you define the specific technologies in the nfc_tech_filter.xml file. For your Beam scenario, you would not use such an intent filter. Btw. the <category ...> tag is not used for this intent filter.

  3. TAG_DISCOVERED:

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

    This intent filter should normally not be used in the manifest. It is meant as a fallback that triggers if no other app could possibly handle a detected NFC tag. Using this can lead to bad user-experience (e.g. your app being started for tags it can't or does not actually want to handle). It is primarily available for backward compatibility with API level 9 (?).

In order to also catch the NFC intents if your activity is already started, you could register for the foreground dispatch like this (in the onResume method):

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
nfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null);

That way, you will receive any NFC discovery events that occur while your activity is in the foreground in your activity's onNewIntent method. They will be dispatched through an ACTION_TAG_DISCOVERED intent.

这篇关于NFC标签的检测并没有叫onNewIntent,它的启动从主要活动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆