【Andoird开发】android获取蓝牙权限,beacon,android-beacon-library

iBeacon 最先是苹果的技术,使用android-beacon-library包可以在android上开发iBeacon 技术。

iBeacon的发明意义重大。它是一种基于蓝牙低功耗(Bluetooth Low Energy, BLE)技术的定位系统,通过向周围发送信号来标识其位置。这项技术的意义体现在以下几个方面:

  1. 室内定位与导航: iBeacon可用于在室内环境中提供定位和导航服务。传统的GPS技术在室内环境下往往效果不佳,而iBeacon通过布置在建筑物内部的信标,可以实现更精准的室内定位。

  2. 增强零售体验: 零售业是iBeacon应用的一个重要领域。商店可以利用iBeacon技术向顾客发送特定的优惠信息、促销活动或产品推荐,从而提升顾客体验并促进销售。

  3. 实时定位服务: iBeacon可以实现对移动设备的实时追踪,为企业和组织提供更有效的资产管理、人员定位和安全监控等服务。

  4. 交互式体验: 利用iBeacon技术,可以为用户提供更加个性化和交互式的体验。比如,在博物馆、展览或游乐园等场所,可以通过iBeacon向游客提供相关的解说信息或互动体验。

  5. 开发者创新: iBeacon开放的开发平台为开发者提供了广阔的创新空间,他们可以基于iBeacon技术开发各种各样的应用,从而为用户带来更丰富的体验和功能。

iBeacon的发明为室内定位和个性化服务领域带来了革命性的变革,极大地丰富了移动应用的功能和体验。

先加这句:implementation group: ‘org.altbeacon’, name: ‘android-beacon-library’, version: ‘2.20.6’
在这里插入图片描述
然后sync之后就能使用,xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><!-- Android 12以下才需要定位权限, Android 9以下官方建议申请ACCESS_COARSE_LOCATION --><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><uses-permission android:name="android.permission.BLUETOOTH" /><uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /><!-- Android 12在不申请定位权限时,必须加上android:usesPermissionFlags="neverForLocation",否则搜不到设备 --><uses-permissionandroid:name="android.permission.BLUETOOTH_SCAN"android:usesPermissionFlags="neverForLocation"tools:targetApi="s" /><uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" /><uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.MyApplication"tools:targetApi="31"><activityandroid:name=".MainActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

主java【搜不到我想要的设备,没有android自带的搜设备兼容性好,或许我用错了,但可以搜到设备!】:

