【问题标题】:onNewIntent not called after tapping to another NFC enabled device在点击另一个启用 NFC 的设备后未调用 onNewIntent
【发布时间】:2016-07-16 10:11:49
【问题描述】:

我正在使用 Xamarin 编写 C# 代码。我尝试通过 NFC 从一台设备共享数据到另一台设备。

打开浏览器 -> 选项 -> 分享 -> App4 到 MainActivity

我的两台设备都在运行同一个应用,我正在将我的设备与另一台设备连接,但没有任何反应。

我认为它无法到达onNewIntent()

我错过了什么吗?我一直很困惑,一直在寻找一个星期。

这是我的代码:

using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Android.Nfc;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms;

namespace App4
{
    [Activity(Label = "App4", MainLauncher = false, Icon = "@drawable/icon",LaunchMode = Android.Content.PM.LaunchMode.SingleTop)]
    [IntentFilter(new[] { Intent.ActionSend , NfcAdapter.ActionNdefDiscovered }, Categories = new[] {
    Intent.CategoryDefault,
    Intent.CategoryBrowsable
    }, DataMimeType = "text/plain")]
    public class MainActivity : Activity
    {
        string share;
        PendingIntent mPendingIntent;
        IntentFilter ndefDetected;
        IntentFilter[] intentF;
        TextView testTV;
        protected override void OnCreate(Bundle bundle)
        {

            base.OnCreate(bundle);
            SetContentView(Resource.Layout.Main);  

            Intent Myintent = new Intent(this, GetType());
            Myintent.SetFlags(ActivityFlags.SingleTop);
            mPendingIntent = PendingIntent.GetActivity(this, 0, Myintent, 0);
            ndefDetected = new IntentFilter(NfcAdapter.ActionNdefDiscovered);
            try
            {
                ndefDetected.AddDataType("text/plain");
                ndefDetected.AddCategory(Intent.CategoryDefault);
            }
            catch { };

            intentF = new IntentFilter[] { ndefDetected };
            NfcAdapter NA = NfcAdapter.GetDefaultAdapter(this);   

            if (NA!=null && NA.IsEnabled)
            {
                Toast.MakeText(this, "Nfc Found", ToastLength.Long).Show();
            }else
            {
                Toast.MakeText(this, "Nfc Not Found", ToastLength.Long).Show();
            }
            testTV = FindViewById<TextView>(Resource.Id.text_view);
            share = Intent.GetStringExtra(Intent.ExtraText);  
            testTV.Text = share;   
    }

        protected override void OnPause()
        {
            base.OnPause();

            NfcManager manager = (NfcManager)GetSystemService(NfcService);
            NfcAdapter adapter = manager.DefaultAdapter;
            adapter.DisableForegroundNdefPush(this);
            adapter.DisableForegroundDispatch(this);
        }

        protected override void OnResume()
        {
            base.OnResume();


            var result2 = new byte[NdefRecord.RtdText.Count];
            NdefRecord.RtdUri.CopyTo(result2, 0);

            NfcManager manager = (NfcManager)GetSystemService(NfcService);
            NdefRecord record = new NdefRecord(NdefRecord.TnfAbsoluteUri,new byte[0], new byte[0], System.Text.Encoding.Default.GetBytes(share));
            manager.DefaultAdapter.EnableForegroundNdefPush(this, new NdefMessage(record));
            manager.DefaultAdapter.EnableForegroundDispatch(this, mPendingIntent, intentF, null);
        }

        protected override void OnNewIntent(Intent intent)
        {

            base.OnNewIntent(intent);
            testTV.Text = "onNewIntent";        
        }
    }
}

这是我的 AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="App4.App4" android:versionCode="1" android:versionName="1.0" android:installLocation="auto">
    <uses-sdk android:minSdkVersion="10" />
    <uses-permission android:name="android.permission.NFC"></uses-permission>
    <application android:label="App4"></application>
</manifest>

【问题讨论】:

    标签: c# android xamarin nfc ndef


    【解决方案1】:

    是的,您遗漏了一些东西:您注册了前台调度以侦听“text/plain”类型的 NDEF 消息,这意味着您需要一个 Text 记录或 MIME 类型 text/plain 的记录。

    ndefDetected = new IntentFilter(NfcAdapter.ActionNdefDiscovered);
    ndefDetected.AddDataType("text/plain");
    ndefDetected.AddCategory(Intent.CategoryDefault);
    intentF = new IntentFilter[] { ndefDetected };
    manager.DefaultAdapter.EnableForegroundDispatch(this, mPendingIntent, intentF, null);
    

    但是,您的应用会推送具有无效(空!)类型名称的绝对 URI 记录。

    NdefRecord record = new NdefRecord(NdefRecord.TnfAbsoluteUri,new byte[0], new byte[0], System.Text.Encoding.Default.GetBytes(share));
    manager.DefaultAdapter.EnableForegroundNdefPush(this, new NdefMessage(record));
    

    为了匹配意图过滤器,您需要推送一条文本记录:

    byte[] text = System.Text.Encoding.UTF8.GetBytes(share);
    byte[] language = System.Text.Encoding.ASCII.GetBytes("en");
    byte[] payload = new byte[1 + language.Count + text.Count];
    payload[0] = (byte)language.Count;
    System.Array.Copy(language, 0, payload, 1, language.Count);
    System.Array.Copy(text, 0, payload, 1 + language.Count, text.Count);
    NdefRecord record = new NdefRecord(NdefRecord.TnfWellKnown, new List<byte>(NdefRecord.RtdText).ToArray(), new byte[0], payload);
    manager.DefaultAdapter.EnableForegroundNdefPush(this, new NdefMessage(record));
    

    【讨论】:

    • 顺便说一句,如何像您的代码一样使用 NedfRecord.RtdText?我现在正在使用 NdefRecord.CreateTextRecord("en", share)。因为有一个错误:“无法从 'System.Collections.Generic.IList'to'byte[]' 转换”。我尝试将其复制到新的 byte[]:result2。它会起作用吗?
    • @wuken 我的更新应该可以解决问题,尽管它可能不是最有效的解决方案。顺便提一句。 NdefRecord.CreateTextRecord 是首选方法(并且基本上包装了我的代码所做的事情)。但是,该方法仅从 API 级别 21 开始可用,而您的清单表明您需要 API 级别 10+。
    • 再次感谢您的耐心和帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-06
    • 1970-01-01
    相关资源
    最近更新 更多