手机NFC基础

NFC是一种非接触式无线通信技术,用于移动设备、电子设备间的信息交换和服务。在Android开发中,NFC终端有3种工作模式:主动模式、被动模式和双向模式。通过Android.nfc包,开发者可以与NFC适配器交互处理tags和NDEF数据格式。集成NFC功能能实现移动支付、位置服务等多种便捷应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

NFC--近距离无线通信技术(Near Field Communication,NFC),是由飞利浦公司和索尼公司共同开发的一种非接触式识别和互联技术,可以在移动设备、消费类电子产品、PC和智能设备间进行近距离无线通信。NFC提供了一种简单的、非触控式的解决方案,可以让消费者简单直观地交换信息、访问内容与服务。NFC整合了非接触式读卡器、非接触式智能卡和点对点(Peer-to—Peer)通信功能,为消费者开创了全新的便捷生活方式。手机和NFC技术的结合,将会给消费者提供极大的生活便利,例如移动支付、位置服务信息、公共交通卡等应用。安卓开发,需要了解NFC终端有3种工作模式:

1)主动模式,NFC终端作为一个读卡器,主动发出自己的射频场去识别和读,写别的NFC设备;
2)被动模式,NFC终端可以模拟成一个智能卡被读,写,它只在其他设备发出的射频场中被动响应;
3)双向模式,双方都主动发出射频场来建立点对点的通信”

Android.nfc package包含顶层类用来与本地NFC适配器交互. 这些类可以表示被检测到的tags和用NDEF数据格式。

class

Description

NfcManager

一个NFC adapter的管理器,可以列出所有此android设备支持的NFC adapter.只不过大部分android 设备只有一个NFC adapter,所以你大部分情况下可以直接用静态方法 getDefaultAdapter(context)来取适配器。

NfcAdapter

表示本设备的NFC adapter,可以定义Intent来请求将系统检测到tags的提醒发送到你的Activity.并提供方法去注册前台tag提醒发布和前台NDEF推送。 前台NDEF推送是当前android版本唯一支持的p2p NFC通信方式。

NdefMessageandNdefRecord

NDEF是NFC论坛定义的数据结构,用来有效的存数据到NFC tags.比如文本,URL,和其他MIME类型。一个NdefMessage扮演一个容器,这个容器存哪些发送和读到的数据。一个NdefMessage对象包含0或多个NdefRecord,每个NDEF record有一个类型,比如文本,URL,智慧型海报/广告,或其他MIME数据。在NDEFMessage里的第一个NfcRecord的类型用来发送tag到一个android设备上的activity.

Tag

标示一个被动的NFC目标,比如tag,card,钥匙挂扣,甚至是一个电话模拟的的NFC卡.

当一个tag被检测到,一个tag对象将被创建并且封装到一个Intent里,然后NFC 发布系统将这个Intent用startActivity发送到注册了接受这种Intent的activity里。你可以用getTechList()方法来得到这个tag支持的技术细节和创建一个android.nfc.tech提供的相应的TagTechnology对象。

注册清单设置:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.demo.xnfc"
    android:versionCode="15"
    android:versionName="2.3" >

    <uses-sdk
        android:minSdkVersion="10"
        android:targetSdkVersion="19" />

    <uses-permission android:name="android.permission.NFC" />


    <uses-feature
        android:name="android.hardware.nfc"
        android:required="true" />


    <application
        android:name=".ThisApplication"
        android:allowBackup="false"
        android:hardwareAccelerated="true"
        android:icon="@drawable/nfcard"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <meta-data
            android:name="android.nfc.disable_beam_default"
            android:value="true" />


        <activity
            android:name="com.demo.xnfc.MainActivity"
            android:alwaysRetainTaskState="false"
            android:configChanges="orientation|screenSize"
            android:label="@string/app_name"
            android:launchMode="singleTask"
            android:windowSoftInputMode="adjustUnspecified|stateAlwaysHidden" >
            <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" />  <!-- NDEF_DISCOVERED过滤 -->
                <action android:name="android.nfc.action.TECH_DISCOVERED" /> <!-- TECH_DISCOVERED过滤 -->
                <action android:name="android.nfc.action.TAG_DISCOVERED" /> <!-- TAG_DISCOVERED过滤 -->
            </intent-filter>
            <meta-data
                android:name="android.nfc.action.TECH_DISCOVERED"
                android:resource="@xml/nfc_tech_filter" /> <!-- 自定义res/xml/nfc_techfilter。xml-->
            
        </activity>
    </application>

</manifest>
<?xml version="1.0" encoding="utf-8"?> <!-- 自定义res/xml/nfc_techfilter。xml-->
<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.NfcF</tech>
	</tech-list>
