【Android 高德地图POI定位地址搜索】

news2024/11/15 9:32:34

先上演示:
在这里插入图片描述
高德地图的key申请这里就不讲了,比较简单,网上有很多资料,或者前往官网查看:官方文档

依赖引入

项目使用了如下依赖:

    //高德地图
    implementation 'com.amap.api:3dmap:latest.integration'
    //地图搜索功能
    implementation 'com.amap.api:search:latest.integration'
    //权限申请
    implementation 'com.github.getActivity:XXPermissions:18.3'

配置清单

	<!--允许访问网络,必选权限-->
    <uses-permission android:name="android.permission.INTERNET" />

    <!--允许获取粗略位置,若用GPS实现定位小蓝点功能则必选-->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

    <!--允许获取网络状态,用于网络定位,若无gps但仍需实现定位小蓝点功能则此权限必选-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <!--允许获取wifi网络信息,用于网络定位,若无gps但仍需实现定位小蓝点功能则此权限必选-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

    <!--允许获取wifi状态改变,用于网络定位,若无gps但仍需实现定位小蓝点功能则此权限必选-->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

    <!--允许写入扩展存储,用于数据缓存,若无此权限则写到私有目录-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <!--允许写设备缓存,用于问题排查-->
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />

    <!--允许读设备等信息,用于问题排查-->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

在application节点下配置key:

<meta-data
	android:name="com.amap.api.v2.apikey"
	android:value="******你的key******"/>

代码部分

页面布局

页面比较简单,就是一个输入框,一个MapView和一个ListView

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

    <EditText
        android:id="@+id/et_search"
        android:layout_width="match_parent"
        android:layout_height="33dp"
        android:layout_marginVertical="15dp"
        android:layout_marginHorizontal="10dp"
        android:background="@drawable/round_shape"
        android:gravity="center"
        android:hint="搜索地点"
        android:textColorHint="@color/black"
        android:imeOptions="actionDone"
        android:inputType="text"
        android:paddingHorizontal="10dp"
        android:textColor="@color/black"
        android:textSize="15sp" />
    <RelativeLayout
        android:layout_weight="1"

        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <com.amap.api.maps.MapView
            android:id="@+id/mapView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </RelativeLayout>

    <ListView
        android:id="@+id/listView"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

round_shape

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <!--圆角半径-->
    <!-- rounded corner -->
    <corners android:radius="20dp" />
    <!--填充颜色-->
    <solid android:color="#C8C8C8" />
</shape>

图片资源:location_center
在这里插入图片描述

隐私合规

新版本在使用高德地图前都要调用隐私合规接口,不然无法使用

//隐私合规接口
MapsInitializer.updatePrivacyShow(this,true,true);
MapsInitializer.updatePrivacyAgree(this,true);

权限申请

    /**
     * 权限请求
     **/
    private void permission(){
        String[] permission;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            permission=new String[]{
                    Permission.ACCESS_COARSE_LOCATION,
                    Permission.ACCESS_FINE_LOCATION,
                    Permission.MANAGE_EXTERNAL_STORAGE,
                    Permission.READ_PHONE_STATE,
            };
        }
        else {
            permission=new String[]{
                    Permission.ACCESS_COARSE_LOCATION,
                    Permission.ACCESS_FINE_LOCATION,
                    Permission.READ_PHONE_STATE,
            };
        }
        XXPermissions.with(this)
                .permission(permission).request(new OnPermissionCallback() {
                    @Override
                    public void onGranted(@NonNull List<String> permissions, boolean allGranted) {
                        if (allGranted){
                            initLocation();
                            startLocation();
                        }
                        else {
                            Toast.makeText(MainActivity.this, "获取部分权限成功,但部分权限未正常授予", Toast.LENGTH_SHORT).show();
                        }
                    }
                    @Override
                    public void onDenied(@NonNull List<String> permissions, boolean doNotAskAgain) {
                        if (doNotAskAgain){
                            XXPermissions.startPermissionActivity(MainActivity.this,permissions);
                        }
                        else {
                            Toast.makeText(MainActivity.this, "权限获取失败", Toast.LENGTH_SHORT).show();
                        }
                    }
                });
    }

初始化

