Android 蓝牙开发(一)

news2025/1/22 1:32:54

蓝牙简介

蓝牙(Bluetooth)是一种无线技术标准,能够在短距离内实现设备之间的数据交换和通信。蓝牙技术最初由瑞典爱立信公司于1994年开发,其名称源自丹麦国王哈拉尔·布吕特的译名“Harald Bluetooth”,他曾统一了斯堪的纳维亚半岛。

蓝牙技术是基于无线射频技术的,工作频率为2.4GHz,可支持多达8个设备同时连接。蓝牙技术应用广泛,包括手机、电脑、音频设备、手环、智能家居等领域,可以实现数据传输、音频传输、遥控和定位等功能。蓝牙技术的优点包括低功耗、低成本、易于使用和可靠性高等,成为了现代通信领域不可或缺的一部分。

前言

蓝牙是一种短距离无线通信技术,我们相对熟悉的移动端设备短距离通信技术有NFC红外蓝牙 ;

NFC:主要应用于操作简单,即时相应的刷卡

红外:主要应用于需要按键控制,例如家电遥控

蓝牙:主要用于两部设备之间复杂且大量的数据传输(这里又分为低功耗蓝牙经典蓝牙)今天小编给大家分享的是经典蓝牙

Android蓝牙开发步骤

1.检查设备是否支持蓝牙

在应用程序中,你需要首先检查设备是否支持蓝牙。你可以在AndroidManifest.xml文件中声明必需的蓝牙权限,并使用BluetoothAdapter类来查询设备是否支持蓝牙

BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
    // 该设备不支持蓝牙
} else {
    // 该设备支持蓝牙
}

2.打开蓝牙

在你的应用程序中,你需要引导用户打开他们的蓝牙功能。你可以使用ACTION_REQUEST_ENABLE活动提供一个请求

if (!bluetoothAdapter.isEnabled()) {
    //如果该设备蓝牙未开启

    Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}

3.扫描可用蓝牙设备

一旦蓝牙已启用,你就可以开始扫描设备了。你可以使用BluetoothAdapter类和BluetoothDevice类执行扫描操作

bluetoothAdapter.startDiscovery();

可以使用BroadcastReceiver类来接收扫描结果:

private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            //该设备成功搜索到蓝牙设备
        }
    }
};

4.选择蓝牙并与其配对成功

通过BluetoothAdapter对象,你可以来进行蓝牙配对。你需要将BluetoothDevice类实例化并使用其connect()方法来建立连接

BluetoothAdapter mBluetoothAdapter;
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
device.createBond();

 5.选择蓝牙并与其建立连接

通过BluetoothDevice对象,你可以使用BluetoothSocket类来建立蓝牙连接。你需要将BluetoothSocket类实例化并使用其connect()方法来建立连接

BluetoothSocket socket = device.createRfcommSocketToServiceRecord(MY_UUID);
socket.connect();

6.数据传输

一旦蓝牙连接已建立,你可以使用BluetoothSocket的getInputStream()和getOutputStream()方法来发送和接收数据

InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();

以上就是Android蓝牙开发的基本流程,需要注意的是在实际开发中,还需要处理蓝牙连接的断开、多设备连接等复杂情况

7.断开蓝牙连接并关闭蓝牙

BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.disable(); //关闭蓝牙

注意:Android提供了蓝牙模块的管理工具BluetoothAdapter(蓝牙适配器)

BluetoothAdapter类的一些常用方法说明:

1. enable() - 开启蓝牙

2. disable() - 关闭蓝牙

3. startDiscovery() - 开始搜索设备

4. cancelDiscovery() - 取消搜索设备

5. getBondedDevices() - 获取已配对的设备列表

6. getRemoteDevice(String address) - 获取远程设备对象

7. setState(int state) - 设置蓝牙状态

8. setScanMode(int mode) - 设置扫描模式

9. getScanMode() - 获取扫描模式

10. getName() - 获取本地蓝牙设备名称

11. setName(String name) - 设置本地蓝牙设备名称

12. getAddress() - 获取本地蓝牙设备地址

13. isDiscovering:判断是否正在搜索周围的蓝牙设备

14. getBluetoothLeScanner() - 获取BluetoothLeScanner对象

15. getProfileProxy(Context context, BluetoothProfile.ServiceListener listener, int profile) - 获取BluetoothProfile对象