package com.example.myapplication;import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanRecord;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;import com.google.android.material.bottomnavigation.BottomNavigationView;import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;import org.altbeacon.beacon.Beacon;
import org.altbeacon.beacon.BeaconConsumer;
import org.altbeacon.beacon.BeaconManager;
import org.altbeacon.beacon.BeaconParser;
import org.altbeacon.beacon.MonitorNotifier;
import org.altbeacon.beacon.RangeNotifier;
import org.altbeacon.beacon.Region;import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.UUID;public class MainActivity extends AppCompatActivity {private static final int PERMISSION_REQUEST_CODE = 100;private static final long SCAN_PERIOD = 10000;private static final String TAG = "TimeAttendantFast";private BluetoothLeScanner mLEScanner;private BluetoothManager btManager;private BluetoothAdapter btAdapter;private Handler scanHandler;private Handler mHandler;private Button checkInBtn;private TextView tvEmpID;private boolean isShowDialog;private ScanSettings settings;private ArrayList<ScanFilter> filters;private String employeeID;private List<String> beaconDeviceList = new ArrayList<>();private static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;private static final int REQUEST_CHECK_SETTINGS = 14;private static final String TAGx = "BluetoothSearch";private BluetoothAdapter bluetoothAdapter;private BroadcastReceiver bluetoothReceiver;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 请求权限requestPermissions();settingBlueTooth();scanLeDevice(true);EdgeToEdge.enable(this);setContentView(R.layout.activity_main);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);return insets;});}@Overrideprotected void onDestroy() {super.onDestroy();// 停止蓝牙设备搜索并注销广播接收器if (bluetoothAdapter != null) {if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {return;}bluetoothAdapter.cancelDiscovery();}unregisterReceiver(bluetoothReceiver);}private void settingBlueTooth() {// init BLEbtManager = (BluetoothManager) this.getSystemService(Context.BLUETOOTH_SERVICE);btAdapter = btManager.getAdapter();if (Build.VERSION.SDK_INT >= 21) {mLEScanner = btAdapter.getBluetoothLeScanner();settings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();filters = new ArrayList<>();}}/*** bytesToHex method*/static final char[] hexArray = "0123456789ABCDEF".toCharArray();private static String bytesToHex(byte[] bytes) {char[] hexChars = new char[bytes.length * 2];for (int j = 0; j < bytes.length; j++) {int v = bytes[j] & 0xFF;hexChars[j * 2] = hexArray[v >>> 4];hexChars[j * 2 + 1] = hexArray[v & 0x0F];}return new String(hexChars);}private void foundBeacon(String uuid, int major, int minor) {//LOGLog.i(TAG, "UUID: " + uuid + "\\nmajor: " + major + "\\nminor" + minor);}private void findBeaconPattern(byte[] scanRecord) {int startByte = 2;boolean patternFound = false;while (startByte <= 5) {if (((int) scanRecord[startByte + 2] & 0xff) == 0x02 && //Identifies an iBeacon((int) scanRecord[startByte + 3] & 0xff) == 0x15) { //Identifies correct data lengthpatternFound = true;break;}startByte++;}if (patternFound) {//Convert to hex Stringbyte[] uuidBytes = new byte[16];System.arraycopy(scanRecord, startByte + 4, uuidBytes, 0, 16);String hexString = bytesToHex(uuidBytes);//UUID detectionString uuid = hexString.substring(0, 8) + "-" +hexString.substring(8, 12) + "-" +hexString.substring(12, 16) + "-" +hexString.substring(16, 20) + "-" +hexString.substring(20, 32);// majorfinal int major = (scanRecord[startByte + 20] & 0xff) * 0x100 + (scanRecord[startByte + 21] & 0xff);// minorfinal int minor = (scanRecord[startByte + 22] & 0xff) * 0x100 + (scanRecord[startByte + 23] & 0xff);Log.i(TAG, "UUID: " + uuid + "\\nmajor: " + major + "\\nminor" + minor);foundBeacon(uuid, major, minor);}}private BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {@Overridepublic void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {findBeaconPattern(scanRecord);}};private ScanCallback mScanCallback = new ScanCallback() {@Overridepublic void onScanResult(int callbackType, ScanResult result) {Log.i(TAG, "callbackType " + callbackType);// 获取ScanRecord对象ScanRecord scanRecord = result.getScanRecord();String MAC = result.getDevice().getAddress();// 如果字符是以A4开头的,就是我们的设备if (MAC.startsWith("A4")) {Log.i(TAG, "MAC: " + MAC);}// 尝试直接从ScanRecord中获取设备名称if (scanRecord != null) {String deviceName = scanRecord.getDeviceName();if (deviceName != null && !deviceName.isEmpty()) {Log.i(TAG, "Device Name: " + deviceName);} else {// 如果getDeviceName返回null,可能需要从scanRecord的bytes中手动解析(虽然不常见)// 但大多数情况下,直接使用getDeviceName应该足够byte[] scanRecordBytes = scanRecord.getBytes();// 这里可以调用您自定义的方法findBeaconPattern来进一步解析数据,如果需要的话findBeaconPattern(scanRecordBytes);Log.i(TAG, "Device Name not directly available, parsing scan record...");}}}@Overridepublic void onBatchScanResults(List<ScanResult> results) {for (ScanResult sr : results) {Log.i(TAG, "ScanResult - Results" + sr.toString());}}@Overridepublic void onScanFailed(int errorCode) {Log.e(TAG, "Scan Failed Error Code: " + errorCode);}};private void scanLeDevice(final boolean enable) {Log.i(TAG, "BLE start scan");if (Build.VERSION.SDK_INT < 21) {Log.i(TAG, "start SDK_INT < 21");if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {// TODO: Consider calling//    ActivityCompat#requestPermissions// here to request the missing permissions, and then overriding//   public void onRequestPermissionsResult(int requestCode, String[] permissions,//                                          int[] grantResults)// to handle the case where the user grants the permission. See the documentation// for ActivityCompat#requestPermissions for more details.return;}btAdapter.startLeScan(leScanCallback);} else {Log.i(TAG, "start SDK_INT >= 21");mLEScanner.startScan(filters, settings, mScanCallback);}}private void requestPermissions() {if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED|| ContextCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_ADMIN) != PackageManager.PERMISSION_GRANTED|| ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED|| ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {// 如果没有获取到权限,请求权限ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.BLUETOOTH,android.Manifest.permission.BLUETOOTH_ADMIN,android.Manifest.permission.ACCESS_FINE_LOCATION,android.Manifest.permission.WRITE_EXTERNAL_STORAGE,}, PERMISSION_REQUEST_CODE);}} else {if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED|| ContextCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_ADVERTISE) != PackageManager.PERMISSION_GRANTED|| ContextCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED|| ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED|| ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {// 如果没有获取到权限,请求权限ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.BLUETOOTH_SCAN,android.Manifest.permission.BLUETOOTH_ADVERTISE,android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.ACCESS_FINE_LOCATION,android.Manifest.permission.WRITE_EXTERNAL_STORAGE,}, PERMISSION_REQUEST_CODE);}}// 如果权限已经被授予,直接进行蓝牙功能检查和定位功能检查checkBluetoothSupport();}private void checkBluetoothSupport() {// 检查手机蓝牙是否打开BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();if (bluetoothAdapter == null) {Toast.makeText(this, "本机不支持蓝牙功能, 无法蓝牙打卡", Toast.LENGTH_SHORT).show();finish();} else if (!bluetoothAdapter.isEnabled()) {Toast.makeText(this, "蓝牙未打开, 请先打开蓝牙", Toast.LENGTH_SHORT).show();finish();}// 检查定位是否打开LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {Toast.makeText(this, "定位未打开, 请先打开定位", Toast.LENGTH_SHORT).show();finish();}// 检查是否联网networkif (!locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {Toast.makeText(this, "网络未打开, 请先打开网络", Toast.LENGTH_SHORT).show();finish();}if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {Toast.makeText(this, "本机不支持蓝牙功能, 无法蓝牙打卡", Toast.LENGTH_SHORT).show();finish();} else {BluetoothManager bm = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);BluetoothAdapter bleAdapter = bm.getAdapter();if (bleAdapter == null || !bleAdapter.isEnabled()) {Toast.makeText(this, "本机不支持低功耗蓝牙功能, 无法蓝牙打卡", Toast.LENGTH_SHORT).show();finish();} else {Toast.makeText(this, "手机支持蓝牙定位打卡", Toast.LENGTH_SHORT).show();}}}
}

