Android 蓝牙开发 —— BLE

2024-06-06 11:48
文章标签 android 开发 蓝牙 ble

本文主要是介绍Android 蓝牙开发 —— BLE,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

蓝牙——BLE

介绍

1.BLE 是 Bluetooth Low Energy 的缩写,意思为低功耗蓝牙。由蓝牙技术联盟(Bluetooth SIG)设计的无线通讯技术,主要用于医疗,健身,安全和家庭娱乐行业。 与传统蓝牙相比,蓝牙低功耗旨在大幅降低功耗和成本,同时也能够达到相同的通讯效果。
支持多个平台,包括 IOS,Android,Windows Phone 和 BlackBerry 以及 macOS,Linux,Windows 8 和 Windows 10 在内的移动操作系统本身支持蓝牙低功耗。 蓝牙 SIG 预测,到 2018 年,超过 90% 的蓝牙智能手机将支持蓝牙低功耗。

在安卓平台,
在 Android 4.3 (API level 18) 以后引进来的,通过这些 API 可以扫描蓝牙设备、连接设备,查询 services、读写设备的 characteristics(属性特征),然后通过属性进行数据传输。

特点:

低功耗,使用 BLE 与周围设备进行通讯时,其峰值功耗为传统蓝牙的一半
传输距离提升到 100 米
低延时,最短可在3 ms内完成连接并开始进行数据传输

缺点:

传输数据量较小,最大 512 个字节,超过 20 个字节需要分包处理

应用领域:

主要用于智能硬件,像健康护理、运动和健身、设备电源管理等

连接模式

对于BLE单设备来讲常见的蓝牙模块的工作模有四种:

  • 主设备模式
  • 从设备模式
  • 广播模式
  • Mesh组网模式

主设备模式

可以与一个从设备进行连接。在此模式下可以对周围设备进行搜索并选择需要连接的从设备进行连接。同时可以设置默认连接从设备的MAC地址,这样模块上电之后就可以查找此模块并进行连接。

从设备模式

BLE支持从设备模式,在此模式下完全符合BLE4.1协议,用户可以根据协议自己开发APP。此模式下包含一个串口收发的Service,用户可以通过UUID找到它,里面有两个通道,分别是读和写。用户可以操作这两个通道进行数据的传输。

广播模式

在这种模式下模块可以一对多进行广播。用户可以通过AT指令设置模块广播的数据,模块可以在低功耗的模式下持续的进行广播,应用于极低功耗,小数据量,单向传输的应用场合,比如无线抄表,室内定位等功能。

Mesh组网模式

在这种模式下模块可以实现简单的自组网络,每个模块只需要设置相同的通讯密码就可以加入到同一网络当中,每一个模块都可以发起数据,每个模块可以收到数据并且进行回复。并且不需要网关,即使某一个设备出现故障也会跳过并选择最近的设备进行传输。

GATT协议

GATT generic Attributes的缩写,中文是通用属性,是低功耗蓝牙设备之间进行通信的协议。
GATT定义了一种多层的数据结构,已连接的低功耗蓝牙设备用它来进行通信,GATT层是传输真正数据所在的层。一个GATT服务器通过一个称为属性表的表格组织数据,这些数据就是用于真正发送的数据。

GATT定义的多层数据结构简要概括起来就是服务(service)可以包含多个特征(characteristic),每个特征包含属性(properties)和值(value),还可以包含多个描述(descriptor)。它形象的结构如下图:

pic1

profile(数据配置文件)

一个profile文件可以包含一个或者多个服务,一个profile文件包含需要的服务的信息或者为对等设备如何交互的配置文件的选项信息。设备的GAP和GATT的角色都可能在数据的交换过程中改变,因此,这个文件应该包含广播的种类、所使用的连接间隔、所需的安全等级等信息。

需要注意的是: 一个profile中的属性表不能包含另一个属性表。

属性

一个属性包含句柄、UUID(类型)、值,句柄是属性在GATT表中的索引,在一个设备中每一个属性的句柄都是唯一的。UUID包含属性表中数据类型的信息,它是理解属性表中的值的每一个字节的意义的关键信息。在一个GATT表中可能有许多属性,这些属性能可能有相同的UUID。
个人理解,属性指的是 Service、Characteristic 这样的对象

