安卓应用开发学习:通过腾讯地图SDK实现定位功能

news2024/11/16 23:32:32

一、引言

这几天有些忙,耽误了写日志,但我的学习始终没有落下,有空我就会研究《 Android App 开发进阶与项目实战》一书中定位导航方面的内容。在我的手机上先后实现了“获取经纬度及地理位置描述信息”和“获取导航卫星信息”功能后,这两天,我又参照这书中的内容,实现了通过腾讯地图的Android定位SDK实现定位的功能,并有所扩展。书文以记之。

二、腾讯位置服务平台创建应用

要使用腾讯地图的位置服务,首先要到腾讯位置服务平台(https://lbs.qq.com/)注册一个用户,登录后进入控制台,在应用管理下创建自己的应用,然后添加Key。具体步骤见以下截图:

1.登录打开控制台

2.找到应用管理->我的应用,点击“创建应用”按钮。

3.输入应用的名称,并选择应用类型,确认后生成应用。

4.回到我的应用页面,点击“添加Key”。

5.输入Key名称、描述,勾选“SDK"和”导航SDK“,并在下方的文本框中输入你在Android Studio中要创建应用的包名。

6.完成,生成的Key在Android Studio中集成腾旭地图时要用到。

三、集成腾讯地图

完成上面的操作后,在Android Studio中要对需要使用腾讯位置服务的应用进行设置才能使用腾讯地图的SDK。

1.打开已创建好的Module下的build.gradle文件,在文的依赖中添加腾讯地图组件。

// 腾讯定位
implementation 'com.tencent.map.geolocation:TencentLocationSdk-openplatform:7.2.8'
// 腾讯地图
implementation 'com.tencent.map:tencent-map-vector-sdk:4.3.9.9'
// 地图组件库
implementation 'com.tencent.map:sdk-utilities:1.0.6'

上述组件的版本并不是最新的,我是照着 《 Android App 开发进阶与项目实战》上输入的,组件的最新版本请到官网查询。

2.在Module的AndroidManifest.xml文件中添加权限配置。

我添加的权限是参考了 《 Android App 开发进阶与项目实战》中的内容,官网给的添加权限(见下方)和我添加的有些不同,但我这边能正常定位,说明有些权限应该是可由可无的。

<!-- 通过GPS得到精确位置 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!-- 通过网络得到粗略位置 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!-- 访问网络,某些位置信息需要从网络服务器获取 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- 访问WiFi状态,需要WiFi信息用于网络定位 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!-- 修改WiFi状态,发起WiFi扫描, 需要WiFi信息用于网络定位 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<!-- 访问网络状态, 检测网络的可用性,需要网络运营商相关信息用于网络定位 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- 访问网络的变化, 需要某些信息用于网络定位 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<!-- 蓝牙扫描权限 -->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<!-- 前台service权限 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<!-- 后台定位权限 -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<!-- A-GPS辅助定位权限,方便GPS快速准确定位 -->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>

3. 在AndroidManifest.xml文件的application节点中添加一行属性配置:

android:usesCleartextTraffic="true"

4.最后,在AndroidManifest.xml文件的application节点末尾添加名为TencentMapSDK的元数据,之前在官网平台上生成的Key就填在这里。

以上就是我的设置步骤,全部是参考《 Android App 开发进阶与项目实战》中的内容,与官网的步骤有所区别(官网设置连接),但我的应用实现腾讯地图定位没有遇到问题。

四、功能实现

我是参照《 Android App 开发进阶与项目实战》书中9.3.2 显示地图面板 的内容,创建的Activity可以在腾讯地图上显示手机所在的位置,并能在普通地图和卫星地图之间切换,还可以显示交通情况。另外,可以通过手势操作移动地图和缩放地图。其功能与微信中共享位置功能差不多。

 

                (普通地图模式)                                        (卫星地图+显示交通情况模式)

对书中的源码研究后,我决定再扩展一下,增加SDK自带的指南针图标,自己自定义的放大按钮、缩小按钮、回到手机所在位置按钮,另外还自定义一个显示地图中心图标且显示中心经纬度的功能。最终效果如下:

1. 普通地图模式

这是照搬的书中的源码,点击“普通”单选按钮,将地图类型设置为TencentMap.MAP_TYPE_NORMAL。进入地图后默认也是这个类型。关键代码:

private TencentMap mTencentMap; // 声明一个腾讯地图对象
private MapView mMapView; // 声明一个地图视图对象

// onCreate方法中初始化
mMapView = findViewById(R.id.mapView);
mTencentMap = mMapView.getMap(); // 获取腾讯地图对象

// 点击“普通地图”单选按钮后,执行以下语句
mTencentMap.setMapType(TencentMap.MAP_TYPE_NORMAL); // 设置普通地图

2.卫星地图模式

通过点击“卫星”单选按钮触发。关键代码:

// 点击“卫星地图”单选按钮后,执行以下语句
mTencentMap.setMapType(TencentMap.MAP_TYPE_SATELLITE); // 设置卫星地图

3. 显示交通情况

通过点击“交通情况”复选按钮触发,关键代码:

// 点击“交通情况”复选按钮触发
mTencentMap.setTrafficEnabled(isChecked); // 是否显示交通拥堵状况

4. 显示/隐藏中心点标记

这是我自己添加的功能,红色十字图标是一个TextView组件,这个组件与腾讯地图组件MapView都放在一个RelativeLayout布局中,MapView充满整个布局,TextView放在RelativeLayout中心位置。在onCreate方法初始化时,将这个TextView组件隐藏,在勾选了复选框后,才显示,另外“中心点”按钮,也与这个TextView联动,在TextView组件显示时“中心点”按钮可用,在TextView组件隐藏时“中心点”按钮不可用。

关键代码:

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >

        <com.tencent.tencentmap.mapsdk.maps.MapView
            android:id="@+id/mapView"
            android:layout_width="match_parent"
            android:layout_height="fill_parent" />

        <TextView
            android:id="@+id/tv_centerPoint"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center"
            android:layout_centerInParent="true"
            android:textSize="48sp"
            android:textColor="@color/red"
            android:text="+" />
    </RelativeLayout>
private Button btn_getCenter;  // 获取中心点按钮
private TextView tv_centerPoint; // 中心点标记


// 点“中心点”按钮左侧的复选框后,显示
tv_centerPoint.setVisibility(View.VISIBLE);  // 显示
btn_getCenter.setEnabled(true);  // 可用


// 取消“中心点”按钮左侧的复选框后,隐藏
tv_centerPoint.setVisibility(View.INVISIBLE);  // 隐藏
btn_getCenter.setEnabled(false);  // 不可用

5. 获取中心点位置

在“中心点”按钮左侧的复选框勾选的情况下,点击“中心点”按钮,会显示中心点标识,且获取地图中心点经纬度,并显示在界面中。关键代码如下:

CameraPosition cameraPosition = mTencentMap.getCameraPosition();
mCenterLatLng = cameraPosition.target;
Toast.makeText(this, "中心点坐标:" + mCenterLatLng.latitude + ";" + mCenterLatLng.longitude, Toast.LENGTH_LONG).show();

6. 放大/缩小地图

(点击放大按钮效果)                                        (点击缩小按钮效果)

放大和缩小按钮时参考了其它地图软件上的效果,我自己用带圆角样式的LinearLayout布局包裹了两个TextView组件实现的。这个LinearLayout布局也是放在前面说到的RelativeLayout布局中。LinearLayout布局位于地图组件的右下方向。两个TextView组件设置了OnClick监听器,点击后执行放大和缩小地图操作。关键代码:

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >

        <com.tencent.tencentmap.mapsdk.maps.MapView
            android:id="@+id/mapView"
            android:layout_width="match_parent"
            android:layout_height="fill_parent" />

        <LinearLayout
            android:layout_width="55dp"
            android:layout_height="wrap_content"
            android:layout_above="@+id/mapView"
            android:layout_alignEnd="@+id/mapView"
            android:layout_alignBottom="@+id/mapView"
            android:layout_marginEnd="20dp"
            android:layout_marginBottom="110dp"
            android:background="@drawable/radius_border_15"
            android:orientation="vertical">

            <TextView
                android:id="@+id/tv_enlarge"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="15dp"
                android:layout_marginBottom="15dp"
                android:gravity="center"
                android:text="+"
                android:textColor="@color/black"
                android:textSize="32sp"
                android:textStyle="bold" />

            <TextView
                android:id="@+id/tv_narrow"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="15dp"
                android:layout_marginBottom="15dp"
                android:gravity="center"
                android:text="-"
                android:textColor="@color/black"
                android:textSize="32sp"
                android:textStyle="bold" />

        </LinearLayout>
    </RelativeLayout>
// 点击放大按钮后执行
mTencentMap.moveCamera(CameraUpdateFactory.zoomIn()); // 放大一级
// 点击缩小按钮后执行
mTencentMap.moveCamera(CameraUpdateFactory.zoomOut()); // 缩小一级

7. 回到手机定位处

在地图中通过手指拖动地图,使手机定位脱离地图中心点后,通过点击“回到手机处”按钮就可以将地图的中心点重新设置为手机定位处,从而让地图中心点快速回到定位处。

这个图标是我从手机的百度地图上截图后,通过PS处理后得到的,保存为PNG格式后,放在项目的res/drawable-xhdpi文件夹下。在xml文件中这个图标放在ImageButton组件中,这个组件外套了一个带圆角的LinearLayout布局。LinearLayout布局放在RelativeLayout布局中,设置在mapView组件的左下方。

关键代码:

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >

        <com.tencent.tencentmap.mapsdk.maps.MapView
            android:id="@+id/mapView"
            android:layout_width="match_parent"
            android:layout_height="fill_parent" />
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignStart="@+id/mapView"
            android:layout_alignBottom="@+id/mapView"
            android:background="@drawable/radius_border_15"
            android:layout_marginStart="20dp"
            android:layout_marginBottom="50dp"
            android:orientation="horizontal">

            <ImageButton
                android:id="@+id/img_btn_myPlace"
                android:layout_width="54dp"
                android:layout_height="54dp"
                android:backgroundTint="@color/white"
                android:src="@drawable/ic_my_place"
                tools:ignore="ContentDescription" />
        </LinearLayout>
    </RelativeLayout>
// 点击“中心点”按钮后,执行
CameraPosition cameraPosition = mTencentMap.getCameraPosition();
mCenterLatLng = cameraPosition.target;
Toast.makeText(this, "中心点坐标:" + mCenterLatLng.latitude + ";" + mCenterLatLng.longitude, Toast.LENGTH_LONG).show();
        

8.添加指南针

这是腾讯地图自带的组件,只需要在onCreate方法中添加几行代码就可以:

mTencentMap = mMapView.getMap(); // 获取腾讯地图对象

// 在上面的语句获取到地图对象后,添加以下两行代码
UiSettings mysetting = mTencentMap.getUiSettings();
mysetting.setCompassEnabled(true);  // 开启指南针

五、代码展示

最后上完整的代码,希望对大家有用:

MapBasicActivity.Java文件

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.tencent.map.geolocation.TencentLocation;
import com.tencent.map.geolocation.TencentLocationListener;
import com.tencent.map.geolocation.TencentLocationManager;
import com.tencent.map.geolocation.TencentLocationRequest;
import com.tencent.tencentmap.mapsdk.maps.CameraUpdate;
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
import com.tencent.tencentmap.mapsdk.maps.MapView;
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
import com.tencent.tencentmap.mapsdk.maps.UiSettings;
import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptor;
import com.tencent.tencentmap.mapsdk.maps.model.BitmapDescriptorFactory;
import com.tencent.tencentmap.mapsdk.maps.model.CameraPosition;
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
import com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions;

public class MapBasicActivity extends AppCompatActivity implements TencentLocationListener, View.OnClickListener {
    private final static String TAG = "MapBasicActivity";
    private TencentLocationManager mLocationManager; // 声明一个腾讯定位管理器对象
    private MapView mMapView; // 声明一个地图视图对象
    private TencentMap mTencentMap; // 声明一个腾讯地图对象
    private boolean isFirstLoc = true; // 是否首次定位
    private Button btn_getCenter;  // 获取中心点按钮
    private TextView tv_centerPoint; // 中心点标记
    private LatLng mMyLatLng, mCenterLatLng;  // 我的位置, 地图中心位置

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map_basic);
        initLocation(); // 初始化定位服务
        initView(); // 初始化视图
    }

    // 初始化视图
    private void initView() {
        tv_centerPoint = findViewById(R.id.tv_centerPoint);
        tv_centerPoint.setVisibility(View.INVISIBLE);
        btn_getCenter = findViewById(R.id.btn_getCenter);
        btn_getCenter.setEnabled(false);
        RadioGroup rg_type = findViewById(R.id.rg_type);
        rg_type.setOnCheckedChangeListener((group, checkedId) -> {
            if (checkedId == R.id.rb_common) {
                mTencentMap.setMapType(TencentMap.MAP_TYPE_NORMAL); // 设置普通地图
            } else if (checkedId == R.id.rb_satellite) {
                mTencentMap.setMapType(TencentMap.MAP_TYPE_SATELLITE); // 设置卫星地图
            }
        });
        CheckBox ck_traffic = findViewById(R.id.ck_traffic);
        ck_traffic.setOnCheckedChangeListener((buttonView, isChecked) -> {
            mTencentMap.setTrafficEnabled(isChecked); // 是否显示交通拥堵状况
        });
        CheckBox ck_centerPoint = findViewById(R.id.ck_centerPoint);
        ck_centerPoint.setOnCheckedChangeListener((buttonView, isChecked) -> {
            if (isChecked) {
                tv_centerPoint.setVisibility(View.VISIBLE);
                btn_getCenter.setEnabled(true);
            } else {
                tv_centerPoint.setVisibility(View.INVISIBLE);
                btn_getCenter.setEnabled(false);
            }
        });
        // 设置按钮监听器
        findViewById(R.id.tv_enlarge).setOnClickListener(this);  // 放大地图
        findViewById(R.id.tv_narrow).setOnClickListener(this);  // 缩小地图
        findViewById(R.id.img_btn_myPlace).setOnClickListener(this);  // 回到我的位置
        findViewById(R.id.btn_getCenter).setOnClickListener(this);  // 获取中心点
        btn_getCenter.setOnClickListener(this);  // 获取中心点
    }

    // 初始化定位服务
    private void initLocation() {
        mMapView = findViewById(R.id.mapView);
        mTencentMap = mMapView.getMap(); // 获取腾讯地图对象
        UiSettings mysetting = mTencentMap.getUiSettings();
        mysetting.setCompassEnabled(true);  // 开启指南针
        mLocationManager = TencentLocationManager.getInstance(this);
        // 创建腾讯定位请求对象
        TencentLocationRequest request = TencentLocationRequest.create();
        request.setInterval(30000).setAllowGPS(true);
        request.setRequestLevel(TencentLocationRequest.REQUEST_LEVEL_ADMIN_AREA);
        mLocationManager.requestLocationUpdates(request, this); // 开始定位监听
    }

    @Override
    public void onLocationChanged(TencentLocation location, int resultCode, String resultDesc) {
        if (resultCode == TencentLocation.ERROR_OK) { // 定位成功
            if (location != null && isFirstLoc) { // 首次定位
                isFirstLoc = false;
                // 创建一个经纬度对象
                mMyLatLng = new LatLng(location.getLatitude(), location.getLongitude());
                CameraUpdate update = CameraUpdateFactory.newLatLngZoom(mMyLatLng, 12);
                mTencentMap.moveCamera(update); // 把相机视角移动到指定地点
                // 从指定图片中获取位图描述
                BitmapDescriptor bitmapDesc = BitmapDescriptorFactory
                        .fromResource(R.drawable.icon_locate);
                MarkerOptions ooMarker = new MarkerOptions(mMyLatLng).draggable(false) // 不可拖动
                        .visible(true).icon(bitmapDesc).snippet("这是您的当前位置");
                mTencentMap.addMarker(ooMarker); // 往地图添加标记
            }
        } else { // 定位失败
            Log.d(TAG, "定位失败,错误代码为"+resultCode+",错误描述为"+resultDesc);
        }
    }

    @Override
    public void onStatusUpdate(String s, int i, String s1) {}
    // 绑定生命周期
    @Override
    protected void onStart() {
        super.onStart();
        mMapView.onStart();
    }

    @Override
    protected void onStop() {
        super.onStop();
        mMapView.onStop();
    }

    @Override
    public void onPause() {
        super.onPause();
        mMapView.onPause();
    }

    @Override
    public void onResume() {
        super.onResume();
        mMapView.onResume();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mLocationManager.removeUpdates(this); // 移除定位监听
        mMapView.onDestroy();
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.tv_enlarge) {  // 放大地图
            mTencentMap.moveCamera(CameraUpdateFactory.zoomIn()); // 放大一级
        } else if (v.getId() == R.id.tv_narrow) {  // 缩小地图
            mTencentMap.moveCamera(CameraUpdateFactory.zoomOut()); // 缩小一级
        } else if (v.getId() == R.id.img_btn_myPlace) {  // 回到我的位置
            CameraUpdate update = CameraUpdateFactory.newLatLng(mMyLatLng);
            mTencentMap.moveCamera(update); // 把相机视角移动到指定地点
        } else if (v.getId() == R.id.btn_getCenter) {  // 获取中心点坐标
            CameraPosition cameraPosition = mTencentMap.getCameraPosition();
            mCenterLatLng = cameraPosition.target;
            Toast.makeText(this, "中心点坐标:" + mCenterLatLng.latitude + ";" + mCenterLatLng.longitude, Toast.LENGTH_LONG).show();
        }
    }
}