</resources>
主要代码:  NfcAdapter.getDefaultAdapter(this);
import android.app.Activity;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
import android.text.method.LinkMovementMethod;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.ViewSwitcher;
import com.demo.xnfc.R;
import com.sinpo.xnfc.nfc.NfcManager;
import com.sinpo.xnfc.ui.AboutPage;
import com.sinpo.xnfc.ui.MainPage;
import com.sinpo.xnfc.ui.NfcPage;
import com.sinpo.xnfc.ui.Toolbar;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main); 

		initViews(); 

		nfc = new NfcManager(this);

		onNewIntent(getIntent());
	}

	@Override
	public void onBackPressed() {
		if (isCurrentPage(SPEC.PAGE.ABOUT))
			loadDefaultPage();
		else if (safeExit)
			super.onBackPressed();
	}

	@Override
	public void setIntent(Intent intent) {
		if (NfcPage.isSendByMe(intent))
			loadNfcPage(intent);
		else if (AboutPage.isSendByMe(intent))
			loadAboutPage();
		else
			super.setIntent(intent);
	}

	@Override
	protected void onPause() {
		super.onPause();
		nfc.onPause();
	}

	@Override
	protected void onResume() {
		super.onResume();
		nfc.onResume();
	}

	@Override
	public void onWindowFocusChanged(boolean hasFocus) {
		if (hasFocus) {
			if (nfc.updateStatus())
				loadDefaultPage();

			// 有些ROM将关闭系统状态下拉面板的BACK事件发给最顶层窗口
			// 这里加入一个延迟避免意外退出
			board.postDelayed(new Runnable() {
				public void run() {
					safeExit = true;
				}
			}, 800);
		} else {
			safeExit = false;
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		loadDefaultPage();
	}

	@Override
	protected void onNewIntent(Intent intent) {
		if (!nfc.readCard(intent, new NfcPage(this)))
			loadDefaultPage();
	}

	public void onSwitch2DefaultPage(View view) {
		if (!isCurrentPage(SPEC.PAGE.DEFAULT))
			loadDefaultPage();
	}

	public void onSwitch2AboutPage(View view) {
		if (!isCurrentPage(SPEC.PAGE.ABOUT))
			loadAboutPage();
	}

	public void onCopyPageContent(View view) {
		toolbar.copyPageContent(getFrontPage());
	}

	public void onSharePageContent(View view) {
		toolbar.sharePageContent(getFrontPage());
	}

	private void loadDefaultPage() {
		toolbar.show(null);

		TextView ta = getBackPage();

		resetTextArea(ta, SPEC.PAGE.DEFAULT, Gravity.CENTER);
		ta.setText(MainPage.getContent(this));

		board.showNext();
	}

	private void loadAboutPage() {
		toolbar.show(R.id.btnBack);

		TextView ta = getBackPage();

		resetTextArea(ta, SPEC.PAGE.ABOUT, Gravity.LEFT);
		ta.setText(AboutPage.getContent(this));

		board.showNext();
	}

	private void loadNfcPage(Intent intent) {
		final CharSequence info = NfcPage.getContent(this, intent);

		TextView ta = getBackPage();

		if (NfcPage.isNormalInfo(intent)) {
			toolbar.show(R.id.btnCopy, R.id.btnShare, R.id.btnReset);
			resetTextArea(ta, SPEC.PAGE.INFO, Gravity.LEFT);
		} else {
			toolbar.show(R.id.btnBack);
			resetTextArea(ta, SPEC.PAGE.INFO, Gravity.CENTER);
		}

		ta.setText(info);

		board.showNext();
	}

	private boolean isCurrentPage(SPEC.PAGE which) {
		Object obj = getFrontPage().getTag();

		if (obj == null)
			return which.equals(SPEC.PAGE.DEFAULT);

		return which.equals(obj);
	}

	private void resetTextArea(TextView textArea, SPEC.PAGE type, int gravity) {

		((View) textArea.getParent()).scrollTo(0, 0);

		textArea.setTag(type);
		textArea.setGravity(gravity);
	}

	private TextView getFrontPage() {
		return (TextView) ((ViewGroup) board.getCurrentView()).getChildAt(0);
	}

	private TextView getBackPage() {
		return (TextView) ((ViewGroup) board.getNextView()).getChildAt(0);
	}

	private void initViews() {
		board = (ViewSwitcher) findViewById(R.id.switcher);

		Typeface tf = ThisApplication.getFontResource(R.string.font_oem1);
		TextView tv = (TextView) findViewById(R.id.txtAppName);
		tv.setTypeface(tf);

		tf = ThisApplication.getFontResource(R.string.font_oem2);

		tv = getFrontPage();
		tv.setMovementMethod(LinkMovementMethod.getInstance());
		tv.setTypeface(tf);

		tv = getBackPage();
		tv.setMovementMethod(LinkMovementMethod.getInstance());
		tv.setTypeface(tf);

		toolbar = new Toolbar((ViewGroup) findViewById(R.id.toolbar));
	}

	private ViewSwitcher board;
	private Toolbar toolbar;
	private NfcManager nfc;
	private boolean safeExit;
}
github demo例子:

https://codeload.github.com/sinpolib/nfcard/zip/master 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值