Service

一个低功耗蓝牙设备可以定义许多 Service, Service 可以理解为一个功能的集合。设备中每一个不同的 Service 都有一个 128 bit 的 UUID 作为这个 Service 的独立标志。蓝牙核心规范制定了两种不同的UUID,一种是基本的UUID,一种是代替基本UUID的16位UUID。所有的蓝牙技术联盟定义UUID共用了一个基本的UUID:
0x0000xxxx-0000-1000-8000-00805F9B34FB
为了进一步简化基本UUID,每一个蓝牙技术联盟定义的属性有一个唯一的16位UUID,以代替上面的基本UUID的‘x’部分。例如,心率测量特性使用0X2A37作为它的16位UUID,因此它完整的128位UUID为:
0x00002A37-0000-1000-8000-00805F9B34FB

Characteristic

在 Service 下面,又包括了许多的独立数据项,我们把这些独立的数据项称作 Characteristic。同样的,每一个 Characteristic 也有一个唯一的 UUID 作为标识符。在 Android 开发中,建立蓝牙连接后,我们说的通过蓝牙发送数据给外围设备就是往这些 Characteristic 中的 Value 字段写入数据;外围设备发送数据给手机就是监听这些 Charateristic 中的 Value 字段有没有变化,如果发生了变化,手机的 BLE API 就会收到一个监听的回调。

DesCriptor

任何在特性中的属性不是定义为属性值就是为描述符。描述符是一个额外的属性以提供更多特性的信息,它提供一个人类可识别的特性描述的实例。然而,有一个特别的描述符值得特别地提起:客户端特性配置描述符(Client Characteristic Configuration Descriptor,CCCD),这个描述符是给任何支持通知或指示功能的特性额外增加的。在CCCD中写入“1”使能通知功能,写入“2”使能指示功能,写入“0”同时禁止通知和指示功能。

使用过程

常采用的模式是主机模式,然后扫描客户端硬件,然后连接,获取相关服务和特性,然后进行数据传输。
steps

1. 扫描
权限获取

<uses-permission android:name="android.permission.BLUETOOTH"/> 使用蓝牙所需要的权限
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> 使用扫描和设置蓝牙的权限(申明这一个权限必须申明上面一个权限)

在Android5.0之前,是默认申请GPS硬件功能的。而在Android 5.0 之后,需要在manifest 中申明GPS硬件模块功能的使用。

    <!-- Needed only if your app targets Android 5.0 (API level 21) or higher. --><uses-feature android:name="android.hardware.location.gps" />

在 Android 6.0 及以上,还需要打开位置权限。如果应用没有位置权限,蓝牙扫描功能不能使用(其它蓝牙操作例如连接蓝牙设备和写入数据不受影响)。

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

除了上面的设置之外,如果想设置设备只支持 BLE,可以加上下面这句话

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

同样,如果不想添加 BLE 的支持,那么可以设置 required="false"

然后可以在运行时判断设备是否支持 BLE,

    // Use this check to determine whether BLE is supported on the device. Then// you can selectively disable BLE-related features.if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();finish();}
初始化

判断 BLE 在设备上是否支持,如果不支持的话,那么可以不用继续后面的操作了;如果支持,但是有可能蓝牙被禁掉了,因为开着蓝牙比较好点,用户一般都会关闭蓝牙,这时候可以发送请求,来打开蓝牙,可以通过两个步骤来完成。

  1. 获取 BluetoothAdapter

BluetoothAdapter 对于一个设备来说唯一的,整个系统或者应用,对蓝牙进行操作时都是需要这个的适配器。它的获取需要通过系统服务来获取。

    private BluetoothAdapter mBluetoothAdapter;...// Initializes Bluetooth adapter.final BluetoothManager bluetoothManager =(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);mBluetoothAdapter = bluetoothManager.getAdapter();

2.打开蓝牙

一般对于用户来说,在手机上蓝牙是关闭,当开启你的应用时就需要开启蓝牙,有两种方式,一种是跳转到设置界面,由用户自己开启蓝牙;
另外一种时,直接在应用开启蓝牙,不需要用户打开,而是直接帮用户开启手机上的蓝牙。