在onCreate进行初始化

        mMapView=findViewById(R.id.mapView);
        ListView listView = findViewById(R.id.listView);
        EditText search = findViewById(R.id.et_search);
        mMapView.onCreate(savedInstanceState);
        aMap=mMapView.getMap();
        //地图移动监听
        aMap.setOnCameraChangeListener(new AMap.OnCameraChangeListener() {
            @Override
            public void onCameraChange(CameraPosition cameraPosition) {
            }

            @Override
            public void onCameraChangeFinish(CameraPosition cameraPosition) {

                if (!flag){
                    if (poiAdapter!=null){
                        poiAdapter.setSelectPosition(0);
                    }
                    try {
                        getGeocodeSearch(cameraPosition.target);
                        setMapCenter(cameraPosition.target);
                    } catch (AMapException e) {
                        throw new RuntimeException(e);
                    }
                    listView.smoothScrollToPosition(0);
                }
                flag=false;
            }
        });

        permission();

        poiAdapter = new PoiAdapter(beanList,this);
        listView.setAdapter(poiAdapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                poiAdapter.setSelectPosition(position);
                poiAdapter.notifyDataSetChanged();
                selectBean = beanList.get(position);
                flag=true;//当是点击地址条目触发的地图移动时,不进行逆地理解析
                aMap.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(selectBean.getLatitude(),selectBean.getLongitude()))); //设置地图中心点
            }
        });
        //搜索监听
        search.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (!TextUtils.isEmpty(s.toString())){
                    showTip(s.toString());
                }
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

tip搜索

    /**
     * 搜索tip
     **/
    private void showTip(String input){
        InputtipsQuery inputQuery = new InputtipsQuery(input, city);
        Inputtips inputTips = new Inputtips(MainActivity.this, inputQuery);
        inputTips.setInputtipsListener(new Inputtips.InputtipsListener() {
            @Override
            public void onGetInputtips(List<Tip> tipList, int rCode) {
                if (rCode == AMapException.CODE_AMAP_SUCCESS) {// 正确返回
                    if (tipList.size()!=0){
                        beanList.clear();
                        for (Tip tip:tipList){
                            if (tip.getPoint()!=null){
                                beanList.add(new Bean(tip.getName(),tip.getAddress(),tip.getPoint().getLatitude(),tip.getPoint().getLongitude()));
                            }
                        }
                        poiAdapter.notifyDataSetChanged();
                        aMap.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(tipList.get(0).getPoint().getLatitude(),tipList.get(0).getPoint().getLongitude()))); //设置地图中心点
                    }
                } else {
                    Toast.makeText(MainActivity.this, String.valueOf(rCode), Toast.LENGTH_SHORT).show();
                }
            }
        });
        inputTips.requestInputtipsAsyn();
    }

定位

    /**
     * 初始化定位
     **/
    private void initLocation(){
        if (aMap == null) {
            aMap = mMapView.getMap();
        }
        //设置定位蓝点
        MyLocationStyle myLocationStyle;
        myLocationStyle = new MyLocationStyle();
        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);//定位一次,且将视角移动到地图中心点。
        aMap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style

        //设置缩放级别
        aMap.moveCamera(CameraUpdateFactory.zoomTo(15));

        // 控件交互 缩放按钮、指南针、定位按钮、比例尺等
        UiSettings mUiSettings;//定义一个UiSettings对象
        mUiSettings = aMap.getUiSettings();//实例化UiSettings类对象
        mUiSettings.setZoomControlsEnabled(false);
        mUiSettings.setMyLocationButtonEnabled(true); //显示默认的定位按钮
        aMap.setMyLocationEnabled(true);// 可触发定位并显示当前位置
        mUiSettings.setScaleControlsEnabled(true);//控制比例尺控件是否显示
        mUiSettings.setLogoPosition(AMapOptions.LOGO_MARGIN_LEFT);//设置logo位置
    }
    /**
     * 开始定位
     **/
    private void startLocation() {
        try {
            //获取位置信息
            mLocationClient = new AMapLocationClient(this);
        }catch (Exception e){
            e.printStackTrace();
        }
        //初始化定位参数
        AMapLocationClientOption mLocationOption = new AMapLocationClientOption();
        //设置定位监听
        mLocationClient.setLocationListener(this);
        //设置定位模式为高精度模式,Battery_Saving为低功耗模式,Device_Sensors是仅设备模式
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        //获取一次定位结果
        mLocationOption.setOnceLocation(true);
        //获取最近3s内精度最高的一次定位结果
        mLocationOption.setOnceLocationLatest(true);
        //设置定位参数
        mLocationClient.setLocationOption(mLocationOption);
        //启动定位
        mLocationClient.startLocation();
    }

