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

先上演示:

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

依赖引入

项目使用了如下依赖:

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

配置清单

swift 复制代码
	<!--允许访问网络,必选权限-->
    <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:

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

代码部分

页面布局

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

swift 复制代码
<?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

swift 复制代码
<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

隐私合规

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

swift 复制代码
//隐私合规接口
MapsInitializer.updatePrivacyShow(this,true,true);
MapsInitializer.updatePrivacyAgree(this,true);

权限申请

swift 复制代码
    /**
     * 权限请求
     **/
    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进行初始化

swift 复制代码
        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搜索

swift 复制代码
    /**
     * 搜索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();
    }

定位

swift 复制代码
    /**
     * 初始化定位
     **/
    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();
    }

定位回调

swift 复制代码
    /**
     * 定位回调
     **/
    @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();
        }
    }

地图中心点

swift 复制代码
    /**
     * 设置中心点
     **/
    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);
    }

地理编码和逆地理编码

swift 复制代码
	/**
     * 逆地理编码获取当前位置信息
     **/
    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生命周期

swift 复制代码
    @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完整代码

swift 复制代码
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;
        }
    }
}

地址适配器

swift 复制代码
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类

swift 复制代码
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;
    }
}
相关推荐
恋猫de小郭1 小时前
Flutter 3.38 发布,快来看看有什么更新吧
android·前端·flutter
百锦再6 小时前
第11章 泛型、trait与生命周期
android·网络·人工智能·python·golang·rust·go
会跑的兔子7 小时前
Android 16 Kotlin协程 第二部分
android·windows·kotlin
键来大师7 小时前
Android15 RK3588 修改默认不锁屏不休眠
android·java·framework·rk3588
江上清风山间明月10 小时前
Android 系统超级实用的分析调试命令
android·内存·调试·dumpsys
百锦再10 小时前
第12章 测试编写
android·java·开发语言·python·rust·go·erlang
用户693717500138414 小时前
Kotlin 协程基础入门系列:从概念到实战
android·后端·kotlin
SHEN_ZIYUAN14 小时前
Android 主线程性能优化实战:从 90% 降至 13%
android·cpu优化
曹绍华15 小时前
android 线程loop
android·java·开发语言
雨白15 小时前
Hilt 入门指南:从 DI 原理到核心用法
android·android jetpack