一、项目描述
项目简介: NFC音乐播放卡是一个基于Near Field Communication(NFC)技术的项目,旨在通过使用NFC标签,使用户能够轻松地通过NFC功能启动手机上的网易云音乐并播放中的音乐。
项目特点:
-
NFC标签触发播放: 项目利用NFC标签,用户只需将手机靠近NFC标签,即可拉起网易云 音乐app,并播放音乐。
-
自定义NFC标签: 用户可以自定义NFC标签上的信息,包括要播放的音乐。
-
跨平台兼容性: 该项目支持多个平台,包括Android和iOS。用户可以在支持NFC功能的智能手机上使用该功能。
NFC音乐播放器项目旨在为用户提供一种简便的方式,通过NFC标签触发并播放他们最喜爱的音乐,提升他们的音乐欣赏体验。
硬件介绍:
nRF7002 DK是用于nRFF7002 Wi-Fi 6 协同IC的开发套件,在单一电路板上包含了启动开发工作所需要的一切。这款DK带有一个nRF5340多协议系统级芯片(SoC),用作nRF7002的主处理器。
nRF5340主芯片采用了双核架构,包括一个Cortex-M33核心和一个Cortex-M33核心。这两个核心可以分别运行不同的应用程序,或者协同工作以提高性能。这款SoC支持多种通信协议,包括蓝牙(Bluetooth),Thread和Zigbee等,使其非常适合物联网(IoT)和无线通信应用。
该芯片集成了丰富的外设,包括GPIO引脚、SPI、I2C、UART等,以支持各种外部设备的连接和控制。nRF5340芯片具有内置的NFC(Near Field Communication)功能,该功能使其能够支持短距离无线通信和数据交换。芯片可以模拟NFC卡,使其可以被其他NFC设备读取,用于实现诸如门禁卡、交通卡和身份认证卡等应用。
二、工作流程图
NFC拉起手机app的原理解析
通过搜索引擎,可以搜索到网易云音乐的NFC拉起的规则有以下的内容:
然后我们需要唤起网易云音乐app,并播放アイドル这首歌的话,就需要把NFC标签里的URI信息修改成orpheus://song/2034742057。
那为什么手机扫描NFC标签,获取到这一段URI信息就能唤起app播放音乐呢,就要说一下URL Scheme了。先来看一下chatGPT里关于URL Scheme的介绍
URL Scheme(统一资源定位符协议)是一种在操作系统中用于识别并启动相关应用程序的链接协议。
它是一种自定义协议,通常与特定应用程序或服务相关联,允许您通过特定的URL来打开相关的应用程序。
这对于实现深层链接(Deep Linking)和跨应用程序交互非常有用。
而这一段orpheus://song/2034742057,就是告诉操作系统,我需要调用orpheus这个应用(一般由APP向操作系统注册对应信息),并打开song这个页面,播放2034742057这首歌。
现在知道了吧,URL Scheme 是一种特殊的 URL,它不是用于访问 Web 页面的,而是用于唤起移动应用程序并传递参数。
三 、主要代码
本工程使用了nrf/samples/nfc/record_launch_app项目作为模版项目,将原有的app拉起功能修改成url标签功能,然后就实现了一键拉起网易云音乐和播放固定歌曲的功能。
修改的内容如下:
1、调整头文件内容,引入uri_msg等头文件(nfc/ndef/launchapp_msg.h, nfc/ndef/uri_msg.h)
2、修改uri链接(修改成上文提到的orpheus://song/2034742057),删除apk_name(不需要这个内容)
3、将拉起app的函数修改成url标签的函数。将nfc_launchapp_msg_encode修改成
nfc_ndef_uri_msg_encode,并调整对应参数。
以下是详细修改内容的diff文件。
@@ -8,23 +8,15 @@
#include <zephyr/sys/reboot.h>
#include <nfc_t2t_lib.h>
-#include <nfc/ndef/launchapp_msg.h>
+#include <nfc/ndef/uri_msg.h>
#include <dk_buttons_and_leds.h>
#define NDEF_MSG_BUF_SIZE 256
#define NFC_FIELD_LED DK_LED1
-/** .. include_startingpoint_pkg_def_launchapp_rst */
-/* Package: no.nordicsemi.android.nrftoolbox */
-static const uint8_t android_pkg_name[] = {
- 'n', 'o', '.', 'n', 'o', 'r', 'd', 'i', 'c', 's', 'e', 'm', 'i', '.', 'a', 'n', 'd', 'r',
- 'o', 'i', 'd', '.', 'n', 'r', 'f', 't', 'o', 'o', 'l', 'b', 'o', 'x' };
-
/* URI nrf-toolbox://main/ */
-static const uint8_t universal_link[] = {
- 'n', 'r', 'f', '-', 't', 'o', 'o', 'l', 'b', 'o', 'x', ':', '/', '/', 'm', 'a', 'i', 'n',
- '/'};
+static const uint8_t universal_link[] = "orpheus://song/2034742057";
/** .. include_endpoint_pkg_def_launchapp_rst */
/* Buffer used to hold an NFC NDEF message. */
@@ -74,10 +66,9 @@ int main(void)
}
/* Encode launch app data */
- err = nfc_launchapp_msg_encode(android_pkg_name,
- sizeof(android_pkg_name),
+ err = nfc_ndef_uri_msg_encode(NFC_URI_NONE,
universal_link,
- sizeof(universal_link),
+ sizeof(universal_link) - 1,
ndef_msg_buf,
&len);
if (err) {
4、使用menuconfig,并使能CONFIG_NFC_NDEF_URI_MSG,如下图
四、完整代码
/*
* Copyright (c) 2021 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/
#include <zephyr/kernel.h>
#include <zephyr/sys/reboot.h>
#include <nfc_t2t_lib.h>
#include <nfc/ndef/uri_msg.h>
#include <dk_buttons_and_leds.h>
#define NDEF_MSG_BUF_SIZE 256
#define NFC_FIELD_LED DK_LED1
/* URI nrf-toolbox://main/ */
static const uint8_t universal_link[] = "orpheus://song/2034742057";
/** .. include_endpoint_pkg_def_launchapp_rst */
/* Buffer used to hold an NFC NDEF message. */
static uint8_t ndef_msg_buf[NDEF_MSG_BUF_SIZE];
static void nfc_callback(void *context,
nfc_t2t_event_t event,
const uint8_t *data,
size_t data_length)
{
ARG_UNUSED(context);
ARG_UNUSED(data);
ARG_UNUSED(data_length);
switch (event) {
case NFC_T2T_EVENT_FIELD_ON:
dk_set_led_on(NFC_FIELD_LED);
break;
case NFC_T2T_EVENT_FIELD_OFF:
dk_set_led_off(NFC_FIELD_LED);
break;
default:
break;
}
}
int main(void)
{
int err;
size_t len = sizeof(ndef_msg_buf);
printk("Starting NFC Launch app example\n");
/* Configure LED-pins as outputs */
err = dk_leds_init();
if (err) {
printk("Cannot init LEDs!\n");
goto fail;
}
/* Set up NFC */
err = nfc_t2t_setup(nfc_callback, NULL);
if (err) {
printk("Cannot setup NFC T2T library!\n");
goto fail;
}
/* Encode launch app data */
err = nfc_ndef_uri_msg_encode(NFC_URI_NONE,
universal_link,
sizeof(universal_link) - 1,
ndef_msg_buf,
&len);
if (err) {
printk("Cannot encode message!\n");
goto fail;
}
/* Set created message as the NFC payload */
err = nfc_t2t_payload_set(ndef_msg_buf, len);
if (err) {
printk("Cannot set payload!\n");
goto fail;
}
/* Start sensing NFC field */
err = nfc_t2t_emulation_start();
if (err) {
printk("Cannot start emulation!\n");
goto fail;
}
printk("NFC configuration done\n");
return 0;
fail:
#if CONFIG_REBOOT
sys_reboot(SYS_REBOOT_COLD);
#endif /* CONFIG_REBOOT */
return err;
}
五、心得体会
通过本次的活动 ,我学会了Zephyr的项目结构和常见用法,也学会了 NFC近场通讯的一些知识和调用方式 。通过NFC开发,我不仅学到了技术方面的知识,还深刻体会到了无线通信在改善用户生活和推动物联网发展中的潜力。我期待着在未来继续探索这个令人兴奋的领域。