16. closeProfileProxy(int profile, BluetoothProfile proxy) - 关闭BluetoothProfile对象的连接

Android蓝牙开发效果演示

1. 声明蓝牙权限

新建一个Android项目,然后在AndroidManifest清单文件里声明相关的权限

2. 动态获取定位权限

package com.example.bluetoothdemo;

import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.pm.PackageManager;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

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

        //判断是否有访问位置的权限,没有权限,直接申请位置权限
        isPermission();
    }

    //动态获取位置权限
    @SuppressLint("NewApi")
    private void isPermission(){
        if ((checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
                || (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) {
            requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 200);
        }
    }
}

运行效果:

3. 判断该设备是否支持蓝牙功能

package com.example.bluetoothdemo;

import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private BluetoothAdapter mBluetoothAdapter;

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

        //初始化蓝牙适配器
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();


        if (isBluetoothSupport()){
            Toast.makeText(MainActivity.this, "该设备支持蓝牙功能", Toast.LENGTH_SHORT).show();
        }else {
            Toast.makeText(MainActivity.this, "该设备不支持蓝牙功能", Toast.LENGTH_SHORT).show();
        }
    }


    //判断该设备是否支持蓝牙功能
    private Boolean isBluetoothSupport(){
        if(mBluetoothAdapter == null){
            return false;
        }else {
            return true;
        }
    }
}

运行效果:

4. 判断本机是否开启蓝牙

package com.example.bluetoothdemo;

import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private BluetoothAdapter mBluetoothAdapter;

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

        //初始化蓝牙适配器
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();


            //判断蓝牙是否打开
            if(!isBluetoothEnabled()){
                //如果蓝牙未开启,则申请打开蓝牙
                Intent enableBluetoothIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(enableBluetoothIntent, RESULT_CANCELED);
            }else {

            }

    }




    /**
     * 检查该设备蓝牙是否开启
     */
    private boolean isBluetoothEnabled(){
        if(mBluetoothAdapter.isEnabled()){
            return true;
        }else {
            return false;
        }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == RESULT_CANCELED) {
            if (resultCode == RESULT_OK) {
                // 蓝牙已成功开启
                Toast.makeText(MainActivity.this, "用户已开启蓝牙", Toast.LENGTH_SHORT).show();
            } else {
                // 用户取消了蓝牙开启请求
                Toast.makeText(MainActivity.this, "用户已拒绝开启蓝牙", Toast.LENGTH_SHORT).show();
            }
        }
    }

}

运行效果:

5. 获取设备已配对过的蓝牙设备

package com.example.bluetoothdemo;

import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import java.util.Set;

public class MainActivity extends AppCompatActivity {
    private BluetoothAdapter mBluetoothAdapter;


    @SuppressLint({"MissingPermission", "MissingInflatedId"})
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //初始化蓝牙适配器
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        //判断是否有访问位置的权限,没有权限,直接申请位置权限
        isPermission();


        getPairedDevices();
    }

    //动态获取位置权限
    @SuppressLint("NewApi")
    private void isPermission(){
        if ((checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
                || (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) {
            requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 200);
        }
    }

    
    @SuppressLint("MissingPermission")
    private void getPairedDevices() {
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
        if (pairedDevices.size() > 0) {
            for (BluetoothDevice device : pairedDevices) {
                String deviceName = device.getName();
                String deviceHardwareAddress = device.getAddress();
                Log.d("MainActivity","设备名:"+deviceName+'\n'+"地址:"+deviceHardwareAddress);
            }
        }
    }


}

运行效果:

6. 搜索蓝牙设备

package com.example.bluetoothdemo;

import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import java.util.Set;

public class MainActivity extends AppCompatActivity {
    private BluetoothAdapter mBluetoothAdapter;


    @SuppressLint({"MissingPermission", "MissingInflatedId"})
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //初始化蓝牙适配器
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        //判断是否有访问位置的权限,没有权限,直接申请位置权限
        isPermission();