activity_map_basic.xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MapBasicActivity">

    <RadioGroup
        android:id="@+id/rg_type"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <RadioButton
            android:id="@+id/rb_common"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:checked="true"
            android:text="普通"
            android:textColor="@color/black"
            android:textSize="17sp" />

        <RadioButton
            android:id="@+id/rb_satellite"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:checked="false"
            android:text="卫星"
            android:textColor="@color/black"
            android:textSize="17sp" />

        <CheckBox
            android:id="@+id/ck_traffic"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="false"
            android:text="交通情况"
            android:textColor="@color/black"
            android:textSize="17sp" />

        <CheckBox
            android:id="@+id/ck_centerPoint"
            android:layout_width="35dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="10dp"
            android:checked="false"
            android:text=""
            android:textColor="@color/black"
            android:textSize="17sp" />

        <Button
            android:id="@+id/btn_getCenter"
            android:layout_width="80dp"
            android:layout_height="wrap_content"
            android:text="中心点"/>
    </RadioGroup>


    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >

        <com.tencent.tencentmap.mapsdk.maps.MapView
            android:id="@+id/mapView"
            android:layout_width="match_parent"
            android:layout_height="fill_parent" />

        <LinearLayout
            android:layout_width="55dp"
            android:layout_height="wrap_content"
            android:layout_above="@+id/mapView"
            android:layout_alignEnd="@+id/mapView"
            android:layout_alignBottom="@+id/mapView"
            android:layout_marginEnd="20dp"
            android:layout_marginBottom="110dp"
            android:background="@drawable/radius_border_15"
            android:orientation="vertical">

            <TextView
                android:id="@+id/tv_enlarge"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="15dp"
                android:layout_marginBottom="15dp"
                android:gravity="center"
                android:text="+"
                android:textColor="@color/black"
                android:textSize="32sp"
                android:textStyle="bold" />

            <TextView
                android:id="@+id/tv_narrow"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="15dp"
                android:layout_marginBottom="15dp"
                android:gravity="center"
                android:text="-"
                android:textColor="@color/black"
                android:textSize="32sp"
                android:textStyle="bold" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignStart="@+id/mapView"
            android:layout_alignBottom="@+id/mapView"
            android:background="@drawable/radius_border_15"
            android:layout_marginStart="20dp"
            android:layout_marginBottom="50dp"
            android:orientation="horizontal">

            <ImageButton
                android:id="@+id/img_btn_myPlace"
                android:layout_width="54dp"
                android:layout_height="54dp"
                android:backgroundTint="@color/white"
                android:src="@drawable/ic_my_place"
                tools:ignore="ContentDescription" />
        </LinearLayout>

        <TextView
            android:id="@+id/tv_centerPoint"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center"
            android:layout_centerInParent="true"
            android:textSize="48sp"
            android:textColor="@color/red"
            android:text="+" />

    </RelativeLayout>

