Android百度地图显示+抽屉式侧边栏

本文介绍了如何使用安卓开发构建一个具备百度地图定位功能的应用。包括显示地图、侧滑抽屉布局、GPS和网络定位、权限管理、POI检索、周边搜索等功能。核心代码展示了MainActivity的实现,涉及LocationClient、地图控件和定位监听器的使用。此外,还提到了Android 6.0以上的运行时权限管理和百度地图API的Key申请流程。
摘要由CSDN通过智能技术生成

App介绍

之前学安卓时候做了一个百度地图定位app。

功能有:显示地图,侧面抽屉布局,悬浮按钮点位点击能回到自己位置,标题栏控件,GPS和网络定位,权限管理等等。

真机测试图
在这里插入图片描述
在这里插入图片描述

==================================================

后续:加了一些功能:POI检索,周边搜索,搜索框条件搜索,中心标记地点等等功能。

下面是进阶版

请添加图片描述

主要代码部分

主程序 MainActivity

package com.example.lbstest;

import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ZoomControls;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.navigation.NavigationView;

import java.util.ArrayList;
import java.util.List;
import static com.baidu.mapapi.map.MyLocationConfiguration.LocationMode.FOLLOWING;
import static com.baidu.mapapi.map.MyLocationConfiguration.LocationMode.NORMAL;

public class MainActivity extends AppCompatActivity {

    private TextView positionText;//经纬度等信息显示
    private boolean isVisibility_flag = false;//控制是否显示经纬度
    private LocationClient mLocationClient;//定位客户端
    private MapView mapView;//地图显示
    private BaiduMap baiduMap;//地图总控制器
    private boolean isFirstLocate = true;//控制第一次经纬度显示次数
    private FloatingActionButton  Map_but;
    private Toolbar toolbar;//标题栏
    private DrawerLayout drawerLayout;//抽屉式布局


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mLocationClient = new LocationClient(getApplicationContext());
        //注册位置监听器 , 当获取到位置信息时候,会回调
        mLocationClient.registerLocationListener(new MyLocationListener());
        //初始化:一定要在setContentView之前用
        SDKInitializer.initialize(getApplicationContext());

        setContentView(R.layout.activity_main);
        positionText = findViewById(R.id.position_text_view);
        mapView = findViewById(R.id.bmapView);
        Map_but =findViewById(R.id.Map_but);//浮选按钮

        baiduMap = mapView.getMap();
        baiduMap.setMyLocationEnabled(true);//开启 我 在地图上显示的功能
        toolbar = findViewById(R.id.toolbar);
        drawerLayout = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        setSupportActionBar(toolbar);//设置好自定义的标题栏