        mBluetoothAdapter.startDiscovery();
        registerBluetoothReceiver();
    }

    //动态获取位置权限
    @SuppressLint("NewApi")
    private void isPermission(){
        if ((checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
                || (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) {
            requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 200);
        }
    }

  

    private void registerBluetoothReceiver(){
        //filter注册广播接收器
        IntentFilter filter = new IntentFilter();


        //蓝牙当前状态
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);


        //开始扫描蓝牙设备广播
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);

        //找到蓝牙设备广播
        filter.addAction(BluetoothDevice.ACTION_FOUND);

        //扫描蓝牙设备结束广播
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);

        //蓝牙设备配对状态改变广播
        filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);

        //设备扫描模式改变广播
        filter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);

        registerReceiver(receiver, filter);
    }


    //处理找到蓝牙设备和搜索完成的广播消息
    BroadcastReceiver receiver = new BroadcastReceiver() {

        @SuppressLint("MissingPermission")
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            //开始查找设备
            if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
                Log.d("","开始查找");
            }
            //找到蓝牙设备
            else if(BluetoothDevice.ACTION_FOUND.equals(action)){
                //搜到蓝牙设备
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                //把搜索到的设备添加到已找到列表中,显示它的信息
                Log.d("","设备名:"+device.getName()+'\n'+"地址:"+device.getAddress());

            }
            //查找设备结束
            else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
                //搜索完毕
                Toast.makeText(MainActivity.this, "选择要配对的蓝牙设备", Toast.LENGTH_SHORT).show();
                Log.d("","查找结束");
            }

        }
    };


}

运行效果:

7. 配对蓝牙设备

package com.example.bluetoothdemo;

import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import java.util.Set;

public class MainActivity extends AppCompatActivity {
    private BluetoothAdapter mBluetoothAdapter;


    @SuppressLint({"MissingPermission", "MissingInflatedId"})
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //初始化蓝牙适配器
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        //判断是否有访问位置的权限,没有权限,直接申请位置权限
        isPermission();


        getPairedDevices();

    }

    //动态获取位置权限
    @SuppressLint("NewApi")
    private void isPermission(){
        if ((checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
                || (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) {
            requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 200);
        }
    }

   

    @SuppressLint("MissingPermission")
    private void getPairedDevices() {
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
        if (pairedDevices.size() > 0) {
            int i=0;
            for (BluetoothDevice device : pairedDevices) {
                i++;
                if(i==pairedDevices.size()){
                    device.createBond();
                    Log.d("","本机与另一个蓝牙设备"+device.getName()+"成功配对");
                }
                String deviceName = device.getName();
                String deviceHardwareAddress = device.getAddress();
                Log.d("","设备名:"+deviceName+'\n'+"地址:"+deviceHardwareAddress);
            }
        }
    }


}

运行效果:

这一篇文章就先分享到这里,大家可以把代码复制一下去运行;下一篇再给大家分享一下蓝牙项目实战用法

Android蓝牙开发注意事项:

  1. 确保设备支持蓝牙:在开发之前,请确保您的设备支持蓝牙。大多数现代智能手机和平板电脑都支持蓝牙。

  2. 获取必要的权限:在开发蓝牙应用之前,您需要获取适当的权限。例如,您需要请求“android.permission.BLUETOOTH”权限,以便您的应用程序可以使用蓝牙。

  3. 确定您需要的蓝牙配置类型:Android提供了两种不同的蓝牙配置类型:经典蓝牙和低功耗蓝牙。使用低功耗蓝牙可以延长设备电池寿命,但需要Android 4.3(API level 18)或更高版本。

  4. 确保您的应用程序与其他应用程序兼容:在您的应用程序中使用蓝牙之前,请确保它与其他应用程序兼容。如果您的应用程序和其他应用程序同时使用蓝牙,可能会导致冲突和不稳定的行为。

  5. 使用正确的蓝牙协议:在开发蓝牙应用程序时,您需要确保使用正确的蓝牙协议。不同的设备和应用程序可能使用不同的蓝牙协议,因此您需要确定您的应用程序需要使用哪些协议。

  6. 处理错误和异常:在使用蓝牙时,可能会出现错误和异常。要确保您的应用程序具有适当的错误处理和异常处理代码,以确保它可以在出现问题时正确地处理蓝牙连接。

  7. 调试您的应用程序:在开发蓝牙应用程序时,请确保使用适当的调试工具。Android Studio提供了一些内置的调试工具,用于诊断和修复蓝牙连接问题。

  8. 避免使用已知的蓝牙错误:在使用蓝牙时,可能会出现许多已知的错误。要避免这些错误,请编写适当的代码,以确保您的应用程序可以正确处理这些错误。