</LinearLayout>

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

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

相关文章

Zookeeper笔记1

一、介绍 Zookeeper 是一个开源的分布式的&#xff0c;为分布式框架提供协调服务的 Apache 项目。是一个基于观察者模式设计的分布式服务管理框架&#xff0c;它负责存储和管理大家都关心的数据&#xff0c;然后接受观察者的注册&#xff0c;一旦这些数据的状态发生变化&#…

基于路径长度的样条插补算法(自动驾驶和路径跟踪控制适用)

以前在做车辆跟踪控制的时候发现在针对有多个X和多个Y对应的路径插补时候&#xff0c;总是报错&#xff0c;因为MATLAB里面的interp1插补函数它要求x要唯一对应一个y&#xff0c;当路径以单独的x或者y来求插补时候的时候就报错。由于在使用Matlab的interp1函数进行插值时&#…

暴雨来袭,陈赫家变“水帘洞”网友:赫哥滴滴打船吗?

在魔都上海&#xff0c;一场突如其来的暴雨 不仅让街道变成了河流&#xff0c;还悄悄上演了一场现实版的“水帘洞”奇遇 而这场奇遇的主角&#xff0c;竟然是喜剧界的明星——陈赫&#xff01; 这天&#xff0c;乌云密布&#xff0c;电闪雷鸣 魔都的天空仿佛被捅了个窟窿 雨…