        //下面几列是布局
        ActionBar actionBar = getSupportActionBar();//标题栏
        if (actionBar!=null){
            actionBar.setDisplayHomeAsUpEnabled(true);//让导航栏显示出来
            actionBar.setHomeAsUpIndicator(R.drawable.daohanglan);//设置导航栏按钮
        }
        navigationView.setCheckedItem(R.id.nav_daohang);//设置为默认选中
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {//处理逻辑
                drawerLayout.closeDrawers();//关闭抽屉
                return true;
            }
        });


        //由于android 6.0运行时权限,所以要加上动态申请权限的代码,其中有三个属于危险权限,我们需要一次性申请三个权限
        //这里我们用到一个做法,首先创建一个空的List集合,然后判断这3个权限是否被授权,如果没有被授权就添加到集合中,如果已经授权则不添加
        List<String> permissionList = new ArrayList<>();

        if (ContextCompat.checkSelfPermission(MainActivity.this,
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION);
        }
        if (ContextCompat.checkSelfPermission(MainActivity.this,
                Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_DENIED) {
            permissionList.add(Manifest.permission.READ_PHONE_STATE);
        }
        if (ContextCompat.checkSelfPermission(MainActivity.this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }

        //然后判断List里是否有对象,有则代表需要动态申请权限
        if (!permissionList.isEmpty()) {//集合不为空则代表有需要申请的危险权限

            //调用toArray()方法将List转换成数组,然后传入到ActivityCompat.requestPermissions()一次性全部去申请
            String[] perimissions = permissionList.toArray(new String[permissionList.size()]);
            ActivityCompat.requestPermissions(MainActivity.this,perimissions,1);

        }else requestLocation();
    }
    private void requestLocation(){
        initLocation();
        mLocationClient.start();
    }

    /*位置管理选择*/
    private void initLocation() {
        LocationClientOption option = new LocationClientOption();//定位客户端选项类
        option.setScanSpan(2000);//设置2秒钟更新一次数据
        //High_Accuracy :表示高精度模式,在GPS信号正常的情况下优先使用GPS,在无法接收GPS的时候使用网络定位,一般手机默认就是这种模式
        //Battery_Saving :表示节电模式,只会使用网络定位
        //Device_Sensors :表示传感器模式,只会使用GPS定位
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        option.setIsNeedAddress(true);//详细的位置信息
        option.setCoorType("bd09ll");//设置的是百度的定位标准
        mLocationClient.setLocOption(option);
    }
    @Override
    //只有权限全部允许才能运行
    //第一是请求的id,第二个是请求具体的权限,第三个是请求的结果
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode){
            case 1:
                if (grantResults.length>0){
                    for (int result: grantResults){
                        if (result!=PackageManager.PERMISSION_GRANTED){
                            Toast.makeText(MainActivity.this,"权限未全部通过",Toast.LENGTH_SHORT);
                            finish();
                            return;
                        }
                    }
                    requestLocation();
                }else {
                    Toast.makeText(MainActivity.this,"未发生未知错误",Toast.LENGTH_SHORT);
                    finish();
                }
                break;
            default:
                break;
        }
    }

    /*监听线程,获得当前的经纬度,并显示*/
    public class MyLocationListener extends BDAbstractLocationListener {
        @Override
        public void onReceiveLocation(final BDLocation location) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {

                    if (location.getLocType() == BDLocation.TypeGpsLocation || location.getLocType() == BDLocation.TypeNetWorkLocation) {
                        if (location.getLocType() == BDLocation.TypeGpsLocation) {
                        positionText.setText(" Location Type  :  GPS "+"\n Longitude  :  "+location.getLongitude()+"\n Latitude  :  "+location.getLatitude()+"\n Developer  :  KaiKai-G");
                    }else positionText.setText(" Location Type  :  Network "+"\n Longitude  :  "+location.getLongitude()+"\n Latitude  :  "+location.getLatitude()+"\n Developer  :  KaiKai-G");
                        navigateTo(location);

                    }
                    //按锁定自己位置按钮改变isFirslLocate可以再次回到地图
                    Map_but.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            isFirstLocate = true;
                        }
                    });
                    //隐藏百度logo
                    View child = mapView.getChildAt(1);
                    if (child != null && (child instanceof ImageView || child instanceof ZoomControls)) {
                        child.setVisibility(View.INVISIBLE);
                    }

                }
            });
        }
    }
    private void navigateTo(BDLocation location){//封装地点信息和我的信息, 并把信息传到地图显示

        if(isFirstLocate){//防止多次调用,这个方法只需要调用一次 地图移动到我们当前位置
            LatLng ll = new LatLng(location.getLatitude(),location.getLongitude());//传入纬度(第一个参数)和经度
            MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);
            baiduMap.animateMapStatus(update);
            update =MapStatusUpdateFactory.zoomTo(17f);//缩放 3-19之间选择值越大越清晰
            baiduMap.animateMapStatus(update);
            isFirstLocate = false;
        }
        MyLocationData locData = new MyLocationData.Builder()
                //获取半径
                .accuracy(location.getRadius())
                // 此处设置开发者获取到的方向信息,顺时针0-360
                .direction(location.getDirection())
                .latitude(location.getLatitude())
                .longitude(location.getLongitude()).build();
        baiduMap.setMyLocationData(locData);
        //定位模式、是否开启方向、设置自定义定位图标、精度圈填充颜色以及精度圈边框颜色5个属性。
        //地图SDK支持三种定位模式:NORMAL(普通态), FOLLOWING(跟随态), COMPASS(罗盘态)
        BitmapDescriptor mCurrentMarker = BitmapDescriptorFactory.fromResource(R.drawable.location);
        MyLocationConfiguration myLocationConfiguration =new MyLocationConfiguration(NORMAL,true,
                mCurrentMarker,0x3290A4F7,0xAA212101);
        baiduMap.setMyLocationConfiguration(myLocationConfiguration);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {//加载toolbar这个菜单文件
        getMenuInflater().inflate(R.menu.toolbar,menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {//menu上面的item按键具体实现

        switch (item.getItemId()){
            case R.id.backup:
                if (isVisibility_flag){
                    positionText.setVisibility(View.VISIBLE);//显示经纬度信息
                    Toast.makeText(this,"显示信息",Toast.LENGTH_SHORT).show();
                    isVisibility_flag = false;
                }else{
                    positionText.setVisibility(View.GONE);//隐藏经纬度信息
                    isVisibility_flag = true;
                }
                break;
            case R.id.delete:
                Toast.makeText(this,"清除",Toast.LENGTH_SHORT).show();
                break;
            case R.id.settings:
                Toast.makeText(this,"you clicked settings",Toast.LENGTH_SHORT).show();
                break;
            case android.R.id.home://注意 前面加android 而且导航栏按钮 id 一直是android.R.id.home
                drawerLayout.openDrawer(GravityCompat.START);//打开向Start滑动的菜单
        }
        return true;
    }

    public void onConnectHotSpotMessage(String s, int i) {

    }

    @Override
    protected void onResume() {
        super.onResume();
        mapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mapView.onPause();
    }

    @Override
    protected void onDestroy(){
        super.onDestroy();
        mLocationClient.stop();
        mapView.onDestroy();
        baiduMap.setMyLocationEnabled(false);

    }
}

布局:activity_main

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    <com.baidu.mapapi.map.MapView
        android:id="@+id/bmapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true"/>
        <!--clickable  true可点击-->
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="70dp"
                android:background="#F0494950"
                android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

            <!--them 设置的是单独Tooolbar这个控件为深色,其他元素:比如他上边的字为浅色
            popupTheme Toolbar内如果有按键,为了防止是深色主题 就设置弹出来的菜单是淡色(和原本主题颜色一样)-->
        </FrameLayout>
    <TextView
        android:id="@+id/position_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/colorPrimary"
        android:layout_marginTop="70dp"
        />
        <!--visibility="gone" 隐藏TextView-->

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/Map_but"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="530dp"
        android:layout_marginRight="16dp"
        android:layout_alignParentRight="true"
        android:src="@drawable/temg"
        android:elevation="8dp"
        app:maxImageSize="30dp"
        />
        <!--floatingActionButton浮选按钮 elevation 悬浮的阴影大小
        fabSize设置圆圈背景大小 maxImageSize 设置圈内图片大小-->
    </RelativeLayout>

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/nav_menu"
        app:headerLayout="@layout/nav_header"
        />

</androidx.drawerlayout.widget.DrawerLayout>

侧面抽屉布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="180dp"
    android:padding="10dp"
    android:background="@drawable/yueqiu">
    <de.hdodenhof.circleimageview.CircleImageView
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:src="@drawable/kai"
        android:layout_centerInParent="true"/>
    <TextView
        android:id="@+id/user"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Test User:KaiKai_G"
        android:textColor="#FBFBFB"
        android:layout_alignParentBottom="true"
        android:layout_centerInParent="true"
        />

</RelativeLayout>

设置主题和浮选按钮的样式。

styles.xml

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">#C3EDE9</item>
    </style>

    <style
        name ="nav_menus_style">
        <item name="android:textSize">30sp</item>
    </style>
    <dimen name="design_fab_size_normal">45dp</dimen><!--设置 浮选按钮背景的大小-->
</resources>

完整项目下载

还有一些需要的jar包,权限设置,菜单栏等等完整的项目都放到了:GitHub,这只是普通的后续添加的功能我还没上传。

注意事项

jar 包和其他几个so文件的位置
请添加图片描述
需要在这个文件里写明
请添加图片描述
百度地图的key每一个项目都对应不同的key
所以需要去百度地图开发者平台申请key,不然无法正常使用地图
在这里插入图片描述
SHA1两个都需要填写

第一个发布版需要先将项目进行apk打包,生成秘钥库,然后通过秘钥库才能得到SHA1.

keytool -list -v -keystore D:\Android_Studio\miyaoku_jks\Crms.jks

密码是自己打包时候定义的。

SHA1开发板 的需要在sdk的.android 目录下找到.debug.keystore文件再输入

keytool -list -v -keystore debug.keystore

然后密码是 android

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值