需要注意的是,蓝牙开发需要特别注意电量和性能问题,对于频繁的蓝牙搜索、连接和数据传输等操作,应尽量减少或优化,避免对设备电量和性能造成过大的影响。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/942874.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

R语言空气污染数据的地理空间可视化和分析:颗粒物2.5(PM2.5)和空气质量指数(AQI)...

原文链接&#xff1a;http://tecdat.cn/?p23800 由于空气污染对公众健康的不利影响&#xff0c;人们一直非常关注。世界各国的环境部门都通过各种方法&#xff08;例如地面观测网络&#xff09;来监测和评估空气污染问题&#xff08;点击文末“阅读原文”获取完整代码数据&…

Spring Security存在认证绕过漏洞 CVE-2021-22096

文章目录 0.前言1.参考文档2.基础介绍漏洞影响范围&#xff1a;官方说明&#xff1a;修复版本&#xff1a;漏洞利用步骤&#xff1a;修复方式&#xff1a; 3.解决方案 0.前言 背景&#xff1a;项目被扫到Spring Boot 的漏洞&#xff0c;严格的说应该是Spring Security 组件的漏…

前端面试基础面试题——1

总结了一些基础的面试题 如果大家有兴趣的话可以关注留意一下 今后会不断更新一些面试题 1.JavaScript 中的 AJAX 原理及应用。 2.什么是闭包?请简单描述一下闭包的特点与应用场景。 3.请简述 HTTPS 与 HTTP 的区别&#xff0c;如何保证 HTTPS 的安全性? 4.请简述…

配置DNS服务的正反向解析

正向解析 安装DNS服务 2.在服务器端 编辑区域配置文件&#xff0c;选择一个解析模版进行修改---------/etc/named.rfc1912.zones 修改第一第三行 编辑数据配置文件&#xff0c;使用cp -a命令完全拷贝一份正向解析模版&#xff08;named.localhost&#xff09;&#xff0c;在…

Ceph源码解析:PG peering

集群中的设备异常(异常OSD的添加删除操作)&#xff0c;会导致PG的各个副本间出现数据的不一致现象&#xff0c;这时就需要进行数据的恢复&#xff0c;让所有的副本都达到一致的状态。 一、OSD的故障和处理办法&#xff1a; 1. OSD的故障种类&#xff1a; 故障A&#xff1a;一…

Jumpserver堡垒机一键安装

堡垒机简介 运维常见背黑锅场景 1、由于不明身份用户利用远程运维通道攻击服务器造成业务系统出现异常&#xff1a;但是运维人员无法明确攻击来源&#xff0c;那么领导很生气、后果很严重。 2、只有张三能管理的服务器&#xff0c;被李四登录过并且做了违规操作&#xff1a;…

新能源电驱动总成相关标准简介

新能源电驱动总成相关标准简介 电驱动系统标准体系是电动汽车标准体系中重要的组成部分&#xff0c;其制定和更新对于保障电动汽车的使用性能和安全性能具有非常重要的作用。 随着电动汽车行业的快速发展和普及&#xff0c;电驱动系统的重要性也越来越凸显。为了确保电动汽车的…

政府科技项目验收全流程分享

科技验收测试 &#xff08;验收申请→主管部门初审→科技厅审核→组织验收→归档备案→信用管理&#xff09;&#xff1a; &#xff08;一&#xff09;验收申请 项目承担单位通过省科技业务管理系统提交验收申请。 按期完成的项目&#xff0c;项目承担单位应当在项目合同书…

揭开波动性的神秘面纱:简要介绍预测市场走势

一、说明 本文是数据专家的体会&#xff0c;他之前写了一系列关于时间序列的文章&#xff0c;在这些文章之后&#xff0c;他想给出一个关于我们如何通过投资组合分析在潜在风险情况下将自己保持在安全区域的想法。文章专业性很强&#xff0c;但机器学习方面的工作还是有参考价值…

液体神经网络LLN:通过动态信息流彻底改变人工智能

