NFC communication of Android hardware communication

1. Introduction

​​​​​​​​1.1 NFC is another new short-range wireless transmission technology after wifi and Bluetooth. This kind of limitation is relatively large. The device must be equipped with NFC hardware to realize data transmission, and the transmission distance is very short. , It can only be transmitted within 4cm, and the real scene may only be transmitted when touched.

1.2 Advantages and disadvantages of NFC

Advantages: fast transmission speed; convenient connection, communication can be realized by touching; high security

Disadvantages: the transmission distance is very short; the amount of transmitted data is small; not all popular, some mobile phones do not support

1.3 NFC, Bluetooth, infrared contrast

Comparison item NFC Bluetooth infrared
Network Type peer to peer point-to-multipoint peer to peer
effective distance <=0.1m <=10m, the latest Bluetooth 4.0 effective distance up to 100m Generally within 1m, thermal technology connection, unstable
transfer speed Maximum 424kbps Maximum 24Mbps Slow 115.2kbp5, Fast 4Mbps
connection time <0.1s 6s 0.5s
safety security, hardware implementation Security, Software Implementation safety, except when using IRFM
communication mode active-active/passive active-active active-active
cost Low middle Low

1.4 NFC communication mode

Card reader mode (Reader/writer mode), emulation card mode (Card Emulation Mode), peer-to-peer mode (P2P mode).

card reader mode

The data in the NFC chip can be simply understood as "swiping tags". In essence, it is to read and write information from labels, stickers, business cards and other media with NFC chips through mobile phones or other electronic devices that support NFC. Usually NFC tags do not require external power supply. When an NFC-enabled peripheral reads and writes data to NFC, it will send some kind of magnetic field, and this magnetic field will automatically supply power to the NFC tag.

emulation card mode

Data in a mobile phone or other electronic device that supports NFC can be simply understood as "swiping the mobile phone". In essence, it is to use NFC-enabled mobile phones or other electronic devices as IC cards such as debit cards, bus cards, and access control cards. The basic principle is to encapsulate the information certificate in the corresponding IC card into a data packet and store it in the peripheral device supporting NFC.

An NFC radio frequency device (equivalent to a card reader) is also required when using it. Put the mobile phone close to the NFC radio frequency device, and the mobile phone will receive the signal sent by the NFC radio frequency device. After passing a series of complex verifications, the corresponding information of the IC card will be transmitted to the NFC radio frequency device, and finally the IC card data will be transmitted to the NFC radio frequency device. The computer connected to the radio frequency device, and perform corresponding processing (such as electronic transfer, door opening, etc.).

peer-to-peer mode

This mode is similar to Bluetooth and infrared, and is used for data exchange between different NFC devices, but this mode does not have the feeling of "swiping". Its effective distance generally cannot exceed 4 cm, but the transmission establishment speed is much faster than infrared and Bluetooth technology, and the transmission speed is much faster than infrared. If both parties use Android 4.2, NFC will directly use Bluetooth to transmit. This technology is called Android Beam. So two devices using Android Beam to transfer data are no longer limited to within 4cm.

A typical application of peer-to-peer mode is peer-to-peer data transmission between two NFC-enabled mobile phones or tablets, for example, exchanging pictures or synchronizing device contacts. Therefore, through NFC, multiple devices such as digital cameras, computers, and mobile phones can be quickly connected and exchange data or services.

Two, NFC communication steps

2.1 AndroidManifest.xml adds NFC permission without dynamic request

<!--NFC 相关权限-->
<!--描述所需硬件特性-->
<uses-feature
	android:name="android.hardware.nfc"
	android:required="true" />
<uses-permission android:name="android.permission.NFC" />

2.2 Add NFC tag filtering, two ways

Method 1: Add xml configuration to the Activity tag of AndroidManifest.xml

Create a new xml folder in the res directory, and then create a new nfc_tech_filter.xml file

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <!-- 可以处理所有Android支持的NFC类型 -->
    <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.MifareUltralight</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.MifareClassic</tech>
    </tech-list>
</resources>

The activity tag configures the xml

<activity
	android:name=".MainActivity"
	android:exported="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.TECH_DISCOVERED" />
	</intent-filter>
	<meta-data
		android:name="android.nfc.action.TECH_DISCOVERED"
		android:resource="@xml/nfc_tech_filter" />

</activity>

 Method 2: Dynamically configure tags when initializing NFC

/**
 * 初始化nfc设置
 */
public static void NfcInit(Activity activity) {
	Intent intent = new Intent(activity, activity.getClass());
	intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
	mPendingIntent = PendingIntent.getActivity(activity, 0, intent, 0);
	//做一个IntentFilter过滤你想要的action 这里过滤的是ndef
	IntentFilter filter = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
	//如果你对action的定义有更高的要求,比如data的要求,你可以使用如下的代码来定义intentFilter
	//        IntentFilter filter2 = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
	//        try {
	//            filter.addDataType("*/*");
	//        } catch (IntentFilter.MalformedMimeTypeException e) {
	//            e.printStackTrace();
	//        }
	//        mIntentFilter = new IntentFilter[]{filter, filter2};
	//        mTechList = null;
	  try {
			filter.addDataType("*/*");
	  } catch (IntentFilter.MalformedMimeTypeException e) {
			e.printStackTrace();
	  }
	mTechList = new String[][]{
   
   {MifareClassic.class.getName()},
		{NfcA.class.getName()}};
	//生成intentFilter
	mIntentFilter = new IntentFilter[]{filter};
}

2.3 Create NFC Adapter