定位回调

    /**
     * 定位回调
     **/
    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        if (aMapLocation != null && aMapLocation.getErrorCode() == AMapLocation.LOCATION_SUCCESS) {
            LatLng latLng = new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude());
            setMapCenter(latLng);
            city = aMapLocation.getCity();
            aMap.animateCamera(CameraUpdateFactory.newLatLng(latLng)); //设置地图中心点
            mLocationClient.stopLocation();
            mLocationClient.onDestroy();
        }
    }

地图中心点

    /**
     * 设置中心点
     **/
    private void setMapCenter(LatLng latLng) {
        MarkerOptions markerOptions=new MarkerOptions()
                .icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
                        .decodeResource(getResources(),R.mipmap.location_center)))
                .position(latLng);
        if (marker!=null){
            marker.remove();
        }
        marker = aMap.addMarker(markerOptions);
        //坐标系转换,坐标信息转换为屏幕的中心点信息
        Point markerPoint = aMap.getProjection().toScreenLocation(latLng);
        marker.setFixingPointEnable(true);
        marker.setPositionByPixels(markerPoint.x, markerPoint.y);
        //marker动画
        Point point =  aMap.getProjection().toScreenLocation(latLng);
        point.y -= dip2px(this);
        LatLng target = aMap.getProjection().fromScreenLocation(point);
        //使用TranslateAnimation,填写一个需要移动的目标点
        Animation animation = new TranslateAnimation(target);
        animation.setInterpolator(new LinearInterpolator());
        long duration = 300;
        animation.setDuration(duration);
        animation.setInterpolator(new LinearInterpolator());

        marker.setAnimation(animation);
        marker.startAnimation();

    }
    /**
     * dip和px转换
     **/
    private static int dip2px(Context context) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) ((float) 30 * scale + 0.5f);
    }

地理编码和逆地理编码

	/**
     * 逆地理编码获取当前位置信息
     **/
    private void getGeocodeSearch(LatLng target) throws AMapException {
        if (geocoderSearch == null){
            geocoderSearch = new GeocodeSearch(this);
            geocoderSearch.setOnGeocodeSearchListener(this);
        }
        // 第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系
        RegeocodeQuery query = new RegeocodeQuery(new LatLonPoint(target.latitude, target.longitude), 500, GeocodeSearch.AMAP);
        query.setExtensions("all");
        geocoderSearch.getFromLocationAsyn(query);
    }
    /**
     * 地理编码
     **/
    private void searchLocation(String address) throws AMapException {
        if (geocoderSearch == null){
            geocoderSearch = new GeocodeSearch(this);
            geocoderSearch.setOnGeocodeSearchListener(this);
        }
        GeocodeQuery query=new GeocodeQuery(address,city);
        geocoderSearch.getFromLocationNameAsyn(query);
    }
    /**
     * 逆地理编码回调
     **/
    @Override
    public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
        if (i != 1000) return;
        beanList.clear();
        List<PoiItem> poiItems=regeocodeResult.getRegeocodeAddress().getPois();
        beanList.add(new Bean("当前位置",regeocodeResult.getRegeocodeAddress().getFormatAddress(),regeocodeResult.getRegeocodeQuery().getPoint().getLatitude(),regeocodeResult.getRegeocodeQuery().getPoint().getLongitude()));
        if (poiItems.size()!=0){
            for (PoiItem poiItem:poiItems){
                beanList.add(new Bean(poiItem.getTitle(),poiItem.getSnippet(),poiItem.getLatLonPoint().getLatitude(),poiItem.getLatLonPoint().getLongitude()));
            }
            poiAdapter.notifyDataSetChanged();
        }
    }
    /**
     * 地理编码回调
     **/
    @Override
    public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {
        if (geocodeResult!=null){
            List<GeocodeAddress> geocodeAddressList = geocodeResult.getGeocodeAddressList();
            if (geocodeAddressList!=null&&geocodeAddressList.size()!=0){
                GeocodeAddress address = geocodeAddressList.get(0);
            }
        }
    }