这个代码就完全没反应搜不到了:

import org.altbeacon.beacon.Beacon;
import org.altbeacon.beacon.BeaconConsumer;
import org.altbeacon.beacon.BeaconManager;
import org.altbeacon.beacon.RangeNotifier;
import org.altbeacon.beacon.Region;public class MainActivity extends AppCompatActivity implements BeaconConsumer {private BeaconManager beaconManager;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 初始化 BeaconManagerbeaconManager = BeaconManager.getInstanceForApplication(this);beaconManager.bind(this);}@Overridepublic void onBeaconServiceConnect() {// 监听 iBeacon 的信号beaconManager.addRangeNotifier(new RangeNotifier() {@Overridepublic void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {if (beacons.size() > 0) {for (Beacon beacon : beacons) {String uuid = beacon.getId1().toString(); // 获取 iBeacon 的 UUIDLog.d("Beacon", "UUID: " + uuid);}}}});try {// 开始监测所有的 iBeaconbeaconManager.startRangingBeaconsInRegion(new Region("myRangingUniqueId", null, null, null));} catch (RemoteException e) {e.printStackTrace();}}@Overrideprotected void onDestroy() {super.onDestroy();beaconManager.unbind(this);}
}

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

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

相关文章

【NumPy】关于numpy.arange()函数,看这一篇文章就够了

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