为什么我的Skype点数不见了?如何重新激活 Skype 点数?

您超过180天没有使用过点数打电话功能&#xff0c;点数暂时封存在您的账户里面&#xff0c;需要您手动激活&#xff08;目前必须要登录网页版skype&#xff09; 可再次使用。 如何重新激活 Skype 点数&#xff1f; 登录到你的帐户 . 选择 重新激活信用额度 .注意&#xff1a; …

中医药文化传承进校园活动授牌仪式在石家庄主办举办

青春闪“药”&#xff0c;我心向党。2024年6月30日&#xff0c;由河北省药品医疗器械检验研究院主办的”中医药文化传承进校园活动在石家庄主办。来自河北省各地24所学校作为示范学校现场接牌。 河北省科协科普部部长范玉鑫、河北省教育厅学位管理与研究生处副处长耿立艳、河北…

Skipfish一键扫描网站漏洞(KALI工具系列三十四)

目录 1、KALI LINUX 简介 2、Skipfish工具简介 3、信息收集 3.1 目标IP 3.2 kali的IP 4、操作步骤 4.1创建目录 4.2开始扫描 4.3 配置扫描 4.4 指定范围 4.5 查看扫描结果 5、总结 1、KALI LINUX 简介 Kali Linux 是一个功能强大、多才多艺的 Linux 发行版 &#xf…