巴乌米克泰吉 一、说明 在在人工智能领域&#xff0c;神经网络已被证明是解决复杂问题的非常强大的工具。多年来&#xff0c;研究人员不断寻求创新方法来提高其性能并扩展其能力。其中一种方法是液体神经网络&#xff08;LNN&#xff09;的概念&#xff0c;这是一个利用动态计算…

实验表明:人工智能生成的论文可在全美大多数大学的文社科类课程中获得及格成绩

两门A&#xff0c;一门A-&#xff0c;一门B&#xff0c;一门B-&#xff0c;一门及格。 对于一名哈佛大学的大一新生来说&#xff0c;这已经是一份相当不错的成绩单&#xff0c;合计3.57的GPA成绩也很可观。 Maya Bodnick 在哈佛大学的政治专业就读大一&#xff0c;上面提到的…

MyBatisPlus简单入门

1、简单介绍MyBatisPlus MyBatisPlus是一个MyBatis的增强工具&#xff0c;在MyBatis的基础上只做增强不做改变&#xff0c;完全去SQL化&#xff0c;封装好了大量的CRUD操作。甚至吧CRUD操作封装到了Service层&#xff0c;可以直接在Controller调用现成的CRUD服务层&#xff0c…

如何借助各个大模型的优点生成原创视频(真人人声)

第1步&#xff0c;借助天工AI搜索&#xff08;天工AI搜索 — 知识从这里开始 (tiangong.cn)&#xff09;&#xff0c;直接手机短信验证就可以使用&#xff0c;该大模型已经接入互联网&#xff0c;注意下图提问方式。 而且&#xff0c;细心的筒子已经发现&#xff0c;该回答可能…

Viobot硬件组成和接口

Viobot主要由主板、传感器板和外壳组成。具体尺寸可以在用户手册上面找到。 传感器板上面是双目摄像头和IMU&#xff0c;摄像头已经打了胶固定在外壳的前脸&#xff0c;由于涉及到传感器外参标定&#xff0c;所以不可自行拆卸。 LED补光灯版本&#xff1a; TOF版本&#xff1a…

Ceph入门到精通-Lunix性能分析工具汇总

出于对Linux操作系统的兴趣&#xff0c;以及对底层知识的强烈欲望&#xff0c;因此整理了这篇文章。本文也可以作为检验基础知识的指标&#xff0c;另外文章涵盖了一个系统的方方面面。如果没有完善的计算机系统知识&#xff0c;网络知识和操作系统知识&#xff0c;文档中的工具…

echarts笔记-上下左右部分显示比例(解决Y轴显示不全)

主要就是option里面的grid如下&#xff1a; grid: {top: 18%,left: 20%,//原来是10%&#xff0c;修改为20%right: 2%,bottom: 24%, },比如y轴显示不全就可以这样设置&#xff1a; grid: {left: 25%,//原来是10%&#xff0c;修改为20%right: 0%, },

vue2项目中表格的增删查改

我们在项目中经常会用到对于表格的增删查改操作&#xff0c;以下使用vue2elementui来实现表格的增删查改 表格的基本属性 基础表格如下:(其中需要注意的是当el-table元素中注入data对象数组后&#xff0c;在el-table-column中用prop属性来对应对象中的键名即可填入数据&#x…

Viobot基本功能使用及介绍

设备拿到手当然是要先试一下效果的&#xff0c;这部分可以参考本专栏的第一篇 Viobot开机指南。 接下来我们就从UI开始熟悉这个产品吧&#xff01; 1.状态 设备上电会自动运行它的程序&#xff0c;开启了一个服务器&#xff0c;上位机通过连接这个服务器连接到设备&#xff0c…

new操作符干了啥(手写new操作符)

new操作符干了啥&#xff08;手写new操作符&#xff09; 在JS中&#xff0c;new操作符用于创建一个新对象并调用一个函数来初始化对象&#xff0c;下面是手写实现new操作符的方法&#xff1a; // 传入构造函数 const myNew (constructor) > {// 1、创建一个空对象 {}cons…

QGIS 如何添加天地图

相信很多小伙伴在 QGIS 里面添加天地图的时候一定感觉很困惑,按照官网的操作申请 Key 之后,添加相对应的服务地址之后看不到地图或者地图不正常显示,今天我们就来解决这个问题 以下所有操作基于 QGIS 3.22 版本 申请 Key 1. 添加天地图的第一步需要申请 Key,首先要注册天…