AI--构建检索增强生成 (RAG) 应用程序

LLM 所实现的最强大的应用之一是复杂的问答 (Q&A) 聊天机器人。这些应用程序可以回答有关特定源信息的问题。这些应用程序使用一种称为检索增强生成 (RAG) 的技术。 典型的 RAG 应用程序有两个主要组件 索引&#xff1a;从源中提取数据并对其进行索引的管道。这通常在线下…

实时3D云渲染与汽车虚拟仿真的联系

汽车虚拟仿真是指利用计算机技术对汽车进行全方位的模拟&#xff0c;包括车身结构、发动机、转向系统、悬挂系统、制动系统等各个方面&#xff0c;以达到实现汽车设计验证、性能分析、安全评估和驾驶模拟等目的的一种技术手段。现如今&#xff0c;越来越多的汽车制造商采用虚拟…

K8s Service 背后是怎么工作的?

kube-proxy 是 Kubernetes 集群中负责服务发现和负载均衡的组件之一。它是一个网络代理&#xff0c;运行在每个节点上, 用于 service 资源的负载均衡。它有两种模式&#xff1a;iptables 和 ipvs。 iptables iptables 是 Linux 系统中的一个用户空间实用程序&#xff0c;用于…

Kroma宣布推出Spectrum:以太坊Layer-2的先进原生质押服务

Kroma宣布推出备受期待的Spectrum&#xff0c;这是一项先进的原生质押服务&#xff0c;旨在彻底改变以太坊 Layer-2格局。Spectrum将于2024年5月14日开始运营&#xff0c;为用户提供利用质押ETH、stETH和eETH的奖励机会&#xff0c;助力用户在去中心化金融&#xff08;DeFi&…

爆火!开源多模态大模型在手机端进行本地部署!

节前&#xff0c;我们组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、今年参加社招和校招面试的同学。 针对大模型& AIGC 技术趋势、大模型& AIGC 落地项目经验分享、新手如何入门算法岗、该如何准备面试攻略、面试常考点等热门话题进行了…

二叉树遍历操作详解

目录 一、思路详解 1.1 递归思路 1.2 递归分支图 1.3 递归栈帧图 二、C语言实现 2.1 前序遍历 2.2 中序遍历 2.3 后序遍历 三、查找值为x的结点 3.1 递归思路 3.2 C语言代码 一、思路详解 采用递归的思想解决问题&#xff0c;以高度为3的满二叉树为例。 1.1 递归思…

ClickHouse 几年内数据查询及细节

在 ClickHouse 中&#xff0c;查询三年内的时间数据可以使用以下方法&#xff1a; 1. 使用日期函数 可以使用 ClickHouse 支持的日期函数来筛选出三年内的数据。例如&#xff0c;使用 today() 函数获取当天日期&#xff0c;使用 toDate() 函数将日期转换为指定格式&#xff0…

【C++】学习笔记——map和set

文章目录 十五、map和set1. 关联式容器2. set的介绍3. set的使用4. multiset5. map的介绍6. map的使用7. multimap8. map中重载的operator[] 未完待续 十五、map和set 1. 关联式容器 我们已经接触过STL中的部分容器&#xff0c;比如&#xff1a;vector 、list 、deque 等&…

Golang | Leetcode Golang题解之第99题恢复二叉搜索树

题目&#xff1a; 题解&#xff1a; func recoverTree(root *TreeNode) {var x, y, pred, predecessor *TreeNodefor root ! nil {if root.Left ! nil {// predecessor 节点就是当前 root 节点向左走一步&#xff0c;然后一直向右走至无法走为止predecessor root.Leftfor pr…