All operations of NFC are completed through NfcAdapter. After creating NfcAdapter, create a waiting PendingIntent at the same time. This is mainly used to start NFC to open the page.

private NfcAdapter mNfcAdapter;
private PendingIntent mPendingIntent;
@Override
protected void onStart() {
	super.onStart();
	mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
	mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass())
			.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

}

2.4 Turn on foreground scheduling in onResume to initialize NFC

//在onResume中开启前台调度
@Override
protected void onResume() {
	super.onResume();
	//设定intentfilter和tech-list。如果两个都为null就代表优先接收任何形式的TAG action。也就是说系统会主动发TAG intent。
	if (mNfcAdapter != null) {
		mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, null, null); //启动        }
	}
}

2.5 Handle the intent passed by the NFC device in onNewIntent


//在onNewIntent中处理由NFC设备传递过来的intent
@Override
protected void onNewIntent(Intent intent) {
	super.onNewIntent(intent);
	processIntent(intent);
}

2.6 Process the read data, including the card ID (usually the device serial number, in hexadecimal form 09:D1:E6:6B)

Then other information of the NFC card may not be available. The information of the NFC card label may not be available, but the serial number must be available, which is the unique identification of the NFC card.

//这块的processIntent() 就是处理卡中数据的方法
public void processIntent(Intent intent) {
	try {
		tvContent.setText("");
		// 检测卡的id
		String id = readNFCId(intent);
		// NfcUtils中获取卡中数据的方法
		String result = readNFCFromTag(intent);
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.append("卡ID十六进制:" + id).append("\r\n");
		stringBuilder.append("卡ID十进制:" + hexToDec(id)).append("\r\n");
		stringBuilder.append("信息:").append("\r\n");
		stringBuilder.append(result).append("\r\n");


		tvContent.setText(stringBuilder);
		
		// 往卡中写数据
		//String data = "this.is.write";
		//writeNFCToTag(data, intent);
	} catch (Exception e) {
		e.printStackTrace();
	}
}

/**
 * 读取nfcID
 */
public String readNFCId(Intent intent) throws UnsupportedEncodingException {
	Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
	String id = ByteArrayToHexString(tag.getId());
	return id;
}


/**
 * 读取NFC的数据
 */
public String readNFCFromTag(Intent intent) throws UnsupportedEncodingException {
	Parcelable[] rawArray = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
	StringBuilder stringBuilder = new StringBuilder();
	if (rawArray != null) {
		for (int i = 0; i < rawArray.length; i++) {
			NdefMessage mNdefMsg = (NdefMessage) rawArray[i];

			for (int j = 0; j < mNdefMsg.getRecords().length; i++) {
				NdefRecord mNdefRecord = mNdefMsg.getRecords()[j];

				if (mNdefRecord != null) {
					String readResult = new String(mNdefRecord.getPayload(), "UTF-8");
					stringBuilder.append(readResult).append("\r\n");
				}
			}
		}
	}
	return stringBuilder.toString();
}


/**
 * 十六进制转10进制
 * @param s
 * @return
 */
public static int hexToDec(String s) {
	String s1 = s.toUpperCase(); // 全转大写
	char[] chars = s1.toCharArray(); // 转成 char 数组
	Stack<Character> stack = new Stack<>();
	for (int i = 0; i < chars.length; i++) {
		stack.push(chars[i]); // 放入栈中,倒序遍历
	}
	int sum = 0;  // 定义总和
	int size = stack.size(); // 要先赋值给 size ,不然 stack.pop() 之后 size 会变
	for (int i = 0; i < size; i++) {
		Character pop = stack.pop();
		if (String.valueOf(pop).matches("[A-F]")) {  // 如果是 A-F
			sum += (Math.pow(16, i) * ((pop - 55))); // A的ASCII码为 65,取偏移量
		} else { // 如果是纯数字
			sum += Math.pow(16, i) * Integer.parseInt(String.valueOf(pop));
		}
	}
	return sum;
}


/**
 * 将字节数组转换为字符串
 */
private String ByteArrayToHexString(byte[] inarray) {
	int i, j, in;
	String[] hex = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"};
	String out = "";

	for (j = 0; j < inarray.length; ++j) {
		in = (int) inarray[j] & 0xff;
		i = (in >> 4) & 0x0f;
		out += hex[i];
		i = in & 0x0f;
		out += hex[i];
	}
	return out;
}

2.7 Write data to NFC

/**
 * 往nfc写入数据
 */
public static void writeNFCToTag(String data, Intent intent){
	try {
		Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
		Ndef ndef = Ndef.get(tag);
		ndef.connect();
		NdefRecord ndefRecord = null;
		if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
			ndefRecord = NdefRecord.createTextRecord(null, data);
		}
		NdefRecord[] records = {ndefRecord};
		NdefMessage ndefMessage = new NdefMessage(records);
		ndef.writeNdefMessage(ndefMessage);
	}catch (Exception e){

	}
}
// 往卡中写数据
String data = "this.is.write";
writeNFCToTag(data, intent);

 2.8 Cancel NfcAdapter scheduling

@Override
protected void onPause() {
	super.onPause();
	if (mNfcAdapter != null) {
		mNfcAdapter.disableForegroundDispatch(this);
	}
}

2.9 Destroy NfcAdapter

@Override
protected void onDestroy() {
	super.onDestroy();
	mNfcAdapter = null;
}

2.10 Summary

NFC is suitable for card swiping data transmission scenarios, such as access control cards, payment cards, subway cards, etc., fast and convenient

Guess you like

Origin blog.csdn.net/qq_29848853/article/details/130278294