mapView生命周期

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

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

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mMapView.onDestroy();
        if (mLocationClient !=null){
            mLocationClient.onDestroy();
            mLocationClient =null;
        }
        if (geocoderSearch!=null){
            geocoderSearch=null;
        }
    }

MainActivity完整代码

package com.example.locationselect;

import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.os.Build;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.AMapOptions;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.MapView;
import com.amap.api.maps.MapsInitializer;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.maps.model.animation.Animation;
import com.amap.api.maps.model.animation.TranslateAnimation;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.geocoder.GeocodeAddress;
import com.amap.api.services.geocoder.GeocodeQuery;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.amap.api.services.help.Inputtips;
import com.amap.api.services.help.InputtipsQuery;
import com.amap.api.services.help.Tip;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements AMapLocationListener, GeocodeSearch.OnGeocodeSearchListener{
    private MapView mMapView;
    private AMap aMap;
    private AMapLocationClient mLocationClient;
    private PoiAdapter poiAdapter;
    private final List<Bean> beanList =new ArrayList<>();
    private Marker marker;
    private String city;
    private Bean selectBean;
    private GeocodeSearch geocoderSearch;
    private boolean flag=false;//条目点击标志位
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //隐私合规接口
        MapsInitializer.updatePrivacyShow(this,true,true);
        MapsInitializer.updatePrivacyAgree(this,true);

        mMapView=findViewById(R.id.mapView);
        ListView listView = findViewById(R.id.listView);
        EditText search = findViewById(R.id.et_search);
        mMapView.onCreate(savedInstanceState);
        aMap=mMapView.getMap();
        //地图移动监听
        aMap.setOnCameraChangeListener(new AMap.OnCameraChangeListener() {
            @Override
            public void onCameraChange(CameraPosition cameraPosition) {
            }

            @Override
            public void onCameraChangeFinish(CameraPosition cameraPosition) {

                if (!flag){
                    if (poiAdapter!=null){
                        poiAdapter.setSelectPosition(0);
                    }
                    try {
                        getGeocodeSearch(cameraPosition.target);
                        setMapCenter(cameraPosition.target);
                    } catch (AMapException e) {
                        throw new RuntimeException(e);
                    }
                    listView.smoothScrollToPosition(0);
                }
                flag=false;
            }
        });

        permission();

        poiAdapter = new PoiAdapter(beanList,this);
        listView.setAdapter(poiAdapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                poiAdapter.setSelectPosition(position);
                poiAdapter.notifyDataSetChanged();
                selectBean = beanList.get(position);
                flag=true;//当是点击地址条目触发的地图移动时,不进行逆地理解析
                aMap.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(selectBean.getLatitude(),selectBean.getLongitude()))); //设置地图中心点
            }
        });
        //搜索监听
        search.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (!TextUtils.isEmpty(s.toString())){
                    showTip(s.toString());
                }
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
    }
    /**
     * 搜索tip
     **/
    private void showTip(String input){
        InputtipsQuery inputQuery = new InputtipsQuery(input, city);
        Inputtips inputTips = new Inputtips(MainActivity.this, inputQuery);
        inputTips.setInputtipsListener(new Inputtips.InputtipsListener() {
            @Override
            public void onGetInputtips(List<Tip> tipList, int rCode) {
                if (rCode == AMapException.CODE_AMAP_SUCCESS) {// 正确返回
                    if (tipList.size()!=0){
                        beanList.clear();
                        for (Tip tip:tipList){
                            if (tip.getPoint()!=null){
                                beanList.add(new Bean(tip.getName(),tip.getAddress(),tip.getPoint().getLatitude(),tip.getPoint().getLongitude()));
                            }
                        }
                        poiAdapter.notifyDataSetChanged();
                        aMap.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(tipList.get(0).getPoint().getLatitude(),tipList.get(0).getPoint().getLongitude()))); //设置地图中心点
                    }
                } else {
                    Toast.makeText(MainActivity.this, String.valueOf(rCode), Toast.LENGTH_SHORT).show();
                }
            }
        });
        inputTips.requestInputtipsAsyn();
    }

    /**
     * 权限请求
     **/
    private void permission(){
        String[] permission;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            permission=new String[]{
                    Permission.ACCESS_COARSE_LOCATION,
                    Permission.ACCESS_FINE_LOCATION,
                    Permission.MANAGE_EXTERNAL_STORAGE,
                    Permission.READ_PHONE_STATE,
            };
        }
        else {
            permission=new String[]{
                    Permission.ACCESS_COARSE_LOCATION,
                    Permission.ACCESS_FINE_LOCATION,
                    Permission.READ_PHONE_STATE,
            };
        }
        XXPermissions.with(this)
                .permission(permission).request(new OnPermissionCallback() {
                    @Override
                    public void onGranted(@NonNull List<String> permissions, boolean allGranted) {
                        if (allGranted){
                            initLocation();
                            startLocation();
                        }
                        else {
                            Toast.makeText(MainActivity.this, "获取部分权限成功,但部分权限未正常授予", Toast.LENGTH_SHORT).show();
                        }
                    }
                    @Override
                    public void onDenied(@NonNull List<String> permissions, boolean doNotAskAgain) {
                        if (doNotAskAgain){
                            XXPermissions.startPermissionActivity(MainActivity.this,permissions);
                        }
                        else {
                            Toast.makeText(MainActivity.this, "权限获取失败", Toast.LENGTH_SHORT).show();
                        }
                    }
                });
    }
    /**
     * 初始化定位
     **/
    private void initLocation(){
        if (aMap == null) {
            aMap = mMapView.getMap();
        }
        //设置定位蓝点
        MyLocationStyle myLocationStyle;
        myLocationStyle = new MyLocationStyle();
        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);//定位一次,且将视角移动到地图中心点。
        aMap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style

        //设置缩放级别
        aMap.moveCamera(CameraUpdateFactory.zoomTo(15));

        // 控件交互 缩放按钮、指南针、定位按钮、比例尺等
        UiSettings mUiSettings;//定义一个UiSettings对象
        mUiSettings = aMap.getUiSettings();//实例化UiSettings类对象
        mUiSettings.setZoomControlsEnabled(false);
        mUiSettings.setMyLocationButtonEnabled(true); //显示默认的定位按钮
        aMap.setMyLocationEnabled(true);// 可触发定位并显示当前位置
        mUiSettings.setScaleControlsEnabled(true);//控制比例尺控件是否显示
        mUiSettings.setLogoPosition(AMapOptions.LOGO_MARGIN_LEFT);//设置logo位置
    }
    /**
     * 开始定位
     **/
    private void startLocation() {
        try {
            //获取位置信息
            mLocationClient = new AMapLocationClient(this);
        }catch (Exception e){
            e.printStackTrace();
        }
        //初始化定位参数
        AMapLocationClientOption mLocationOption = new AMapLocationClientOption();
        //设置定位监听
        mLocationClient.setLocationListener(this);
        //设置定位模式为高精度模式,Battery_Saving为低功耗模式,Device_Sensors是仅设备模式
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        //获取一次定位结果
        mLocationOption.setOnceLocation(true);
        //获取最近3s内精度最高的一次定位结果
        mLocationOption.setOnceLocationLatest(true);
        //设置定位参数
        mLocationClient.setLocationOption(mLocationOption);
        //启动定位
        mLocationClient.startLocation();
    }
    /**
     * 定位回调
     **/
    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        if (aMapLocation != null && aMapLocation.getErrorCode() == AMapLocation.LOCATION_SUCCESS) {
            LatLng latLng = new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude());
            setMapCenter(latLng);
            city = aMapLocation.getCity();
            aMap.animateCamera(CameraUpdateFactory.newLatLng(latLng)); //设置地图中心点
            mLocationClient.stopLocation();
            mLocationClient.onDestroy();
        }
    }
    /**
     * 设置中心点
     **/
    private void setMapCenter(LatLng latLng) {
        MarkerOptions markerOptions=new MarkerOptions()
                .icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
                        .decodeResource(getResources(),R.mipmap.location_center)))
                .position(latLng);
        if (marker!=null){
            marker.remove();
        }
        marker = aMap.addMarker(markerOptions);
        //坐标系转换,坐标信息转换为屏幕的中心点信息
        Point markerPoint = aMap.getProjection().toScreenLocation(latLng);
        marker.setFixingPointEnable(true);
        marker.setPositionByPixels(markerPoint.x, markerPoint.y);
        //marker动画
        Point point =  aMap.getProjection().toScreenLocation(latLng);
        point.y -= dip2px(this);
        LatLng target = aMap.getProjection().fromScreenLocation(point);
        //使用TranslateAnimation,填写一个需要移动的目标点
        Animation animation = new TranslateAnimation(target);
        animation.setInterpolator(new LinearInterpolator());
        long duration = 300;
        animation.setDuration(duration);
        animation.setInterpolator(new LinearInterpolator());

        marker.setAnimation(animation);
        marker.startAnimation();

    }
    /**
     * dip和px转换
     **/
    private static int dip2px(Context context) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) ((float) 30 * scale + 0.5f);
    }
    /**
     * 逆地理编码获取当前位置信息
     **/
    private void getGeocodeSearch(LatLng target) throws AMapException {
        if (geocoderSearch == null){
            geocoderSearch = new GeocodeSearch(this);
            geocoderSearch.setOnGeocodeSearchListener(this);
        }
        // 第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系
        RegeocodeQuery query = new RegeocodeQuery(new LatLonPoint(target.latitude, target.longitude), 500, GeocodeSearch.AMAP);
        query.setExtensions("all");
        geocoderSearch.getFromLocationAsyn(query);
    }
    /**
     * 地理编码
     **/
    private void searchLocation(String address) throws AMapException {
        if (geocoderSearch == null){
            geocoderSearch = new GeocodeSearch(this);
            geocoderSearch.setOnGeocodeSearchListener(this);
        }
        GeocodeQuery query=new GeocodeQuery(address,city);
        geocoderSearch.getFromLocationNameAsyn(query);
    }
    /**
     * 逆地理编码回调
     **/
    @Override
    public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
        if (i != 1000) return;
        beanList.clear();
        List<PoiItem> poiItems=regeocodeResult.getRegeocodeAddress().getPois();
        beanList.add(new Bean("当前位置",regeocodeResult.getRegeocodeAddress().getFormatAddress(),regeocodeResult.getRegeocodeQuery().getPoint().getLatitude(),regeocodeResult.getRegeocodeQuery().getPoint().getLongitude()));
        if (poiItems.size()!=0){
            for (PoiItem poiItem:poiItems){
                beanList.add(new Bean(poiItem.getTitle(),poiItem.getSnippet(),poiItem.getLatLonPoint().getLatitude(),poiItem.getLatLonPoint().getLongitude()));
            }
            poiAdapter.notifyDataSetChanged();
        }
    }
    /**
     * 地理编码回调
     **/
    @Override
    public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {
        if (geocodeResult!=null){
            List<GeocodeAddress> geocodeAddressList = geocodeResult.getGeocodeAddressList();
            if (geocodeAddressList!=null&&geocodeAddressList.size()!=0){
                GeocodeAddress address = geocodeAddressList.get(0);
            }
        }
    }
    @Override
    public void onPause() {
        super.onPause();
        mMapView.onPause();
    }

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

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mMapView.onDestroy();
        if (mLocationClient !=null){
            mLocationClient.onDestroy();
            mLocationClient =null;
        }
        if (geocoderSearch!=null){
            geocoderSearch=null;
        }
    }
}