跳转到设置界面

// Ensures Bluetooth is available on the device and it is enabled. If not,
// displays a dialog requesting user permission to enable Bluetooth.
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}

直接开启蓝牙

    // 打开蓝牙if (!mBluetoothAdapter.isEnabled()) {mBluetoothAdapter.enable();}
扫描

扫描蓝牙设备可以通过startLeScan(),其中有一个参数是 ScanCallback,通过它返回扫描结果,因为扫描过程是很耗电的,所以在扫描过程需要保证

1.一旦找到目标设备,需要停止扫描
2.扫描不要设置循环,而且需要设置一个时间

回调如下


// 设备扫描回调private ScanCallback mScanCallback = new ScanCallback() {@Overridepublic void onScanResult(int callbackType, final ScanResult result) {runOnUiThread(new Runnable() {@Overridepublic void run() {// 广播的信息,可以在result中获取MDevice mDev = new MDevice(result.getDevice(), result.getRssi());if (!mList.contains(mDev)) {mList.add(mDev);}if (mList.size() > 0) {mScanner.stopScan(mScanCallback);Toast.makeText(MainActivity.this, "扫描结束,设备数 " + mList.size(), Toast.LENGTH_SHORT).show();}}});}};

开始扫描

private BluetoothAdapter mBluetoothAdapter;private boolean mScanning;private Handler mHandler;// Stops scanning after 10 seconds.private static final long SCAN_PERIOD = 10000;...private void scanLeDevice(final boolean enable) {if (enable) {// Stops scanning after a pre-defined scan period.mHandler.postDelayed(new Runnable() {@Overridepublic void run() {mScanning = false;mBluetoothAdapter.stopLeScan(mLeScanCallback);}}, SCAN_PERIOD);mScanning = true;mBluetoothAdapter.startLeScan(mLeScanCallback);} else {mScanning = false;mBluetoothAdapter.stopLeScan(mLeScanCallback);}...}

这里遇到一个坑,就是实际中手机与一些智能硬件连接时,也就是需要连接指定的硬件,设备有一个UUID,所以可以通过如下方法连接

    startLeScan(UUID[], BluetoothAdapter.LeScanCallback)