基于深度学习的水果蔬菜检测识别系统(Python源码+YOLOv8+Pyqt5界面+数据集+训练代码 MX_004期)

系统演示&#xff1a; 基于深度学习的水果蔬菜检测识别系统 界面图&#xff1a; 技术组成&#xff1a; 深度学习模型&#xff08;YOLOv8&#xff09;&#xff1a; YOLOv8是基于YOLO系列的目标检测模型&#xff0c;具有较快的检测速度和良好的准确率&#xff0c;适合于实时应用场…

DP:子数组问题

文章目录 引言子数组问题介绍动态规划的基本概念具体问题的解决方法动态规划解法&#xff1a;关于子数组问题的几个题1.最大子数组和2.环形子数组的最大和3.乘积最大子数组4.乘积为正数的最长子数组长度5.等差数列划分 总结 引言 介绍动态规划&#xff08;DP&#xff09;在解决…

6.x86游戏实战-C++实现跨进程读写-通过基址读取人物状态标志位

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 上一个内容&#xff1a;5.x86游戏实战-CE定位基地址 上一个内容找出了人物状态标志位的基址&#xff0…

电脑录音软件哪个好?7款录制音频工具大盘点,赶快学起来!(2024)

也许你渴望提取你最喜欢的节目的背景音乐&#xff0c;或者你希望录制自己的声音制作教程。如果是这样&#xff0c;你就需要一款优秀的电脑录音软件&#xff0c;来帮助你捕捉任何你想要的声音&#xff0c;而且不会损失音质。目前市场上存在着大量的录制音频工具&#xff0c;面对…

