Android读取NFC卡的编号

本文介绍了如何在Android应用中读取NFC卡编号,强调了在AndroidManifest.xml中设置`uses-feature`以限制应用仅在具备NFC功能的设备上运行。同时,为防止每次接收到NFC Intent时启动新Activity,应用需设置为单任务模式,确保在`onNewIntent(Intent intent)`中处理`getId(Intent intent)`。

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

NFC相关androidManifest文件设置:
一、权限:<uses-permission android:name="android.permission.NFC"/>
二、sdk级别限制:<uses-sdk android:minSdkVersion="10"/>

三、特殊功能限制<uses-feature android:name="android.hardware.nfc" android:required="true" />这个生命可以让你的应用在google play上被声明使用者必须拥有nfc功能。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.nfc"
    android:versionCode="1"
    android:versionName="1.0" >

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

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

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:launchMode="singleTask"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.nfc.MainActivity"
            android:label="@string/app_name" >
            <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.TECH_DISCOVERED" />
            </intent-filter>

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

        </activity>
    </application>

</manifest>
上面的android:resource="@xml/nfc_tech_filter"是对tech类型的过滤条件,在res文件夹新建一个xml文件夹,新建nfc_tech_filter.xml文件。


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

下面是封装了读取NFC卡号的一个类:

class NFCCard {

	private Activity context;
	private PendingIntent pendingIntent;
	private NfcAdapter adapter;
	private IntentFilter[] intentFilters;
	private String[][] techLists;
	private final char[] HEX_EXCHANGE = { '0', '1', '2', '3', '4', '5', '6',
			'7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

	public NFCCard(Context context) {
		this.context = (Activity) context;
	}

	void init() {

		adapter = NfcAdapter.getDefaultAdapter(context);
		// 创建一个PendingIntent对象,当Android系统扫描到标签时,则会填充到这个对象。
		pendingIntent = PendingIntent.getActivity(context, 0, new Intent(
				context, context.getClass())
				.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
		IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
		try {
			ndef.addDataType("*/*");
		} catch (MalformedMimeTypeException e) {
			throw new RuntimeException("fail", e);
		}
		intentFilters = new IntentFilter[] { ndef, };
		techLists = new String[][] { new String[] { MifareClassic.class
				.getName() } };
	}

	public boolean open() {
		// TODO 打开NfcAdapter,已打开则返回true。应在onResume()中调用
		if (adapter != null)
			adapter.enableForegroundDispatch(context, pendingIntent,
					intentFilters, techLists);
		return adapter.isEnabled();
	}

	public boolean close() {
		// TODO 关闭NfcAdapter,已关闭则返回true
		if (adapter != null)
			adapter.disableForegroundDispatch(context);
		return !adapter.isEnabled();
	}

	public String getId(Intent intent) {
		// TODO 获取NFC卡的编号。应在onNewIntent()中调用
		Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
		return toHexString(tagFromIntent.getId(), 0,
				tagFromIntent.getId().length);
	}

	private String toHexString(byte[] d, int s, int n) {
		// TODO 转换为十六进制形式的字符串
		final char[] ret = new char[n * 2];
		final int e = s + n;
		int x = 0;
		for (int i = s; i < e; ++i) {
			final byte v = d[i];
			ret[x++] = HEX_EXCHANGE[0x0F & (v >> 4)];
			ret[x++] = HEX_EXCHANGE[0x0F & v];
		}
		return new String(ret);
	}

需要注意的是,上面配置文件中有一个“ android:launchMode="singleTask"”,这是设置应用为单任务。代码中的getId(Intent intent)必须要在Activity的onNewIntent(Intent intent)中执行。因为系统检测到NFC卡的时候,会自动生成封装了相应Tag的Intent,当应用在接收到Intent的时候,默认情况下是启动自己的Activity,这样就会致使每次接收到Intent都会启动新的Activity。把应用设置为单任务后,就可以避免这种情况的发生。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值