地址适配器

package com.example.locationselect;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import java.util.List;

public class PoiAdapter extends BaseAdapter {
    private final List<Bean> poiItemList;
    private final Context context;
    private int selectPosition=0;
    public PoiAdapter(List<Bean> poiItemList, Context context) {
        this.poiItemList = poiItemList;
        this.context = context;
    }

    @Override
    public int getCount() {
        return poiItemList == null ? 0:poiItemList.size();
    }

    @Override
    public Object getItem(int position) {
        return poiItemList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            convertView = LayoutInflater.from(context).inflate(android.R.layout.simple_list_item_2, parent, false);
            holder = new ViewHolder();
            holder.text1 = convertView.findViewById(android.R.id.text1);
            holder.text2 = convertView.findViewById(android.R.id.text2);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        Bean bean=poiItemList.get(position);
        holder.text1.setText(bean.getName());
        holder.text2.setText(bean.getAddress());
        if (selectPosition == position){
            holder.text1.setTextColor(context.getColor(R.color.green));
            holder.text2.setTextColor(context.getColor(R.color.green));
        }
        else {
            holder.text1.setTextColor(context.getColor(R.color.black));
            holder.text2.setTextColor(context.getColor(R.color.black));
        }
        return convertView;
    }

    public void setSelectPosition(int selectPosition) {
        this.selectPosition = selectPosition;
    }

