Mono for Android 之NFC

现在很多国外的手机都支持NFC功能,包括google、三星、HTC等。但中国的手机基本不支持,可能是考虑价格因素,而且NFC应用在中国还很少。NFC功能应该会成为以后的标配吧,这几年NFC应用应该会多起来,包括手机支付、手机刷公交等等。

NFC即near filed communication(近场通信),在RFID技术上发展而来。是由飞利浦公司发起,由诺基亚、索尼等著名厂商联合主推的一项无线技术。

现在市场出现了很多NFC卡,主要包括Mifare卡、felica卡。NFC卡主要是指符合ISO/IEC 14443标准的卡,类型有TypeA、TypeB、TypeF,TypeA和TypeB主要指Mifare卡,TypeF主要是指Felica卡。Mifare卡在欧洲很流行,Felica卡在日本很流行。TypeA卡和TypeB卡主要是在字符编码等方面有些不同

NFC卡又分为逻辑加密和CPU卡。CPU卡是非常安全的,现在的金融卡用的就是这种卡。逻辑加密卡相对来也是安全的,但是国外有人已经把它破解了。逻辑加密可以参考Mifare相关文档,看是怎么进行密钥验证以及权限控制。

在CPU卡中有一种卡叫java卡,java卡的出现,让程序员编写的程序可以在不同厂商生产的java卡上运行。因为每个厂商生成的NFC卡中的cos都可能不一样,所以如果直接在CPU卡上进行编程,移植性就会很差。CPU卡相当与一台微型计算机没有输入设备,也没有输出设备,但可以进行加解密,把信息加密后进行传输,所以CPU卡是很安全的。

好,说了那么多,我们看一下Android是怎么支持的。如果我们是在Android手机进行简单的NFC开发,那是非常简单的,上面的知识可以一点都不了解,也可以开发一个简单的NFC程序。

在AndroidManifest.xml配置如下

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" android:versionCode="100000" android:versionName="Release_V1.0.0" package="NFCTR.Android">
  <uses-sdk android:targetSdkVersion="10" />
  <application android:label="@string/ApplicationName" android:icon="@drawable/icon">
		<activity
					 android:name="nfctr.app.ActTagReader"
					 android:label="@string/ApplicationName"
					 android:noHistory="true"
            >
			<intent-filter>
				<action android:name="android.intent.action.MAIN" />
				<category android:name="android.intent.category.LAUNCHER" />
			</intent-filter>
			<intent-filter>
				<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
				<data android:mimeType="*/*" />
				<category android:name="android.intent.category.DEFAULT"/>
			</intent-filter>
			<intent-filter>
				<action android:name="android.nfc.action.ACTION_TECH_DISCOVERED"/>
				<category android:name="android.intent.category.DEFAULT"/>
			</intent-filter>
			<intent-filter>
				<action android:name="android.nfc.action.TECH_DISCOVERED" />
			</intent-filter>
			<meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/nfc_tech_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.nfc.action.TAG_DISCOVERED"/>
			</intent-filter>
		</activity>
  </application>
  	<uses-feature android:name="android.hardware.nfc" android:required="true" />
	<uses-permission android:name="android.permission.NFC" />
</manifest>

nfc_tech_filter.xml文件内容如下(放在Resources目录下的Xml目录下,记着Xml目录的X一定要大写,这是Mono)

 

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.IsoDep</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcA</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcB</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcF</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcV</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.Ndef</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NdefFormatable</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.MifareClassic</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.MifareUltralight</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcA</tech>
        <tech>android.nfc.tech.MifareClassic</tech>
        <tech>android.nfc.tech.NdefFormatable</tech>
    </tech-list>
</resources>


 

intent-filter用来过滤该Activity多哪些NFC Tag感兴趣。该配置基本上是对所有的NFC Tag感兴趣

Activity ActTagReader界面代码如下:

protected override void OnCreate(Bundle bundle)
		{
			base.OnCreate(bundle);
			m_NFCAdapter = NfcAdapter.GetDefaultAdapter(this);
			string intentType = Intent.Type ?? String.Empty;

			//if (intentType != String.Empty) // 发现新的NFC卡
			{
				// 获取卡ID
				byte[] id = Intent.GetByteArrayExtra(NfcAdapter.ExtraId);
			}
		}


当手机发现NFC卡后就会看哪些程序对NFC卡感兴趣,如果你手机只有这么一个对NFC感兴趣的APP的话,那么手机会直接打开该程序,在OnCreate中,我们可以获取卡的ID。

上面这样执行,每次都会打开一个新的界面。如果有多个对NFC感兴趣的APP,每次都还让你选择一下。如果我们想在打开ActTagReader界面的情况下,就使用该界面来处理NFC Tag,且不打开一个新的ActTagReader界面,那就要添加以下代码

在OnResume方法中启动前端分派系统,在OnPause方法中停止前端分派系统

/// <summary>
		/// 当应用程序恢复运行时,创建一个IntentFilter,当有NFC标签被扫描时,调用OnNewIntent方法
		/// </summary>
		protected override void OnResume()
		{
			base.OnResume();

			var ndefDetected = new IntentFilter(NfcAdapter.ActionNdefDiscovered);
			ndefDetected.AddCategory(Intent.CategoryDefault);
			ndefDetected.AddDataType("*/*");
			var techDetected = new IntentFilter(NfcAdapter.ActionTechDiscovered);
			techDetected.AddCategory(Intent.CategoryDefault);
			techDetected.AddDataType("*/*");
			var tagDetected = new IntentFilter(NfcAdapter.ActionTagDiscovered);
			tagDetected.AddCategory(Intent.CategoryDefault);
			tagDetected.AddDataType("*/*");
			var filters = new[] {  techDetected };
			var intent = new Intent(this, GetType()).AddFlags(ActivityFlags.SingleTop);
			var pendingIntent = PendingIntent.GetActivity(this, 0, intent, 0);

			String[][] techListsArray = new String[][] {
				new String[]{"android.nfc.tech.IsoDep"},
			    new String[]{"android.nfc.tech.NfcA"},
			    new String[]{"android.nfc.tech.NfcB"},
			    new String[]{"android.nfc.tech.NfcF"},
			    new String[]{"android.nfc.tech.NfcV"},
			    new String[]{"android.nfc.tech.Ndef"},
			    new String[]{"android.nfc.tech.NdefFormatable"},
			    new String[]{"android.nfc.tech.MifareClassic"},
			    new String[]{"android.nfc.tech.MifareUltralight"},
			new String[] {"android.nfc.tech.NfcA", "android.nfc.tech.MifareClassic", "android.nfc.tech.NdefFormatable"}};

			m_NFCAdapter.EnableForegroundDispatch(this, pendingIntent, filters, techListsArray);
		}

		protected override void OnPause()
		{
			base.OnPause();
			// 应用程序暂停,所以需要移除对NFC标签的监听
			m_NFCAdapter.DisableForegroundDispatch(this);
		}

OK,填加了以上代码后,在打开ActTagReader界面时,NFC手机发现NFC Tag就会丢给给当前Activity去处理,并执行OnNewIntent方法,所以我们需要覆写OnNewIntent方法

/// <summary>
		/// 当应用程序发现NFC标签时会执行该方法
		/// </summary>
		/// <param name="intent"></param>
		protected override void OnNewIntent(Intent intent)
		{
			string intentType = intent.Type ?? String.Empty;

			//if (intentType != String.Empty) // 发现新的NFC卡
			{
				byte[] id = intent.GetByteArrayExtra(NfcAdapter.ExtraId);
			}
		}

在OnNewIntent中就可以获取NFC卡的ID以及对NFC进行读写


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值