扫描打开应用程序时如何在 Android 上使用 NFC 标签
How To Use An NFC Tag On Android When Scanned To Open App
我正在询问以下问题以寻求建议,我已经在线查看(以及 Whosebug 上的类似问题),但没有适合我的解决方案。
我正在编写一个 Android 应用程序(为了全面披露,我正在 Xamarin 中进行 - 但技术 应该 无关紧要)以及我想要的一切要做的是在扫描 NFC 代码时显示警报/消息。如果我打开应用程序并将 NFC 标签放在我的 phone 上,警报会按预期显示。当应用程序关闭并且我将 NFC 标签放在我的 phone 上时,应用程序将打开,但这是目前为止。
我对 Android 开发相当陌生(我以前在通过 Xamarin 创建 Android 应用程序时非常通用,并没有真正使用 NFC / 蓝牙等设备功能)所以如果我我很抱歉遗漏了一些很明显的东西。
using System.Text;
using Android.App;
using Android.Content;
using Android.Nfc;
using Android.OS;
using Android.Support.V7.App;
namespace Android.Demo
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true, LaunchMode = Content.PM.LaunchMode.SingleInstance)]
[IntentFilter(new[] { NfcAdapter.ActionNdefDiscovered }, Categories = new[] { "android.intent.category.DEFAULT" }, DataMimeType = "*/*")]
public class MainActivity : AppCompatActivity
{
private NfcAdapter _nfcAdapter;
private PendingIntent _pendingIntent;
private string[][] _techList = new string[][]{
new[] { "android.nfc.tech.NdefFormatable" } ,
new [] { "android.nfc.tech.NfcA" } ,
new [] { "android.nfc.tech.Ndef" },
new [] { "android.nfc.tech.Ndef" }};
protected override void OnCreate(Bundle savedInstanceState)
{
_nfcAdapter = NfcAdapter.GetDefaultAdapter(this);
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
SetContentView(Resource.Layout.activity_main);
_pendingIntent = PendingIntent.GetActivity(this, 0, Intent, 0);
Android.Support.V7.Widget.Toolbar toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
}
protected override void OnPause()
{
base.OnPause();
if (_nfcAdapter != null && _nfcAdapter.IsEnabled)
_nfcAdapter.DisableForegroundDispatch(this);
}
protected override void OnResume()
{
base.OnResume();
// doStuff();
_nfcAdapter.EnableForegroundDispatch(this, _pendingIntent, new[] { new IntentFilter(NfcAdapter.ActionNdefDiscovered), new IntentFilter(NfcAdapter.ActionTechDiscovered), new IntentFilter(NfcAdapter.ActionTagDiscovered), new IntentFilter(NfcAdapter.ActionNdefDiscovered) }, _techList);
}
protected override void OnNewIntent(Intent intent)
{
var tag = intent.GetParcelableExtra(NfcAdapter.ExtraTag) as Tag;
if (tag != null)
{
// First get all the NdefMessage
var rawMessages = intent.GetParcelableArrayExtra(NfcAdapter.ExtraNdefMessages);
if (rawMessages != null)
{
var msg = (NdefMessage)rawMessages[0];
// Get NdefRecord which contains the actual data
var record = msg.GetRecords()[0];
if (record != null)
{
if (record.Tnf == NdefRecord.TnfWellKnown) // The data is defined by the Record Type Definition (RTD) specification available from http://members.nfc-forum.org/specs/spec_list/
{
// Get the transfered data
var data = Encoding.ASCII.GetString(record.GetPayload());
var alert = new App.AlertDialog.Builder(this).Create();
alert.SetMessage(data);
alert.SetTitle("NFC Tag Located");
alert.Show();
}
}
}
}
}
}
}
谢谢
我有一个应用程序,它在 运行 时读取标签,并注册为处理标签,以便在它不是 运行 时启动。
您可能遗漏的是,当您 运行 时,带有标签的 Intent
中的数据会传递给 OnNewIntent
,但当您不是 运行 Intent
传递给 onCreate
。
我做了类似的事情:-
protected override void OnCreate(Bundle savedInstanceState)
{
// Other onCreate Stuff
// Get any Intent the app was started with
var mIntent = getIntent();
// Check that the Intent contains details about NFC data
var tag = mIntent.GetParcelableExtra(NfcAdapter.ExtraTag) as Tag;
if (tag != null)
{
OnNewIntent(mIntent);
}
注意我不做 Xamarin,所以没有测试,但我在 Java
中做了类似的事情
通常您应该使用 onNewIntent(Intent intent)
来设置您拥有的最后一个 intnet。
我会按以下方式编写您的代码:
using System.Text;
using Android.App;
using Android.Content;
using Android.Nfc;
using Android.OS;
using Android.Support.V7.App;
namespace Android.Demo
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true, LaunchMode = Content.PM.LaunchMode.SingleInstance)]
[IntentFilter(new[] { NfcAdapter.ActionNdefDiscovered }, Categories = new[] { "android.intent.category.DEFAULT" }, DataMimeType = "*/*")]
public class MainActivity : AppCompatActivity
{
private NfcAdapter _nfcAdapter;
private PendingIntent _pendingIntent;
private string[][] _techList = new string[][]{
new[] { "android.nfc.tech.NdefFormatable" } ,
new [] { "android.nfc.tech.NfcA" } ,
new [] { "android.nfc.tech.Ndef" },
new [] { "android.nfc.tech.Ndef" }};
protected override void OnCreate(Bundle savedInstanceState)
{
_nfcAdapter = NfcAdapter.GetDefaultAdapter(this);
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
SetContentView(Resource.Layout.activity_main);
_pendingIntent = PendingIntent.GetActivity(this, 0, Intent, 0);
Android.Support.V7.Widget.Toolbar toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
}
protected override void OnPause()
{
base.OnPause();
if (_nfcAdapter != null && _nfcAdapter.IsEnabled)
_nfcAdapter.DisableForegroundDispatch(this);
}
protected override void OnResume()
{
base.OnResume();
if(isNfcIntent(getIntent())){
processNfcIntent(getIntent());
}
// doStuff();
_nfcAdapter.EnableForegroundDispatch(this, _pendingIntent, new[] { new IntentFilter(NfcAdapter.ActionNdefDiscovered), new IntentFilter(NfcAdapter.ActionTechDiscovered), new IntentFilter(NfcAdapter.ActionTagDiscovered), new IntentFilter(NfcAdapter.ActionNdefDiscovered) }, _techList);
}
protected override void OnNewIntent(Intent intent)
{
setIntent(intent);
}
}
processIntent(Intent intent){
var tag = intent.GetParcelableExtra(NfcAdapter.ExtraTag) as Tag;
// First get all the NdefMessage
var rawMessages = intent.GetParcelableArrayExtra(NfcAdapter.ExtraNdefMessages);
if (rawMessages != null)
{
var msg = (NdefMessage)rawMessages[0];
// Get NdefRecord which contains the actual data
var record = msg.GetRecords()[0];
if (record != null)
{
if (record.Tnf == NdefRecord.TnfWellKnown) // The data is defined by the Record Type Definition (RTD) specification available from http://members.nfc-forum.org/specs/spec_list/
{
// Get the transfered data
var data = Encoding.ASCII.GetString(record.GetPayload());
var alert = new App.AlertDialog.Builder(this).Create();
alert.SetMessage(data);
alert.SetTitle("NFC Tag Located");
alert.Show();
}
}
}
}
}
所以在这种情况下,如果应用程序启动是因为触摸 NFC 标签,processNfcIntent(Intent intent)
将在应用程序启动时被调用,如果 onNewIntent(Intent intent)
被调用,它将被调用。
android 总是会在 onNewIntent(Intent intent)
之后调用 onResume()
。
如果意图不是 nfc 意图,函数 isNfcIntent(Intent intent)
应该 return false 例如:
private boolean isNfcIntent(Intent intent){
var tag = intent.GetParcelableExtra(NfcAdapter.ExtraTag) as Tag;
return tag != null;
}
我正在询问以下问题以寻求建议,我已经在线查看(以及 Whosebug 上的类似问题),但没有适合我的解决方案。
我正在编写一个 Android 应用程序(为了全面披露,我正在 Xamarin 中进行 - 但技术 应该 无关紧要)以及我想要的一切要做的是在扫描 NFC 代码时显示警报/消息。如果我打开应用程序并将 NFC 标签放在我的 phone 上,警报会按预期显示。当应用程序关闭并且我将 NFC 标签放在我的 phone 上时,应用程序将打开,但这是目前为止。
我对 Android 开发相当陌生(我以前在通过 Xamarin 创建 Android 应用程序时非常通用,并没有真正使用 NFC / 蓝牙等设备功能)所以如果我我很抱歉遗漏了一些很明显的东西。
using System.Text;
using Android.App;
using Android.Content;
using Android.Nfc;
using Android.OS;
using Android.Support.V7.App;
namespace Android.Demo
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true, LaunchMode = Content.PM.LaunchMode.SingleInstance)]
[IntentFilter(new[] { NfcAdapter.ActionNdefDiscovered }, Categories = new[] { "android.intent.category.DEFAULT" }, DataMimeType = "*/*")]
public class MainActivity : AppCompatActivity
{
private NfcAdapter _nfcAdapter;
private PendingIntent _pendingIntent;
private string[][] _techList = new string[][]{
new[] { "android.nfc.tech.NdefFormatable" } ,
new [] { "android.nfc.tech.NfcA" } ,
new [] { "android.nfc.tech.Ndef" },
new [] { "android.nfc.tech.Ndef" }};
protected override void OnCreate(Bundle savedInstanceState)
{
_nfcAdapter = NfcAdapter.GetDefaultAdapter(this);
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
SetContentView(Resource.Layout.activity_main);
_pendingIntent = PendingIntent.GetActivity(this, 0, Intent, 0);
Android.Support.V7.Widget.Toolbar toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
}
protected override void OnPause()
{
base.OnPause();
if (_nfcAdapter != null && _nfcAdapter.IsEnabled)
_nfcAdapter.DisableForegroundDispatch(this);
}
protected override void OnResume()
{
base.OnResume();
// doStuff();
_nfcAdapter.EnableForegroundDispatch(this, _pendingIntent, new[] { new IntentFilter(NfcAdapter.ActionNdefDiscovered), new IntentFilter(NfcAdapter.ActionTechDiscovered), new IntentFilter(NfcAdapter.ActionTagDiscovered), new IntentFilter(NfcAdapter.ActionNdefDiscovered) }, _techList);
}
protected override void OnNewIntent(Intent intent)
{
var tag = intent.GetParcelableExtra(NfcAdapter.ExtraTag) as Tag;
if (tag != null)
{
// First get all the NdefMessage
var rawMessages = intent.GetParcelableArrayExtra(NfcAdapter.ExtraNdefMessages);
if (rawMessages != null)
{
var msg = (NdefMessage)rawMessages[0];
// Get NdefRecord which contains the actual data
var record = msg.GetRecords()[0];
if (record != null)
{
if (record.Tnf == NdefRecord.TnfWellKnown) // The data is defined by the Record Type Definition (RTD) specification available from http://members.nfc-forum.org/specs/spec_list/
{
// Get the transfered data
var data = Encoding.ASCII.GetString(record.GetPayload());
var alert = new App.AlertDialog.Builder(this).Create();
alert.SetMessage(data);
alert.SetTitle("NFC Tag Located");
alert.Show();
}
}
}
}
}
}
}
谢谢
我有一个应用程序,它在 运行 时读取标签,并注册为处理标签,以便在它不是 运行 时启动。
您可能遗漏的是,当您 运行 时,带有标签的 Intent
中的数据会传递给 OnNewIntent
,但当您不是 运行 Intent
传递给 onCreate
。
我做了类似的事情:-
protected override void OnCreate(Bundle savedInstanceState)
{
// Other onCreate Stuff
// Get any Intent the app was started with
var mIntent = getIntent();
// Check that the Intent contains details about NFC data
var tag = mIntent.GetParcelableExtra(NfcAdapter.ExtraTag) as Tag;
if (tag != null)
{
OnNewIntent(mIntent);
}
注意我不做 Xamarin,所以没有测试,但我在 Java
中做了类似的事情通常您应该使用 onNewIntent(Intent intent)
来设置您拥有的最后一个 intnet。
我会按以下方式编写您的代码:
using System.Text;
using Android.App;
using Android.Content;
using Android.Nfc;
using Android.OS;
using Android.Support.V7.App;
namespace Android.Demo
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true, LaunchMode = Content.PM.LaunchMode.SingleInstance)]
[IntentFilter(new[] { NfcAdapter.ActionNdefDiscovered }, Categories = new[] { "android.intent.category.DEFAULT" }, DataMimeType = "*/*")]
public class MainActivity : AppCompatActivity
{
private NfcAdapter _nfcAdapter;
private PendingIntent _pendingIntent;
private string[][] _techList = new string[][]{
new[] { "android.nfc.tech.NdefFormatable" } ,
new [] { "android.nfc.tech.NfcA" } ,
new [] { "android.nfc.tech.Ndef" },
new [] { "android.nfc.tech.Ndef" }};
protected override void OnCreate(Bundle savedInstanceState)
{
_nfcAdapter = NfcAdapter.GetDefaultAdapter(this);
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
SetContentView(Resource.Layout.activity_main);
_pendingIntent = PendingIntent.GetActivity(this, 0, Intent, 0);
Android.Support.V7.Widget.Toolbar toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
}
protected override void OnPause()
{
base.OnPause();
if (_nfcAdapter != null && _nfcAdapter.IsEnabled)
_nfcAdapter.DisableForegroundDispatch(this);
}
protected override void OnResume()
{
base.OnResume();
if(isNfcIntent(getIntent())){
processNfcIntent(getIntent());
}
// doStuff();
_nfcAdapter.EnableForegroundDispatch(this, _pendingIntent, new[] { new IntentFilter(NfcAdapter.ActionNdefDiscovered), new IntentFilter(NfcAdapter.ActionTechDiscovered), new IntentFilter(NfcAdapter.ActionTagDiscovered), new IntentFilter(NfcAdapter.ActionNdefDiscovered) }, _techList);
}
protected override void OnNewIntent(Intent intent)
{
setIntent(intent);
}
}
processIntent(Intent intent){
var tag = intent.GetParcelableExtra(NfcAdapter.ExtraTag) as Tag;
// First get all the NdefMessage
var rawMessages = intent.GetParcelableArrayExtra(NfcAdapter.ExtraNdefMessages);
if (rawMessages != null)
{
var msg = (NdefMessage)rawMessages[0];
// Get NdefRecord which contains the actual data
var record = msg.GetRecords()[0];
if (record != null)
{
if (record.Tnf == NdefRecord.TnfWellKnown) // The data is defined by the Record Type Definition (RTD) specification available from http://members.nfc-forum.org/specs/spec_list/
{
// Get the transfered data
var data = Encoding.ASCII.GetString(record.GetPayload());
var alert = new App.AlertDialog.Builder(this).Create();
alert.SetMessage(data);
alert.SetTitle("NFC Tag Located");
alert.Show();
}
}
}
}
}
所以在这种情况下,如果应用程序启动是因为触摸 NFC 标签,processNfcIntent(Intent intent)
将在应用程序启动时被调用,如果 onNewIntent(Intent intent)
被调用,它将被调用。
android 总是会在 onNewIntent(Intent intent)
之后调用 onResume()
。
如果意图不是 nfc 意图,函数 isNfcIntent(Intent intent)
应该 return false 例如:
private boolean isNfcIntent(Intent intent){
var tag = intent.GetParcelableExtra(NfcAdapter.ExtraTag) as Tag;
return tag != null;
}