    static class ViewHolder {
        TextView text1,text2;
    }
}

Bean类

package com.example.locationselect;

import java.io.Serializable;

class Bean implements Serializable {
    private String name;
    private String address;
    private double latitude;
    private double longitude;

    public Bean(String name, String address, double latitude, double longitude) {
        this.name = name;
        this.address = address;
        this.latitude = latitude;
        this.longitude = longitude;
    }

    public String getName() {
        return name;
    }

    public String getAddress() {
        return address;
    }

    public double getLatitude() {
        return latitude;
    }

    public double getLongitude() {
        return longitude;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }
}

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

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

相关文章

alibabacloud学习笔记06(小滴课堂)

讲Sentinel流量控制详细操作 基于并发线程进行限流配置实操 在浏览器打开快速刷新会报错 基于并发线程进行限流配置实操 讲解 微服务高可用利器Sentinel熔断降级规则 讲解服务调用常见的熔断状态和恢复 讲解服务调用熔断例子 我们写一个带异常的接口&#xff1a;

centos7部署nfs+keepalived+drbd

一、项目需求描述 现在使用的架构是nfskeepalivedrsyncsersync&#xff0c;目前这套架构存在主从nfs节点数据同步不一致问题&#xff0c;大概会有 120s左右的数据延长同步时间&#xff0c;需要提供优化的自动化方案。 二、现有方案缺点 1、切换不能保证主从节点数据一致。 2、…