OpenHarmony开发之MQTT讲解

相信MQTT这个名称大家都不陌生&#xff0c;物联网的开发必然会遇到MQTT相关知识的应用。那么什么是MQTT&#xff1f;它有什么特点&#xff1f;它能解决什么问题&#xff1f;它是如何工作的&#xff1f;OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;的物…

简单快捷的图片格式转换工具:认识webp2jpg-online

经常写博客或记笔记的朋友们可能会碰到图床不支持的图片格式或图片太大需要压缩的情况。通常&#xff0c;我们会在浏览器中搜索在线图片格式转换器&#xff0c;但这些转换器往往伴有烦人的广告或要求登录&#xff0c;并且支持的转换格式有限。最近&#xff0c;我在浏览 GitHub …

hls.js实现分片播放视频

前言&#xff1a;hls.js官网&#xff1a;hls.js - npm 一、demo——在HTML中使用 <audio id"audio" controls></audio><script src"https://cdn.jsdelivr.net/npm/hls.jslatest"></script> <script>document.addEventList…

upload-labs 通关方法

目录 Less-1&#xff08;JS前端验证&#xff09; Less-2&#xff08;MIME验证&#xff09; Less-3&#xff08;黑名单&#xff0c;特殊过滤&#xff09; Less-4&#xff08;黑名单验证&#xff0c;.htaccess&#xff09; Less-5&#xff08;黑名单&#xff0c;点空格点绕过…

Qt | QCalendarWidget 类(日历)

01、QCalendarWidget 类 1、QCalendarWidget 类是 QWidget 的直接子类,该类用于日历,见下图 02、QCalendarWidget 属性 ①、dateEditAcceptDelay:int 访问函数:int dateEditAcceptDelay()const; void setDateEditAcceptDelay(int) 获取和设置日期编辑器的延迟时间(以毫秒…

给树莓派配置静态IP地址

第一步&#xff1a;查找默认网关 打开windowr&#xff1b;输入cmd&#xff0c; 输入 最后一行就是默认网关 ipconfig第二步&#xff1a;确定分配好给树莓派的IP地址 要注意&#xff1a;&#xff08;1&#xff09;静态ip地址与路由器网段保持一致&#xff08;2&#xff09;与…

压缩设备液压控制比例放大器

液压比例阀放大器是液压控制系统中的重要部件之一&#xff0c;用于控制输出油压方向流量和压力的精确控制。它由BEUEC比例放大器和比例电磁阀组成&#xff0c;通过调节比例放大器的增益和灵敏度参数&#xff0c;可以实现对液压系统输出油压方向流量和压力的精确控制。适用于各种…

动态IP与静态IP有什么区别?如何选择?

动态IP和静态IP都是指网络设备&#xff08;如计算机、服务器、路由器等&#xff09;在互联网上分配的IP地址的类型。 一、什么是动态IP&#xff0c;什么是静态IP&#xff1f; 1、什么是动态IP&#xff1f; 动态IP是指由Internet服务提供商&#xff08;ISP&#xff09;动态分配…

SpringBoot中使用AOP实现日志记录功能

目录 一、SpringBoot框架介绍 二、什么是 AOP 三、日志记录的必要性 四、SpringBoot中如何使用AOP实现日志记录功能 一、SpringBoot框架介绍 SpringBoot是一个开源的Java开发框架&#xff0c;旨在简化基于Spring框架的应用程序的开发。它提供了一套开箱即用的工具&#xf…

express.js--连接数据库,并且增删改查(四)

使用数据库需要在电脑安装mysql&#xff0c;然后使用navicat 我没有下载mysql,我使用的是小皮里面的数据库&#xff0c;需要破解版的navicat可以私信我 安装mysql npm i mysql 数据库的基本信息&#xff0c;我是直接写到配置文件里面的 config/index.js module.exports {…