但是实际中使用时,连接时会出错,仍需要再次验证。
我当时的做法是采用了另外一种方法,当时这种方法,要求 API 高于 21。

    private void scanLeDevice() {//50秒后停止扫描mHander.postDelayed(stopScanRunnable, 50000);List<ScanFilter> filters = new ArrayList<>();ScanFilter filter = new ScanFilter.Builder()//"D8:B0:4C:E8:66:DC" 测试MAC 1//"D8:B0:4C:E2:45:2A"  测试MAC 2.setDeviceAddress("D8:B0:4C:E2:45:2A").build();filters.add(filter);// 扫描mScanner.startScan(filters, new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build(), mScanCallback);}

扫描结束后需要停止扫描

boolean startLeScan(BluetoothAdapter.LeScanCallback callback)

连接

设备连接

通过扫描能够获得设备 BluetoothDevice,包含地址和名字
通过设备连接并获取 BluetoothGatt,后面通过 BluetoothGatt 的实例来进行client的操作,如使用该实例去发现服务,获取读、写、通知等属性

public static BluetoothGatt mBluetoothGatt;mBluetoothGatt = device.connectGatt(context, false, mGattCallback);

通过连接回调来监听连接的状态,包含三种状态,连接、断开、正在连接,根据状态可以发送广播,
在接收广播的位置进行做相应的处理

    private final static BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {@Overridepublic void onConnectionStateChange(BluetoothGatt gatt, int status,int newState) {String intentAction;// GATT Server connectedif (newState == BluetoothProfile.STATE_CONNECTED) {System.out.println("---------------------------->已经连接");intentAction = ACTION_GATT_CONNECTED;mConnectionState = STATE_CONNECTED;broadcastConnectionUpdate(intentAction);}// GATT Server disconnectedelse if (newState == BluetoothProfile.STATE_DISCONNECTED) {System.out.println("---------------------------->连接断开");intentAction = ACTION_GATT_DISCONNECTED;mConnectionState = STATE_DISCONNECTED;broadcastConnectionUpdate(intentAction);}// GATT Server disconnectedelse if (newState == BluetoothProfile.STATE_DISCONNECTING) {System.out.println("---------------------------->正在连接");
//                intentAction = ACTION_GATT_DISCONNECTING;
//                mConnectionState = STATE_DISCONNECTING;
//                broadcastConnectionUpdate(intentAction);}}}

当操作完成后,需要关闭连接,必须调用 BluetoothGatt#close 方法释放连接资源

发现服务

由于有了 mBluetoothGatt,就可以去发现服务,再通过服务去获取可以操作的属性


mBluetoothGatt.discoverServices();

发现服务以及获取其他属性,如write和read,notify,Descriptor相关的属性,均是在 BluetoothGattCallback 中有回调,在回调中就可以通过发送广播,然后在其他位置做处理,
如接收数据就会有回调,然后将数据传递出去,对数据解析等

@Overridepublic void onServicesDiscovered(BluetoothGatt gatt, int status) {// GATT Services discovered//发现新的服务if (status == BluetoothGatt.GATT_SUCCESS) {System.out.println("---------------------------->发现服务");broadcastConnectionUpdate(ACTION_GATT_SERVICES_DISCOVERED);} }//通过 Descriptor 写监听@Override public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,int status) {}// 通过 Descriptor 读监听@Overridepublic void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,int status) {}@Overridepublic void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristiccharacteristic, int status) {//write操作会调用此方法if (status == BluetoothGatt.GATT_SUCCESS) {System.out.println("onCharacteristicWrite ------------------->write success");Intent intent = new Intent(ACTION_GATT_CHARACTERISTIC_WRITE_SUCCESS);mContext.sendBroadcast(intent);} else {Intent intent = new Intent(ACTION_GATT_CHARACTERISTIC_ERROR);intent.putExtra(Constants.EXTRA_CHARACTERISTIC_ERROR_MESSAGE, "" + status);mContext.sendBroadcast(intent);}}@Overridepublic void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) {// 接收数据}@Overridepublic void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {//notify 会回调用此方法broadcastNotifyUpdate(characteristic);}@Overridepublic void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {super.onMtuChanged(gatt, mtu, status);}
数据传输
  1. 数据读取

这里有两个方法:

方法一: 一般数据读取的话,想到的是用 read 属性,所以需要获取特定通道的 BluetoothGattCharactristic。

1)BluetoothGatt#getService 得到服务

2)BluetoothGattService#getCharactristic 获取 BluetoothGattCharactristic,这里获取的 BluetoothGattCharactristic 是有指定 UUID 的,也就是说不同的 Charactristic的 UUID 是不同的,读和写的通道不同,根据不同的操作,然后通过UUID获取相应的通道

3)BluetoothGattCharactristic#readCharacteristic 方法可以通知系统去读取特定的数据

4)BluetoothGattCallback#onCharacteristicRead 方法。通过 BluetoothGattCharacteristic#getValue 可以读取到蓝牙设备的数据

方法二:采用 notify 属性,客户端发送数据,服务端监听属性变化,然后根据 属性的 UUID 判断是否是 notify 的属性,如果是的话,说确实是由远程设备发过来的数据。

1)BluetoothGatt#getService 得到服务

2)BluetoothGattService#getCharactristic 获取 BluetoothGattCharactristic,这里的这个属性是 notify 属性

3)获得属性后需要进行判断设备是否支持notify操作,然后再设备打开notify通知

void prepareBroadcastDataNotify(BluetoothGattCharacteristic characteristic) {final int charaProp = characteristic.getProperties();Toast.makeText(this, " " + charaProp, Toast.LENGTH_SHORT).show();if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {BluetoothLeService.setCharacteristicNotification(characteristic, true);}}

4) 设置属性时,也要通知远程设备端也要开启 notify 属性