C++——基础语法(1)

前言 一路磕磕绊绊&#xff0c;也算是走到了C的大门下。C从名字上就可以看出是C语言的“plusplus版本”&#xff0c;C在兼容C语言的基础上又加入了许多方便又高深的特性与机制&#xff0c;便于我们更容易处理C语言中的棘手问题。不得不提的一点是C为我们打开了面向对象思想的大…

【ACM出版】第五届计算机信息和大数据应用国际学术会议(CIBDA 2024)

第五届计算机信息和大数据应用国际学术会议&#xff08;CIBDA 2024&#xff09; 2024 5th International Conference on Computer Information and Big Data Applications 重要信息 大会官网&#xff1a;www.ic-cibda.org 大会时间&#xff1a;2024年3月22-24日 大会地点&#…

Java中哪些很容易出现的坑

文章目录 1空指针2小数的计算3包装类型4Java8 Stream5日期格式化 先来一个简单一点&#xff0c;就从空指针开始吧 1空指针 //多级调用空指针userService.getUser("张三").getUserInfo().getUserName(); //例如getUser("张三")、getUserInfo&#xff08;&a…

基于SpringBoot的景区旅游管理系统

项目介绍 本期给大家介绍一个 景区旅游管理 系统.。主要模块有首页&#xff0c;旅游路线&#xff0c;旅行攻略&#xff0c;在线预定。管理员可以登录管理后台对用户进行管理&#xff0c;可以添加酒店&#xff0c;景区&#xff0c;攻略&#xff0c;路线等信息。整体完成度比较高…

【Java面试系列】JDK 1.8 新特性之 Stream API

目录 一、Stream 简介二、Stream 特点&#xff1a;Stream 注意点&#xff1a;1、什么是聚合操作2、Stream 流1、什么是流2、流的构成3、stream 流的两种操作4、惰性求值和及早求值方法5、Stream 流的并行 三、Stream操作的三个步骤1、创建流第一种&#xff1a;通过集合第二种&a…

2024全球网络安全展望|构建协同生态,护航数字经济

2024年1月&#xff0c;世界经济论坛发布《2024全球网络安全展望》报告&#xff0c;指出在科技快速发展的背景下&#xff0c;网络安全不均衡问题加剧&#xff0c;需加强公共部门、企业组织和个人的合作。 报告强调&#xff0c;面对地缘政治动荡、技术不确定性和全球经济波动&am…

Vue知识学习

Vue 是什么&#xff1f; 概念&#xff1a;Vue 是一个用于构建用户界面的渐进式框架 Vue 的两种使用方式: ① Vue 核心包开发 场景:局部 模块改造 ② Vue 核心包& Vue插件工程化开发 场景:整站开发 创建Vue 实例&#xff0c;初始化渲染的核心步骤: 1.准备容器 2.引包(官…