C++ | Leetcode C++题解之第207题课程表

题目&#xff1a; 题解&#xff1a; class Solution { private:vector<vector<int>> edges;vector<int> indeg;public:bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {edges.resize(numCourses);indeg.resize(numCo…

创意无界:探索国产创成式填充的无限潜力

在数字艺术与设计的世界中&#xff0c;创新技术不断涌现&#xff0c;而"创成式填充"无疑是其中的一颗璀璨新星。今天米兔要安利的这款国产ps插件-StartaAI拥有强大的AI功能&#xff0c;其AI扩图和局部重绘更是成为PS创成式填充的国产平替。 什么是创成式填充&#x…

clion开发51 没有创建成功可能是Clion版本问题

安装插件 PlatformlO for CLion 进入这个网站下载get-platformio.py https://docs.platformio.org/en/latest/core/installation/methods/installer-script.html#local-download-macos-linux-windows 点击 Installation Methods 选择 Local Download (macOS/Linux/Windows) 点…

如何评价CSS框架TailwindCSS?

端午三天&#xff0c;你们在放假&#xff0c;而我&#xff0c;一个人躲在家里&#xff0c;苦练 tailwindcss。 我在准备这样一个学习项目&#xff0c;它与传统的文章/视频类学习不同&#xff0c;我会在教程中内置大量的可交互案例&#xff0c;提供沉浸式的学习体验&#xff0c…