public static void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled) {if (mBluetoothAdapter == null || mBluetoothGatt == null) {return;}//通知远程端开启 notify if (characteristic.getDescriptor(UUID.fromString(GattAttributes.CLIENT_CHARACTERISTIC_CONFIG)) != null) {if (enabled == true) {BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(GattAttributes.CLIENT_CHARACTERISTIC_CONFIG));descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);mBluetoothGatt.writeDescriptor(descriptor);} else {BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(GattAttributes.CLIENT_CHARACTERISTIC_CONFIG));descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);mBluetoothGatt.writeDescriptor(descriptor);}}mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);}
  1. 数据写入

对于 BLE 方式的数据传输来说,数据的大小是有限制的,一次性最多可以传输512个字节,这也是BLE小数据量传输的特点,另外,对于每次传输,也有限制,每个数据包大小不超过20个字节,超过20个字节的话,需要分包处理。写的步骤和读取类似。

1)BluetoothGatt#getService 得到服务

2)BluetoothGattService#getCharactristic 获取 BluetoothGattCharactristic,这里的这个属性是 write 属性

3)写入字节数据


public static void writeCharacteristicGattDb(BluetoothGattCharacteristic characteristic, byte[] byteArray) {if (mBluetoothAdapter == null || mBluetoothGatt == null) {return;} else {byte[] valueByte = byteArray;characteristic.setValue(valueByte);mBluetoothGatt.writeCharacteristic(characteristic);}}

4)对于手机端,写入数据后,远程端会接受,同时回调中也会能够接收,也可以在回调中做一下数据判断,看是否是自己发出的数据

@Overridepublic void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristiccharacteristic, int status) {//write操作会调用此方法if (status == BluetoothGatt.GATT_SUCCESS) {System.out.println("onCharacteristicWrite ------------------->write success");Intent intent = new Intent(ACTION_GATT_CHARACTERISTIC_WRITE_SUCCESS);// 这里通过属性能够读取你发送的数据,可以对此数据进行判断characteristic.getValue();mContext.sendBroadcast(intent);} else {Intent intent = new Intent(ACTION_GATT_CHARACTERISTIC_ERROR);intent.putExtra(Constants.EXTRA_CHARACTERISTIC_ERROR_MESSAGE, "" + status);mContext.sendBroadcast(intent);}}

其他

  1. 一般在通讯过程中,需要有连接的心跳包,来检测是否仍处于连接状态,可以通过设置定时器,主机端定时 write 数据,客户端定时 notify 数据
  2. 2.

断开连接

操作完成,需要断开蓝牙并释放资源,通过 BluetoothGatt#disconnect 断开连接,然后回调中会收到断开的监听,可以根据状态释放资源。BluetoothGattCallback#onConnectionStateChange回调中通过这个方法的 newState 参数可以判断是连接成功还是断开成功的回调,断开成功的话,然后调用 BluetoothGatt#close 方法释放资源

参考

官方文档

Android 开发入门介绍

通用属性配置文件(GATT)及其服务,特性与属性介绍

这篇关于Android 蓝牙开发 —— BLE的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1036026

相关文章

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

【区块链 + 人才服务】区块链集成开发平台 | FISCO BCOS应用案例

随着区块链技术的快速发展,越来越多的企业开始将其应用于实际业务中。然而,区块链技术的专业性使得其集成开发成为一项挑战。针对此,广东中创智慧科技有限公司基于国产开源联盟链 FISCO BCOS 推出了区块链集成开发平台。该平台基于区块链技术,提供一套全面的区块链开发工具和开发环境,支持开发者快速开发和部署区块链应用。此外,该平台还可以提供一套全面的区块链开发教程和文档,帮助开发者快速上手区块链开发。

Vue3项目开发——新闻发布管理系统(六)

文章目录 八、首页设计开发1、页面设计2、登录访问拦截实现3、用户基本信息显示①封装用户基本信息获取接口②用户基本信息存储③用户基本信息调用④用户基本信息动态渲染 4、退出功能实现①注册点击事件②添加退出功能③数据清理 5、代码下载 八、首页设计开发 登录成功后,系统就进入了首页。接下来,也就进行首页的开发了。 1、页面设计 系统页面主要分为三部分,左侧为系统的菜单栏,右侧