哪些软件可以把试卷照片转换成电子版?试试这些软件

哪些软件可以把试卷照片转换成电子版&#xff1f;在数字化时代&#xff0c;纸质试卷的保存和传输都显得不太方便。为了解决这个问题&#xff0c;我们可以将试卷照片转换成电子版。下面&#xff0c;我将为大家介绍5款可以轻松实现这一功能的软件&#xff0c;让你轻松应对各种试卷…

吸虫塔的工作原理是什么?

吸虫塔虫情智能测报分析系统是一款专门用于长期动态监测蚜虫等小型迁飞性害虫的大型植保设备&#xff0c;由装置上方的空气动力装置、上下两层远红外虫体处理装置、高清图像采集装置、虫体收集装置等部分组成。昆虫在经由设备上方的吸风装置后会被吸入设备内部&#xff0c;上下…

【超实用!游戏主程必须掌握的必杀技!】

超实用&#xff01;游戏主程必须掌握的必杀技&#xff01; 大家有没有发现&#xff1f;以上问题都存在共性&#xff1a;那就是跨部门的沟通与协作&#xff0c;这是一个必须高度重视的问题。正是因为这些问题的存在&#xff0c;造成初入职场的焦虑和不适应。 那么产生这些问题的…

【大厂AI课学习笔记】【2.2机器学习开发任务实例】(1)搭建一个机器学习模型

今天学习的是&#xff0c;如何搭建一个机器学习模型。 主要有以上的步骤&#xff1a; 原始数据采集特征工程 数据预处理特征提取特征转换&#xff08;构造&#xff09;预测识别&#xff08;模型训练和测试&#xff09; 在实际工作中&#xff0c;特征比模型更重要。 数据和特征…

01_02_mysql06_(视图-存储过程-函数(变量、流程控制与游标)-触发器)

视图 使用 视图一方面可以帮我们使用表的一部分而不是所有的表&#xff0c;另一方面也可以针对不同的用户制定不同的查询视图。比如&#xff0c;针对一个公司的销售人员&#xff0c;我们只想给他看部分数据&#xff0c;而某些特殊的数据&#xff0c;比如采购的价格&#xff0…

flink 任务提交流程源码解析

flinkjob 提交流程 任务启动流程图1客户端的工作内容1.1解析命令1.2 执行用户代码 2集群工作内容2.2启动JobManager和 ResourceManager2.3 申请资源 启动 taskmanager 3分配任务3.1 资源计算3.2 分发任务 4 Task 任务调度执行图5 任务提交过程总结 任务启动流程图 可以先简单看…

【Vue3】toRefs和toRef在reactive中的一些应用

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

如何在debian上实现一键恢复操作系统?

在Debian或任何其他Linux发行版上实现一键恢复操作系统&#xff0c;需要创建一个系统镜像或快照&#xff0c;并设置一个简单的方法来从该镜像恢复。以下是创建和恢复系统的基本步骤&#xff1a; 1. 创建系统镜像&#xff1a; 使用像dd&#xff0c;rsync或专门的备份工具&#…

详细分析UML的10种图(全)

目录 前言1. 基本知识2. 结构图2.1 类图2.2 对象图2.3 组件图2.4 部署图2.5 包图 3. 行为图3.1 用例图3.2 活动图3.3 状态图 4. 行为图4.1 顺序图4.2 协作图 前言 在软考高级中常见的一种题型&#xff0c;对此补充这方面的知识&#xff0c;并将其归入软考的专栏 1. 基本知识 …

全网最最最详细DataEase源码Docker方式部署教程

1.源码获取 有条件的小伙伴可以使用GitHub方式获取&#xff0c;要是没有条件的小伙伴可以去码云上面获取也是一样的&#xff0c;或者可以联系博主&#xff0c;博主手把手教学~ GitHub地址 Gitee地址 2.配置源码信息 1.配置单机版的配置文件中的数据库信息 2.下载前端的依赖包…

顺序表经典算法及其相关思考

27. 移除元素 - 力扣&#xff08;LeetCode&#xff09; 思路一 利用顺序表中的SLDestroy函数的思想&#xff0c;遇到等于val值的就挪动 思路二 双指针法&#xff1a;不停的将和val不相等的数字往前放。此时的des更像一个空数组&#xff0c;里面存放的都是和val不相等、能够存…