Vue组件化、单文件组件以及使用vue-cli(脚手架)

文章目录 1.Vue组件化1.1 什么是组件1.2 组件的使用1.3 组件的名字1.4 嵌套组件 2.单文件组件2.1 vue 组件组成结构2.1.1 template -> 组件的模板结构2.1.2 组件的 script 节点2.1.3 组件的 style 节点 2.2 Vue组件的使用步骤2.2.1 组件之间的父子关系2.2.2 使用组件的三个步…

通过nginx去除 api url前缀 并保持后面剩余的url不变向后台请求

如 我前台浏览器向后台请求的接口是 http://127.0.0.1:5099/api/sample/sample/getbuttonlist 实际的请求接口传向 http://192.168.3.71:5099/sample/sample/getbuttonlist 方法是向config中加入下面这样一个server server {listen 5099;location /api/ {rewrite ^/a…

【Python机器学习】模型评估与改进——打乱划分交叉验证

打乱划分交叉验证是一种非常灵活的交叉验证策略。 在打乱划分交叉验证中&#xff0c;每次划分为训练集取样train_size个点&#xff0c;为测试集取样test_size个不相交的点。将这一划分方法重复n_iter次。 举例&#xff1a; import matplotlib.pyplot as plt import mglearnm…

mysql wrnning Difficult to find free blocks in the buffer pool解决方法

mysql [InnoDB] Difficult to find free blocks in the buffer pool (140397 search iterations)! 我使用的是mysql8,。 原因&#xff1a;这种情况&#xff0c;多半出现在别人在非常大的写入&#xff0c;或者百万级的查询中。 解决方式&#xff0c;centos7在线安装的mysql&am…

软件测试面试题常见一百道【含答案】

1、问&#xff1a;你在测试中发现了一个bug&#xff0c;但是开发经理认为这不是一个bug&#xff0c;你应该怎样解决? 首先&#xff0c;将问题提交到缺陷管理库里面进行备案。 然后&#xff0c;要获取判断的依据和标准&#xff1a; 根据需求说明书、产品说明、设计文档等&am…

初音未来短视频:成都柏煜文化传媒有限公司

初音未来短视频&#xff1a;虚拟偶像的魅力与影响 在数字化时代&#xff0c;虚拟偶像逐渐崭露头角&#xff0c;其中初音未来无疑是这一领域的佼佼者。她以独特的形象和音乐才华&#xff0c;赢得了全球无数粉丝的喜爱。成都柏煜文化传媒有限公司 初音未来的短视频&#xff0c;更…