精华内容
下载资源
问答
  • 腾讯位置服务仿微信发送位置功能
    2020-08-03 11:52:14

    以下内容转载自面糊的文章《模仿微信发送位置功能》

    作者:面糊

    链接:https://www.jianshu.com/p/47b3ada2e36d

    来源:简书

    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    前言

    微信的发送位置功能是一个十分方便的功能,他会定位用户当前所在地点,然后请求用户周边的POI,并且还可以通过拖动地图来获取其他的位置发送给对方,本Demo是结合腾讯地图SDK来实现类似的功能。

    使用场景

    拖动地图选择地图的中心点,然后请求该点周边的门店信息,可以通过设置搜索分类来指定搜索门店的类型,如:美食、学校等。

    准备

    核心代码:

    1、设置大头针,固定在地图中央,并监听地图移动的时候大头针跟随移动:

    - (void)mapViewRegionChange:(QMapView *)mapView {
        // 更新位置
        _annotation.coordinate = mapView.centerCoordinate;
    }
    

    2、配置周边检索功能,将检索类型设置为"美食":

    - (void)searchCurrentLocationWithKeyword:(NSString *)keyword {
    CLLocationCoordinate2D centerCoord = self.mapView.centerCoordinate;
    
        QMSPoiSearchOption *option = [[QMSPoiSearchOption alloc] init];
        if (keyword.length > 0) {
            option.keyword = keyword;
        }
        option.boundary = [NSString stringWithFormat:@"nearby(%f,%f,2000,1)", centerCoord.latitude, centerCoord.longitude];
        [option setFilter:@"category=美食"];
        [self.mapSearcher searchWithPoiSearchOption:option];
    }
    

    3、解析检索结果,移动地图视野,并将结果显示在tableView上:

    - (void)searchWithPoiSearchOption:(QMSPoiSearchOption *)poiSearchOption didReceiveResult:(QMSPoiSearchResult *)poiSearchResult {
        NSLog(@"%@", poiSearchResult);
    
        if (poiSearchResult.count == 0) {
            return;
        }
    
        // 地图移动到搜索结果的第一个位置
        if (_searchBar.text.length > 0) {
            _selectedIndex = 0;
            QMSPoiData *firstData = poiSearchResult.dataArray[0];
            _annotation.coordinate = firstData.location;
            [self.mapView setCenterCoordinate:firstData.location animated:YES];
        } else {
            _selectedIndex = -1;
        }
    
        _searchResultArray = poiSearchResult.dataArray;
        [_searchResultTableView reloadData];
    }
    

    以上就是核心代码,在Demo中还添加了用于显示地址的TableView以及搜索位置的SearchBar,有兴趣的同学可以在文章最下方进入码云下载完整示例。

    示例:搜索西二旗地铁附近的美食

    在这里插入图片描述

    链接

    感兴趣的同学可以在码云中下载Demo尝试一下。

    更多相关内容
  • Android仿微信发送位置
  • 本篇文章主要介绍了Android高德地图poi检索仿微信发送位置实例代码,具有一定的参考价值,有兴趣的可以了解一下。
  • 仿微信发送位置

    2016-11-02 18:29:02
    仿微信发送位置 使用高德地图实现
  • 使用百度地图API,高仿微信定位。使用技术: * 百度地图的基础定位、基础地图和检索功能 * android6.0以上运行时权限
  • 最近项目中有个需求是仿微信发送位置界面,我选择了使用腾讯地图,毕竟都是腾讯的应该好仿出来,之前用百度地图实现过,不过觉得百度有点麻烦。
  • Android版仿微信发送位置、地图选点(百度地图)
  • Kotlin 高德地图 仿微信 发送位置
  • Android版仿微信发送位置、地图选点(高德地图). 前面上传过一个百度地图的, 这个也一起上传吧(捞点分, 现在下载都强制需要资源分), Key请自行申请, demo包含一个可运行apk和源码.
  • Android 仿微信发送微信Demo Android Studio编译
  • 最近项目中要写一个微信那种发送位置的功能。具体功能在于: – 定位到当前位置 – 可定位当前位置附近的Poi – 可自行搜索目标位置,并展示附近的poi – 选择当前位置或者选择目标位置进行发送 一.准备工作 1....
  • Android百度地图仿微信发送位置

    千次阅读 2020-06-18 11:01:52
    主要功能(参照微信发送定位): 1.定位所在位置并且展示周边POI(建筑物等信息); 2.拖拽地图完成,返回中心覆盖物所处位置周边的POI信息; 3.支持关键词等搜索,每次搜索完成,中央覆盖物移动到第一条POI信息的相应...

    先上图
    地图

    前提:有百度地图账号并配置了相关环境,可以参考百度地图开发者文档并下载so和jar
    百度地图jar导入
    代码有相对应的注释,关键的就是百度地图移动版开发密钥、正确填写SHA1 和 程序包名,这将影响百度地图的功能使用

    主要功能(参照微信发送定位):
    1.定位所在位置并且展示周边POI(建筑物等信息);
    2.拖拽地图完成,返回中心覆盖物所处位置周边的POI信息;
    3.支持关键词等搜索,每次搜索完成,中央覆盖物移动到第一条POI信息的相应位置;
    4.点击定位的图标,中央覆盖物回到所定位的位置;
    5.点击下边列表的某条数据,将中央覆盖物移至该条数据对应的位置;
    6.发送定位时,有相应的地图位置截图和地址信息.
    ————————————————

    核心代码

    //点击地图的监听,并显示所点击位置周围的poi信息
            mBaiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
                @Override
                public void onMapClick(LatLng latLng) {
                    mBaiduMap.clear();
                    adapter.changeSelected(0);
                    mJARecyclerView.smoothScrollToPosition(0);
                    MapStatusUpdate u = MapStatusUpdateFactory
                            .newLatLng(latLng);
                    mBaiduMap.animateMapStatus(u);
                    isUseGeoCoder = true;
                }
    
                @Override
                public boolean onMapPoiClick(MapPoi mapPoi) {
                    LatLng position = mapPoi.getPosition();
                    mBaiduMap.clear();
                    MapStatusUpdate u = MapStatusUpdateFactory
                            .newLatLng(position);
                    mBaiduMap.animateMapStatus(u);
                    isUseGeoCoder = true;
                    return true;
    
                }
            });
    
    //移动地图的监听,并显示所点击位置周围的poi信息
            mBaiduMap.setOnMapTouchListener(new BaiduMap.OnMapTouchListener() {
                @Override
                public void onTouch(MotionEvent motionEvent) {
                    if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
                        isUseGeoCoder = true;
                        isNeedAnimation = true;
                    }
                }
            });
    
    //地图状态发生改变的监听,不管是点击还是移动地图,都会触发状态改变的监听,处理位置居中显示,开启动画,反地理编码(根据坐标获取位置名称、地址等信息)
            mBaiduMap.setOnMapStatusChangeListener(new BaiduMap.OnMapStatusChangeListener() {
                @Override
                public void onMapStatusChangeStart(MapStatus mapStatus) {
                }
    
                @Override
                public void onMapStatusChangeStart(MapStatus mapStatus, int i) {
                }
    
                @Override
                public void onMapStatusChange(MapStatus mapStatus) {
                }
    
                @Override
                public void onMapStatusChangeFinish(MapStatus mapStatus) {
                    mBaiduMap.clear();
                    if (isNeedAnimation) {
                        centerImage.startAnimation(centerAnimation);
                    }
                    LatLng target = mapStatus.target;
                    if (isUseGeoCoder) {
                        showLoading(true);
                        mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption())
                                .location(target));
                        adapter.changeSelected(0);
                        mJARecyclerView.smoothScrollToPosition(0);
                    }
                }
            });
    

    完整代码:
    SelectAddressActivity.class

    package com.lyw.myproject.baidumap.cityselect;
    import android.content.Context;
    import android.graphics.Point;
    import android.os.Bundle;
    import android.text.Editable;
    import android.text.Spannable;
    import android.text.SpannableStringBuilder;
    import android.text.TextWatcher;
    import android.text.style.ForegroundColorSpan;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.animation.Animation;
    import android.view.animation.AnimationUtils;
    import android.view.animation.LinearInterpolator;
    import android.view.animation.RotateAnimation;
    import android.view.inputmethod.InputMethodManager;
    import android.widget.EditText;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    import android.widget.Toast;
    import com.baidu.location.BDLocation;
    import com.baidu.location.BDLocationListener;
    import com.baidu.location.LocationClient;
    import com.baidu.location.LocationClientOption;
    import com.baidu.mapapi.map.BaiduMap;
    import com.baidu.mapapi.map.MapPoi;
    import com.baidu.mapapi.map.MapStatus;
    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.map.offline.MKOLSearchRecord;
    import com.baidu.mapapi.map.offline.MKOfflineMap;
    import com.baidu.mapapi.map.offline.MKOfflineMapListener;
    import com.baidu.mapapi.model.LatLng;
    import com.baidu.mapapi.search.core.PoiInfo;
    import com.baidu.mapapi.search.core.SearchResult;
    import com.baidu.mapapi.search.geocode.GeoCodeResult;
    import com.baidu.mapapi.search.geocode.GeoCoder;
    import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
    import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
    import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
    import com.baidu.mapapi.search.sug.OnGetSuggestionResultListener;
    import com.baidu.mapapi.search.sug.SuggestionResult;
    import com.baidu.mapapi.search.sug.SuggestionSearch;
    import com.baidu.mapapi.search.sug.SuggestionSearchOption;
    import com.lyw.myproject.BaseActivity;
    import com.lyw.myproject.BuildConfig;
    import com.lyw.myproject.R;
    import com.lyw.myproject.adapter.AddressSelectAdapter;
    import com.lyw.myproject.utils.PermissionUtil;
    import com.lyw.myproject.utils.StatusBarUtils;
    import com.lyw.myproject.widget.DefaultItemDecoration;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import androidx.annotation.Nullable;
    import androidx.recyclerview.widget.LinearLayoutManager;
    import androidx.recyclerview.widget.RecyclerView;
    
    /**
     * 功能描述:地址选择
     * Created on 2020/6/17.
     * @author  lyw
     */
    public class SelectAddressActivity extends BaseActivity implements AddressSelectAdapter.OnAddressSelectItemClickListener{
        private RecyclerView mJARecyclerView;
        private TextView cancleTv,searchAddressTv,confirmTv,searchNoDataTv;
        private MapView mBmapView;
        private EditText mSearchAddressEt;
        private LinearLayout searchNoDataLayout,searchNonmalLayout,searchEditLayout;
        private ImageView centerImage,locationIv,clearInputIv,mCheckTipIv;
    
        private BaiduMap mBaiduMap;
        private LocationClient mLocationClient;
        //是否首次定位
        boolean isFirstLoc = true;
        private AddressSelectAdapter adapter;
        private List<PoiInfo> mFilterList = new ArrayList<>();
        //选择的位置信息
        private PoiInfo selPoiDetailInfo;
        // 当前经纬度
        double mLantitude;
        double mLongtitude;
        LatLng mLoactionLatLng;
        // MapView中央对于的屏幕坐标
        Point mCenterPoint = null;
        // 地理编码
        GeoCoder mGeoCoder = null;
        List<PoiInfo> mInfoList;
        PoiInfo mCurentInfo;
        MyBDLocationListner mListner = null;
        private Animation centerAnimation;
        //是否使用反地理编码
        private boolean isUseGeoCoder = true;
        //是否需要动画
        private boolean isNeedAnimation = true;
        private InputMethodManager inputMethodManager;
        private SuggestionSearch mSuggestionSearch;
        private String changeContent;
        private MKOfflineMap mOffline;
        //选中的CityCode
        private String selectCityCode;
        private ArrayList<MKOLSearchRecord> mkolSearchRecords;
        private RotateAnimation mAnimation;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main_activity_address_select_layout);
            FullscreenInputWorkaroundUtil.assistActivity(this);
            //设置状态栏透明
            StatusBarUtils.makeStatusBarTransparent(SelectAddressActivity.this);
            //请求位置权限
            if (!PermissionUtil.isHasLocationPermission(this)) {
                PermissionUtil.requestLocationPermission(this);
            }
            initView();
            initEvent();
            inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            //得到城市code
            mOffline = new MKOfflineMap();
            mOffline.init(new MKOfflineMapListener() {
                @Override
                public void onGetOfflineMapState(int i, int i1) {
    
                }
            });
        }
    
        @Override
        public void onResume() {
            super.onResume();
            if (mBmapView != null) {
                mBmapView.onResume();
            }
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            if (mBmapView != null) {
                mBmapView.onPause();
            }
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            if (mBmapView != null) {
                mBmapView.onDestroy();
            }
            mBaiduMap.setMyLocationEnabled(false);
            if (mLocationClient != null) {
                mLocationClient.stop();
            }
            if (mGeoCoder != null) {
                mGeoCoder.destroy();
            }
            if (mSuggestionSearch != null) {
                mSuggestionSearch.destroy();
            }
            if (mOffline != null) {
                mOffline.destroy();
            }
        }
    
        private void initView() {
            mJARecyclerView = (RecyclerView)findViewById(R.id.recyclerview);
            cancleTv = (TextView)findViewById(R.id.cancle_tv);
            searchAddressTv = (TextView)findViewById(R.id.search_address_tv);
            confirmTv = (TextView)findViewById(R.id.confirm_tv);
            mBmapView = (MapView)findViewById(R.id.bmapView);
            mSearchAddressEt = (EditText)findViewById(R.id.search_address_et);
            searchNoDataTv = (TextView)findViewById(R.id.search_no_data_tv);
            searchNoDataLayout = (LinearLayout)findViewById(R.id.search_no_data_layout);
            searchNonmalLayout = (LinearLayout)findViewById(R.id.search_nonmal_layout);
            searchEditLayout = (LinearLayout)findViewById(R.id.search_edit_layout);
            centerImage = (ImageView)findViewById(R.id.center_image);
            locationIv = (ImageView)findViewById(R.id.location_iv);
            clearInputIv = (ImageView)findViewById(R.id.clear_input_iv);
            mCheckTipIv = (ImageView)findViewById(R.id.check_tip_iv);
        }
    
        private void initEvent() {
            mBaiduMap = mBmapView.getMap();
            adapter = new AddressSelectAdapter(this);
            adapter.setOnAddressSelectItemClickListener(this);
            mJARecyclerView.setLayoutManager(new LinearLayoutManager(this));
            mJARecyclerView.addItemDecoration(new DefaultItemDecoration(this, R.dimen.common_utils_divider_height, R.color.src_line_c9));
            mJARecyclerView.setAdapter(adapter);
            mSearchAddressEt.setHint("搜索地点");
            searchAddressTv.setText("搜索地点");
            mSearchAddressEt.addTextChangedListener(new SearchDevicesTextWatcher());
            cancleTv.setText("取消");
            confirmTv.setText("确定");
    
    
            //加载动画
            mAnimation = new RotateAnimation(0, 359, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            mAnimation.setDuration(1000);
            mAnimation.setRepeatCount(-1);
            mAnimation.setInterpolator(new LinearInterpolator());
            mCheckTipIv.setColorFilter(getResources().getColor(R.color.src_c1));
            mCheckTipIv.setImageResource(R.mipmap.icon_login_loading);
            centerAnimation = AnimationUtils.loadAnimation(this, R.anim.center_anim);
    
            initMyLocation();
            mBaiduMap.setCompassEnable(false);
    
    
            searchNonmalLayout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    searchNonmalLayout.setVisibility(View.GONE);
                    searchEditLayout.setVisibility(View.VISIBLE);
                    showInput(mSearchAddressEt);
                }
            });
    
            clearInputIv.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    searchNonmalLayout.setVisibility(View.VISIBLE);
                    searchEditLayout.setVisibility(View.GONE);
                    mSearchAddressEt.setText("");
                    mSearchAddressEt.clearFocus();
                    hideSoftInputWindow(v);
                    mFilterList.clear();
                    if (mLoactionLatLng != null) {
                        MapStatus.Builder builder = new MapStatus.Builder();
                        builder.target(mLoactionLatLng).zoom(17.0f);
                        mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus
                                (builder.build()));
                        isUseGeoCoder = true;
                        isNeedAnimation = false;
                    } else {
                    }
                }
            });
    
            locationIv.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mLoactionLatLng != null) {
                        MapStatus.Builder builder = new MapStatus.Builder();
                        builder.target(mLoactionLatLng).zoom(17.0f);
                        mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus
                                (builder.build()));
                        isUseGeoCoder = true;
                        isNeedAnimation = true;
                    } else {
                    }
                }
            });
        }
    
        /**
         * 隐藏键盘
         */
        private void hideSoftInputWindow(View view) {
            if (inputMethodManager.isActive()) {
                inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
            }
        }
    
        /**
         * 显示键盘
         * @param et 输入焦点
         */
        public void showInput(final EditText et) {
            et.requestFocus();
            if (inputMethodManager.isActive()) {
                inputMethodManager.showSoftInput(et, InputMethodManager.SHOW_IMPLICIT);
            }
        }
    
        /**
         * 获取我的定位
         */
        private void initMyLocation() {
            // 初始化地图
            mBmapView.showZoomControls(false);
            MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(17.0f);
            mBaiduMap.setMapStatus(msu);
            mInfoList = new ArrayList<PoiInfo>();
            mCenterPoint = mBaiduMap.getMapStatus().targetScreen;
            mLoactionLatLng = mBaiduMap.getMapStatus().target;
    
            // 定位
            mBaiduMap.setMyLocationEnabled(true);
            mLocationClient = new LocationClient(this);
            mListner = new MyBDLocationListner();
            mLocationClient.registerLocationListener(mListner);
            LocationClientOption option = new LocationClientOption();
            option.setCoorType("bd09ll");
            mLocationClient.setLocOption(option);
            mLocationClient.start();
    
            // 地理编码
            mGeoCoder = GeoCoder.newInstance();
            mGeoCoder.setOnGetGeoCodeResultListener(mGeoListener);
    
            showLoading(true);
    
            mBaiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
                @Override
                public void onMapClick(LatLng latLng) {
                    mBaiduMap.clear();
                    adapter.changeSelected(0);
                    mJARecyclerView.smoothScrollToPosition(0);
                    MapStatusUpdate u = MapStatusUpdateFactory
                            .newLatLng(latLng);
                    mBaiduMap.animateMapStatus(u);
                    isUseGeoCoder = true;
                }
    
                @Override
                public boolean onMapPoiClick(MapPoi mapPoi) {
                    LatLng position = mapPoi.getPosition();
                    mBaiduMap.clear();
                    MapStatusUpdate u = MapStatusUpdateFactory
                            .newLatLng(position);
                    mBaiduMap.animateMapStatus(u);
                    isUseGeoCoder = true;
                    return true;
    
                }
            });
    
    
            mBaiduMap.setOnMapTouchListener(new BaiduMap.OnMapTouchListener() {
                @Override
                public void onTouch(MotionEvent motionEvent) {
                    if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
                        isUseGeoCoder = true;
                        isNeedAnimation = true;
                    }
                }
            });
    
            mBaiduMap.setOnMapStatusChangeListener(new BaiduMap.OnMapStatusChangeListener() {
                @Override
                public void onMapStatusChangeStart(MapStatus mapStatus) {
                }
    
                @Override
                public void onMapStatusChangeStart(MapStatus mapStatus, int i) {
                }
    
                @Override
                public void onMapStatusChange(MapStatus mapStatus) {
                }
    
                @Override
                public void onMapStatusChangeFinish(MapStatus mapStatus) {
                    mBaiduMap.clear();
                    if (isNeedAnimation) {
                        centerImage.startAnimation(centerAnimation);
                    }
                    LatLng target = mapStatus.target;
                    if (isUseGeoCoder) {
                        showLoading(true);
                        mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption())
                                .location(target));
                        adapter.changeSelected(0);
                        mJARecyclerView.smoothScrollToPosition(0);
                    }
                }
            });
            mSuggestionSearch = SuggestionSearch.newInstance();
            mSuggestionSearch.setOnGetSuggestionResultListener(listener);
        }
    
    
        OnGetSuggestionResultListener listener = new OnGetSuggestionResultListener() {
            @Override
            public void onGetSuggestionResult(SuggestionResult suggestionResult) {
                //处理sug检索结果
                List<SuggestionResult.SuggestionInfo> allSuggestions = suggestionResult.getAllSuggestions();
                mInfoList.clear();
                if (allSuggestions == null) {
    
                }else {
                    for (SuggestionResult.SuggestionInfo suggestionInfo : allSuggestions) {
                        if (suggestionInfo == null) {
                            continue;
                        }
                        PoiInfo info = new PoiInfo();
                        info.address = suggestionInfo.getKey();
                        LatLng pt = suggestionInfo.pt;
                        info.location = pt;
                        info.city = suggestionInfo.city;
                        info.name = suggestionInfo.getKey();
                        mInfoList.add(info);
                    }
                    selPoiDetailInfo = mInfoList.get(0);
                    mkolSearchRecords = mOffline.searchCity(selPoiDetailInfo.getCity());
                    selectCityCode = String.valueOf(mkolSearchRecords.get(0).cityID);
                }
                handleRelativeAddressResult(mInfoList, changeContent);
            }
        };
    
        @Override
        public void onAddressSelectItemClick(PoiInfo info, int position) {
            isUseGeoCoder = false;
            isNeedAnimation = true;
            mBaiduMap.clear();
            LatLng la = info.location;
            MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(la);
            mBaiduMap.animateMapStatus(u);
            selPoiDetailInfo = info;
            adapter.changeSelected(position);
            if (position != 0) {
                mkolSearchRecords = mOffline.searchCity(selPoiDetailInfo.getCity());
                selectCityCode = String.valueOf(mkolSearchRecords.get(0).cityID);
            }
            if (BuildConfig.DEBUG) {
                Log.d("lyw", "onAddressSelectItemClick-cityCode->" + info.city+selectCityCode);
            }
        }
    
    
        // 定位监听器
        private class MyBDLocationListner implements BDLocationListener {
            @Override
            public void onReceiveLocation(BDLocation location) {
                if (location == null || mBmapView == null){
                    return;
                }
                if (isFirstLoc) {
                    MyLocationData data = new MyLocationData.Builder()
                            .accuracy(location.getRadius())
                            .latitude(location.getLatitude())
                            .longitude(location.getLongitude())
                            .build();
                    mBaiduMap.setMyLocationData(data);
                    MyLocationConfiguration config = new MyLocationConfiguration(
                            MyLocationConfiguration.LocationMode.NORMAL, false, null);
                    mBaiduMap.setMyLocationConfigeration(config);
                    mLantitude = location.getLatitude();
                    mLongtitude = location.getLongitude();
                    LatLng currentLatLng = new LatLng(mLantitude, mLongtitude);
                    mLoactionLatLng = new LatLng(mLantitude, mLongtitude);
                    isFirstLoc = false;
                    MapStatusUpdate u = MapStatusUpdateFactory
                            .newLatLng(currentLatLng);
                    mBaiduMap.animateMapStatus(u);
                    mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption())
                            .location(currentLatLng));
                }
            }
        }
    
        /**
         * 地理编码监听器
         */
        OnGetGeoCoderResultListener mGeoListener = new OnGetGeoCoderResultListener() {
            @Override
            public void onGetGeoCodeResult(GeoCodeResult result) {
            }
    
            @Override
            public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
                if (BuildConfig.DEBUG) {
                    Log.d("lyw","result.error-->" + result.error);
                }
                if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
                    if (result.error == SearchResult.ERRORNO.NETWORK_ERROR) {
                        showLoading(false);
                        Toast.makeText(SelectAddressActivity.this,"网络异常",Toast.LENGTH_SHORT).show();
                    }
                } else {
                    showLoading(false);
                    mCurentInfo = new PoiInfo();
                    mCurentInfo.address = result.getAddress();
                    mCurentInfo.location = result.getLocation();
                    mCurentInfo.name = result.getAddress();
                    mCurentInfo.city = String.valueOf(result.getCityCode());
                    selectCityCode = String.valueOf(result.getCityCode());
                    mInfoList.clear();
                    mInfoList.add(mCurentInfo);
                    if (result.getPoiList() != null) {
                        mInfoList.addAll(result.getPoiList());
                    }
                    adapter.setPoiAddrList(mInfoList);
                    adapter.notifyDataSetChanged();
                    selPoiDetailInfo = mInfoList.get(0);
                }
            }
        };
    
    
        class SearchDevicesTextWatcher implements TextWatcher {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int start, int count, int before) {
            }
    
            @Override
            public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
                changeContent = charSequence.toString();
                if (changeContent != null && !changeContent.isEmpty() || !"".equals(changeContent)) {
                    mSuggestionSearch.requestSuggestion(new SuggestionSearchOption().city("中国").keyword(changeContent));
                }else {
                    if (mLoactionLatLng != null) {
                        MapStatus.Builder builder = new MapStatus.Builder();
                        builder.target(mLoactionLatLng).zoom(17.0f);
                        mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus
                                (builder.build()));
                        isUseGeoCoder = true;
                        isNeedAnimation = false;
                    } else {
                    }
                }
            }
    
            @Override
            public void afterTextChanged(Editable editable) {
            }
        }
    
        /**
         * 处理搜索地点结果
         *
         * @param mInfoList
         */
        private void handleRelativeAddressResult(List<PoiInfo> mInfoList, String content) {
            mJARecyclerView.setAdapter(adapter);
            adapter.setPoiAddrList(mInfoList);
            if (mInfoList.size() == 0) {
                searchNoDataLayout.setVisibility(View.VISIBLE);
                String formatContent = String.format("没有找到“%1$s”相关内容", content);
                SpannableStringBuilder builder = new SpannableStringBuilder(formatContent);
                ForegroundColorSpan blueSpan = new ForegroundColorSpan(getResources().getColor(R.color.src_text_c16));
                int start = formatContent.indexOf(content);
                int end = start + content.length();
                builder.setSpan(blueSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                searchNoDataTv.setText(builder);
            } else {
                searchNoDataLayout.setVisibility(View.GONE);
            }
        }
    
    
        /**
         * Loading的显示
         * @param isShowLoading
         */
        private void showLoading(final boolean isShowLoading){
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (isShowLoading) {
                        mCheckTipIv.setVisibility(View.VISIBLE);
                        mCheckTipIv.setImageResource(R.mipmap.icon_login_loading);
                        mCheckTipIv.setAnimation(mAnimation);
                        mCheckTipIv.getAnimation().start();
                    }else {
                        mCheckTipIv.clearAnimation();
                        mCheckTipIv.setVisibility(View.GONE);
                    }
                }
            });
        }
    }
    
    

    main_activity_address_select_layout.xml

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        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" />
    
        <ImageView
            android:layout_gravity="center"
            android:id="@+id/center_image"
            android:layout_width="40dp"
            android:layout_marginBottom="15dp"
            android:layout_height="40dp"
            android:src="@mipmap/icon_positioning" />
    
    
        <ImageView
            android:id="@+id/location_iv"
            android:layout_gravity="center|end"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_marginEnd="10dp"
            android:src="@mipmap/icon_map_locate" />
    
    
        <RelativeLayout
            android:background="@drawable/background_gradient"
            android:paddingTop="35dp"
            android:paddingBottom="40dp"
            android:paddingStart="10dp"
            android:paddingEnd="10dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <TextView
                android:id="@+id/cancle_tv"
                android:textColor="@color/src_white"
                android:gravity="center"
                android:layout_width="60dp"
                android:layout_height="30dp"/>
            <TextView
                android:id="@+id/confirm_tv"
                android:layout_alignParentEnd="true"
                android:background="@color/src_c46"
                android:gravity="center"
                android:textColor="@color/src_white"
                android:layout_width="60dp"
                android:layout_height="30dp"/>
        </RelativeLayout>
    
    
        <LinearLayout
            android:orientation="vertical"
            android:background="@color/common_utils_white"
            android:layout_gravity="bottom"
            android:layout_width="match_parent"
            android:layout_height="250dp">
    
            <LinearLayout
                android:id="@+id/search_nonmal_layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginStart="15dp"
                android:layout_marginTop="15dp"
                android:layout_marginEnd="15dp"
                android:layout_marginBottom="6dp"
                android:orientation="horizontal">
    
                <LinearLayout
                    android:gravity="center"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:background="@drawable/common_utils_shape_address_input_white_bg"
                    android:focusable="true"
                    android:focusableInTouchMode="true"
                    android:orientation="horizontal"
                    android:paddingTop="7dp"
                    android:paddingBottom="7dp">
    
                    <ImageView
                        android:layout_width="18dp"
                        android:layout_height="18dp"
                        android:layout_gravity="center_vertical"
                        android:layout_marginStart="13dp"
                        android:src="@mipmap/icon_search_1"/>
    
                    <TextView
                        android:layout_marginStart="10dp"
                        android:id="@+id/search_address_tv"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content">
    
                    </TextView>
                </LinearLayout>
    
            </LinearLayout>
    
            <!-- 搜索 -->
            <LinearLayout
                android:visibility="gone"
                android:id="@+id/search_edit_layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginStart="15dp"
                android:layout_marginTop="10dp"
                android:layout_marginEnd="15dp"
                android:layout_marginBottom="6dp"
                android:orientation="horizontal">
    
                <LinearLayout
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:background="@drawable/common_utils_shape_address_input_white_bg"
                    android:focusable="true"
                    android:focusableInTouchMode="true"
                    android:orientation="horizontal"
                    android:paddingTop="7dp"
                    android:paddingBottom="7dp">
    
                    <ImageView
                        android:layout_width="18dp"
                        android:layout_height="18dp"
                        android:layout_gravity="center_vertical"
                        android:layout_marginStart="13dp"
                        android:src="@mipmap/icon_search_1"/>
    
                    <EditText
                        android:id="@+id/search_address_et"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center_vertical"
                        android:layout_marginStart="17dp"
                        android:layout_weight="1"
                        android:background="@null"
                        android:maxLength="32"
                        android:maxLines="1"
                        android:singleLine="true"
                        android:textColor="@color/src_text_c1"
                        android:textColorHint="@color/src_text_c2"
                        android:textSize="@dimen/common_utils_font_14"/>
    
                    <ImageView
                        android:id="@+id/clear_input_iv"
                        android:layout_width="20dp"
                        android:layout_height="20dp"
                        android:layout_gravity="end|center_vertical"
                        android:layout_marginEnd="13dp"
                        android:src="@mipmap/icon_clear_enter_1"/>
                </LinearLayout>
    
            </LinearLayout>
    
            <androidx.recyclerview.widget.RecyclerView
                android:layout_below="@+id/search_devices_layout"
                android:id="@+id/recyclerview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="2dp" />
    
       
            <LinearLayout
                android:layout_below="@+id/search_devices_layout"
                android:layout_gravity="center"
                android:gravity="center"
                android:id="@+id/search_no_data_layout"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/common_utils_white"
                android:orientation="vertical"
                android:visibility="gone">
                <TextView
                    android:id="@+id/search_no_data_tv"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_horizontal"
                    android:layout_marginTop="20dp"
                    android:textColor="@color/src_text_c2"
                    android:textSize="14sp"/>
            </LinearLayout>
        </LinearLayout>
    
        <ImageView
            android:id="@+id/check_tip_iv"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_marginBottom="75dp"
            android:layout_gravity="center|bottom"
            android:src="@mipmap/icon_login_loading"
            />
    </FrameLayout>
    

    background_gradient.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <!--实现应用背景颜色渐变-->
        <gradient
            android:startColor="@color/src_nvr"
            android:endColor="@color/common_utils_transparent"
            android:angle="270"/>
    </shape>
    

    common_utils_shape_address_input_white_bg.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <solid  android:color="@color/baidu_serach_address_bg" />
        <stroke
            android:width="0.5dp"
            android:color="@color/common_utils_black_30_transparent" />
        <corners android:radius="5dp" />
    </shape>
    

    AddressSelectAdapter.class

    package com.lyw.myproject.adapter;
    
    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    
    import com.baidu.mapapi.search.core.PoiInfo;
    import com.lyw.myproject.R;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import androidx.annotation.NonNull;
    import androidx.recyclerview.widget.RecyclerView;
    
    
    /**
     * 功能描述:位置选择Adapter
     * Created on 2020/4/27.
     * @author lyw
     */
    public class AddressSelectAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
        public Context mContext;
        private List<PoiInfo> infoList;
        private OnAddressSelectItemClickListener mItemClickListener;
        private int selectedPosition = 0;// 选中的位置
    
        public AddressSelectAdapter(Context context) {
            mContext = context;
            infoList = new ArrayList<>();
        }
    
        public void changeSelected(int positon){
            if(positon != selectedPosition){
                selectedPosition = positon;
                notifyDataSetChanged();
            }
        }
    
    
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
            return new MyViewHolder(LayoutInflater.from(mContext).inflate(R.layout.main_item_poi_address,viewGroup,false));
        }
    
        @Override
        public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
            MyViewHolder hodler = (MyViewHolder) viewHolder;
            PoiInfo info = infoList.get(i);
            hodler.nameTv.setText(info.getName());
            hodler.addressTv.setText(info.getAddress());
    
            if (selectedPosition == i) {
                hodler.checkImageIv.setImageResource(R.mipmap.icon_select_address);
            }else {
                hodler.checkImageIv.setImageResource(0);
            }
        }
    
        @Override
        public int getItemCount() {
            return infoList.size();
        }
    
        class MyViewHolder extends RecyclerView.ViewHolder{
            TextView nameTv;
            TextView addressTv;
            ImageView checkImageIv;
            LinearLayout addressSelectItemLl;
    
            public MyViewHolder(@NonNull View itemView) {
                super(itemView);
                nameTv = (TextView)itemView.findViewById(R.id.name_tv);
                addressTv = (TextView)itemView.findViewById(R.id.address_tv);
                checkImageIv = (ImageView)itemView.findViewById(R.id.check_image_iv);
                addressSelectItemLl = (LinearLayout)itemView.findViewById(R.id.address_select_item_ll);
                addressSelectItemLl.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (mItemClickListener != null) {
                            int posotion = getAdapterPosition();
                            mItemClickListener.onAddressSelectItemClick(infoList.get(posotion), posotion);
                        }
                    }
                });
            }
        }
    
        public  void setPoiAddrList(List<PoiInfo> infos){
            infoList = infos;
        }
    
        public  void clearPoiAddrList(){
            infoList.clear();
        }
    
    
        public interface OnAddressSelectItemClickListener{
            void onAddressSelectItemClick(PoiInfo info, int position);
        }
    
        public void setOnAddressSelectItemClickListener(OnAddressSelectItemClickListener listener){
            mItemClickListener = listener;
        }
    }
    
    

    main_item_poi_address.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/address_select_item_ll"
        android:layout_width="match_parent"
        android:padding="10dp"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
    
        <LinearLayout
            android:layout_marginStart="10dp"
            android:orientation="vertical"
            android:layout_width="0dp"
            android:layout_weight="10"
            android:layout_height="wrap_content">
            <TextView
                android:textSize="16sp"
                android:id="@+id/name_tv"
                android:textColor="@color/src_black"
                android:layout_width="wrap_content"
                android:layout_height="20dp"/>
            <TextView
                android:textSize="14sp"
                android:id="@+id/address_tv"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"/>
        </LinearLayout>
        <LinearLayout
            android:layout_gravity="center"
            android:layout_weight="1"
            android:layout_margin="5dp"
            android:layout_width="0dp"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/check_image_iv"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="20dp"/>
        </LinearLayout>
    </LinearLayout>
    

    DefaultItemDecoration.class

    package com.lyw.myproject.widget;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.view.View;
    
    import androidx.annotation.ColorRes;
    import androidx.annotation.DimenRes;
    import androidx.recyclerview.widget.RecyclerView;
    
    /**
     * Created on 2018/10/13.
     *
     * @author lyw
     **/
    public class DefaultItemDecoration extends RecyclerView.ItemDecoration {
        private int mDivideHeight;
        private int mPaddingLeft;
        private int mPaddingRight;
        private Paint paint;
    
        public DefaultItemDecoration(Context context, @DimenRes int divideHeight, @ColorRes int divideColor) {
            this(context, divideHeight, divideColor, 0, 0);
        }
    
        public DefaultItemDecoration(Context context, @DimenRes int divideHeight, @ColorRes int divideColor, @DimenRes int paddingLeft, @DimenRes int paddingRight) {
            mDivideHeight = context.getResources().getDimensionPixelSize(divideHeight);
            if (paddingRight != 0) {
                mPaddingRight = context.getResources().getDimensionPixelSize(paddingRight);
            }
    
            if (paddingLeft != 0) {
                mPaddingLeft = context.getResources().getDimensionPixelSize(paddingLeft);
            }
    
            paint = new Paint(Paint.ANTI_ALIAS_FLAG);
            paint.setColor(context.getResources().getColor(divideColor));
        }
    
        @Override
        public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
            super.onDraw(c, parent, state);
            int childCount = parent.getChildCount();
            int width = parent.getWidth();
    
            int top;
            int bottom;
            for (int i = 0; i < childCount; i++) {
                View childAt = parent.getChildAt(i);
                top = childAt.getBottom();
                bottom = top + mDivideHeight;
                c.drawRect(mPaddingLeft, top, width - mPaddingRight, bottom, paint);
            }
        }
    
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            super.getItemOffsets(outRect, view, parent, state);
            outRect.bottom = mDivideHeight;
        }
    }
    
    

    PermissionUtil.class

    package com.lyw.myproject.utils;
    
    import android.Manifest;
    import android.app.Activity;
    import android.content.Context;
    import android.content.pm.PackageManager;
    import android.os.Build;
    import androidx.core.app.ActivityCompat;
    
    /**
     * Created by lyw on 2017/6/12.
     */
    public class PermissionUtil {
        /**
         * 请求地理位置
         *
         * @param context
         */
        public static void requestLocationPermission(Context context) {
            if (Build.VERSION.SDK_INT >= 23) {
                if (!isHasLocationPermission(context)) {
                    ActivityCompat.requestPermissions((Activity) context, PermissionManager.PERMISSION_LOCATION, PermissionManager.REQUEST_LOCATION);
                }
            }
        }
    
        /**
         * 判断是否有地理位置
         *
         * @param context
         * @return
         */
        public static boolean isHasLocationPermission(Context context) {
            return ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
        }
    }
    
    

    PermissionManager.class

    package com.lyw.myproject.utils;
    
    import android.Manifest;
    
    /**
     * Created by lyw on 2017/5/17.
     */
    
    public final class PermissionManager {
    
        /**
         * sd卡
         */
        public static final int REQUEST_SD_WRITE = 101;
    
        /**
         * 地理位置
         */
        public static final int REQUEST_LOCATION = 102;
    
        /**
         * 相机
         */
        public static final int REQUEST_CAMERA = 103;
    
        /**
         * 录音
         */
        public static final int REQUEST_RECORD = 104;
    
        /**
         * 读取手机
         */
        public static final int REQUEST_READ_PHONE = 105;
    
        /**
         * 悬浮窗通知
         */
        public static final int REQUEST_ALERT_WINDOW = 106;
    
        /**
         * 读取MEDIA权限
         */
        public static final int REQUEST_READ_MEDIA = 107;
    
        /**
         * Android Q(10) 读取MEDIA权限
         */
        public static final String[] PERMISSION_READ_MEDIA = new String[]{"android.permission.READ_MEDIA_IMAGES","android.permission.READ_MEDIA_VIDEO","android.permission.READ_MEDIA_AUDIO"};
    
        public static final String[] PERMISSION_SD_WRITE = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
        public static final String[] PERMISSION_LOCATION = new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};
        public static final String[] PERMISSION_CAMERA = new String[]{Manifest.permission.CAMERA};
        public static final String[] PERMISSION_RECORD = new String[]{Manifest.permission.RECORD_AUDIO};
        public static final String[] PERMISSION_READ_PHONE = new String[]{Manifest.permission.READ_PHONE_STATE};
    
    }
    
    

    StatusBarUtils.class

    package com.lyw.myproject.utils;
    
    import android.app.Activity;
    import android.app.Dialog;
    import android.graphics.Color;
    import android.os.Build;
    import android.view.View;
    import android.view.Window;
    import android.view.WindowManager;
    
    /**
     * Created by Administrator on 2017/7/6.
     * 状态栏相关工具
     */
    
    public class StatusBarUtils {
    
        public static void setWindowStatusBarColor(Activity activity, int colorResId) {
            try {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    Window window = activity.getWindow();
                    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                    window.setStatusBarColor(activity.getResources().getColor(colorResId));
    
                    //底部导航栏
                    //window.setNavigationBarColor(activity.getResources().getColor(colorResId));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static void setWindowStatusBarColor(Dialog dialog, int colorResId) {
            try {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    Window window = dialog.getWindow();
                    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                    window.setStatusBarColor(dialog.getContext().getResources().getColor(colorResId));
    
                    //底部导航栏
                    //window.setNavigationBarColor(activity.getResources().getColor(colorResId));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static void makeStatusBarTransparent(Activity activity) {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
                return;
            }
            Window window = activity.getWindow();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                int option = window.getDecorView().getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
                window.getDecorView().setSystemUiVisibility(option);
                window.setStatusBarColor(Color.TRANSPARENT);
            } else {
                window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            }
        }
    }
    
    

    center_anim.xml

    <?xml version="1.0" encoding="utf-8"?>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="500"
        android:fillBefore="true"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:toXDelta="0"
        android:toYDelta="-100">
    
    </translate>
    

    FullscreenInputWorkaroundUtil.class

    package com.lyw.myproject.utils;
    
    import android.app.Activity;
    import android.graphics.Rect;
    import android.view.View;
    import android.view.ViewTreeObserver;
    import android.widget.FrameLayout;
    
    /**
     * 功能描述:解决状态栏沉浸式,软键盘遮住布局的问题
     * Created on 2020/6/18.
     *
     * @author lyw
     */
    public class FullscreenInputWorkaroundUtil {
        public static void assistActivity(Activity activity) {
            new FullscreenInputWorkaroundUtil(activity);
        }
    
        private View mChildOfContent;
        private int usableHeightPrevious;
        private FrameLayout.LayoutParams frameLayoutParams;
    
        private FullscreenInputWorkaroundUtil(Activity activity) {
            FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
            mChildOfContent = content.getChildAt(0);
            mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    possiblyResizeChildOfContent();
                }
            });
            frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
        }
    
        private void possiblyResizeChildOfContent() {
            int usableHeightNow = computeUsableHeight();
            if (usableHeightNow != usableHeightPrevious) {
                int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
                int heightDifference = usableHeightSansKeyboard - usableHeightNow;
                if (heightDifference > (usableHeightSansKeyboard / 4)) {
                    frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
                } else {
                    frameLayoutParams.height = usableHeightSansKeyboard;
                }
                mChildOfContent.requestLayout();
                usableHeightPrevious = usableHeightNow;
            }
        }
    
        private int computeUsableHeight() {
            Rect r = new Rect();
            mChildOfContent.getWindowVisibleDisplayFrame(r);
            return (r.bottom - r.top);
        }
    }
    
    展开全文
  • 仿微信发送在百度地图中定位到当前位置并实现发送位置信息(经纬度,位置信息)的功能。
  • 以下内容转载自面糊的文章《模仿微信发送位置功能》 作者:面糊 链接:https://www.jianshu.com/p/47b3ada2e36d 来源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 前言 微信的...

    以下内容转载自面糊的文章《模仿微信发送位置功能》

    作者:面糊

    链接:https://www.jianshu.com/p/47b3ada2e36d

    来源:简书

    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    前言

    微信的发送位置功能是一个十分方便的功能,他会定位用户当前所在地点,然后请求用户周边的POI,并且还可以通过拖动地图来获取其他的位置发送给对方,本Demo是结合腾讯地图SDK来实现类似的功能。

    使用场景

    拖动地图选择地图的中心点,然后请求该点周边的门店信息,可以通过设置搜索分类来指定搜索门店的类型,如:美食、学校等。

    准备

    核心代码:

    1、设置大头针,固定在地图中央,并监听地图移动的时候大头针跟随移动:

    - (void)mapViewRegionChange:(QMapView *)mapView {
        // 更新位置
        _annotation.coordinate = mapView.centerCoordinate;
    }
    

    2、配置周边检索功能,将检索类型设置为"美食":

    - (void)searchCurrentLocationWithKeyword:(NSString *)keyword {
    CLLocationCoordinate2D centerCoord = self.mapView.centerCoordinate;
    
        QMSPoiSearchOption *option = [[QMSPoiSearchOption alloc] init];
        if (keyword.length > 0) {
            option.keyword = keyword;
        }
        option.boundary = [NSString stringWithFormat:@"nearby(%f,%f,2000,1)", centerCoord.latitude, centerCoord.longitude];
        [option setFilter:@"category=美食"];
        [self.mapSearcher searchWithPoiSearchOption:option];
    }
    

    3、解析检索结果,移动地图视野,并将结果显示在tableView上:

    - (void)searchWithPoiSearchOption:(QMSPoiSearchOption *)poiSearchOption didReceiveResult:(QMSPoiSearchResult *)poiSearchResult {
        NSLog(@"%@", poiSearchResult);
    
        if (poiSearchResult.count == 0) {
            return;
        }
    
        // 地图移动到搜索结果的第一个位置
        if (_searchBar.text.length > 0) {
            _selectedIndex = 0;
            QMSPoiData *firstData = poiSearchResult.dataArray[0];
            _annotation.coordinate = firstData.location;
            [self.mapView setCenterCoordinate:firstData.location animated:YES];
        } else {
            _selectedIndex = -1;
        }
    
        _searchResultArray = poiSearchResult.dataArray;
        [_searchResultTableView reloadData];
    }
    

    以上就是核心代码,在Demo中还添加了用于显示地址的TableView以及搜索位置的SearchBar,有兴趣的同学可以在文章最下方进入码云下载完整示例。

    示例:搜索西二旗地铁附近的美食

    在这里插入图片描述

    链接

    感兴趣的同学可以在码云中下载Demo尝试一下。

    展开全文
  • 主要功能(参照微信发送定位): 1.定位所在位置并且展示周边POI(建筑物等信息); 2.移动中央覆盖物,返回其位置周边的POI信息; 3.支持关键词等搜索,每次搜索完成,中央覆盖物移动到第一条POI信息的相应位置;...

    本篇主要记录在实现这个功能时,遇到的一些问题以及解决,具体的实现代码在下篇文章中贴出

    百度地图开发的笔记(篇3)高仿微信发送位置功能

    首先看下效果图:

    这里写图片描述
    这里写图片描述
    这里写图片描述
    这里写图片描述

    主要功能(参照微信发送定位):

    • 1.定位所在位置并且展示周边POI(建筑物等信息);
    • 2.拖拽地图完成,返回中心覆盖物所处位置周边的POI信息;
    • 3.支持关键词等搜索,每次搜索完成,中央覆盖物移动到第一条POI信息的相应位置;
    • 4.点击右上角的图标,中央覆盖物回到所定位的位置;
    • 5.点击下边列表的某条数据,将中央覆盖物移至该条数据对应的位置;
    • 6.发送定位时,有相应的地图位置截图和地址信息.

    主要问题及解决

    1.如何添加地图中央覆盖物,随着对地图的拖拽,覆盖物始终在地图中心?

    第一眼是不是感觉中央覆盖物,不就是添加个marker,一开始我也这么实现的,然后监听地图的移动,不断让marker移动到屏幕的地图中心点。
    虽然也是能实现,但是明显界面卡顿,核心代码在下图:

    这里写图片描述

    这种方法很明显,是不行的。后来参照58速运App定位功能,对其布局进行查看,原来中央覆盖物是一个ImageView,浮动在MapView中央。那就可以这么实现了。用一个相对布局,里面放MapView和ImageView,ImageView处于MapView的中央位置,就这么搞定咯。

    2.当用户拖拽地图时,如何监听地图的移动?

    这个问题看着很简单,但我却觉得如果api选择错了,那就头痛了。

    刚开始我用OnMapStatusChangeListener类来实现监听地图的移动,因为该类可以知道 "地图状态的改变原因、状态改变的过程(开始改变/正在改变/改变结束),使用这个类的话,要注意判断地图状态的改变原因,因为MapStatusUpdate相关类也是会触发该类。

    由于OnMapStatusChangeListener类并不好控制,后面用OnMapTouchListener类将其替换,明显少了很多处理逻辑.

    3.当地图被拖动时,如何获取中央覆盖物的地理坐标?

    中央覆盖物是由于相对布局才处于MapView的中央,跟MapView只是层叠的关系,百度地图api中有个Projection类,用于屏幕像素点坐标系统和地球表面经纬度点坐标系统之间的变换,那我就尝试着获取ImageView的坐标,通过Projection类将屏幕坐标转换成地理坐标,刚开始试了确实可行;

    后面发现地理坐标偏差较大,源于后面要通过中央覆盖物的地理坐标,获取到周边的数据,发现数据有问题,获取到的数据都不是中央覆盖物周边的。

    后来在百度api文档中,翻到MapStatus这个类,这个类主要记录地图的状态,可以获取到地图操作的中心点、地图操作中心点在屏幕中的坐标等。由于覆盖物处于地图的中央,那么通过MapStatus获取到的中心地理坐标值,该值也就是该中心覆盖物的坐标。

    4.如何通过中央覆盖物的地理坐标,获取到周边的POI数据?

    刚开始是用周边检索功能来获取周边的POI数据,但周边检索功能必须设置keyword,那根据微信的功能实现,我并不能对keyword赋值,比如赋值 “大厦”,那获取到的数据都是关于周边大厦的。后来尝试着不用keyword来获取,但由于keyword的限制,也难以像微信一样。

    后面在百度文档中找到GeoCoder这个类,可以通过地理坐标反地理编码,从而获取到周边的POI数据。

    5.点击下边列表的某条数据,如何将中央覆盖物移至该数据对应的位置?

    由于获取到的数据是带有地址信息和地理坐标的,可以通过MapStatusUpdate/MapStatusUpdateFactory,移动地图。这样就以中央覆盖物为参照物,而地图进行移动, 眼睛却察觉到是中央覆盖物移至该数据对应的位置.

    6.发送定位时,对mapView进行截图,图中没有中央覆盖物?

    使用百度api中的SnapshotReadyCallback类对mapView进行截图,所截取到的图中并没有中央覆盖物。这是由于中央覆盖物并不处于mapView这个控件中.

    那么利用Android中View的截图方式,在mapView和中央覆盖物ImageView的父布局RelativeLayout外嵌套一层FrameLayout,对FrameLayout这个View进行截图呢?尝试了下,发现所截取的mapView是黑屏的,这就蓝瘦香菇了.

    没办法,那就只能狸猫换太子咯。在点击发送定位时,将中央覆盖物隐藏,往地图中央添加marker覆盖物,然后再调用百度api进行截图.

    其它

    1.上面说的OnMapStatusChangeListener类并不好控制,其中1点看下面截图:

    这里写图片描述

    明明是手指触摸,在触发事件中,监听到的地图状态原因是开发者调用,这明显不对。写这篇文章时再测了下,并没再发现监听状态错误的问题,猜测可能是由于MapStatusUpdate等类引起的,具体的就不去深究咯.

    2.获取ImageView的坐标,通过Projection类将屏幕坐标转换成地理坐标,偏差很大.下面截图中,地图中心点和中心覆盖物关于屏幕坐标、地理坐标的比较,这可能是因为地图并不是完全显示在手机屏幕的原因,导致偏差问题.

    这里写图片描述

    3.百度地图上面的签名跟apk的签名不一致,即sha1值错误

    galaxy lib host missing meta-data,make sure you know the right way to integrate galaxy

    这里写图片描述

    链接

    百度地图开发基础篇
    百度地图开发的笔记(篇3)高仿微信发送位置功能

    GitHub链接

    展开全文
  • 给大家介绍了利用百度地图Android sdk高仿微信发送位置功能,在实现此功能的时候遇到点小问题,下面小编给大家列出来,需要的朋友参考下吧
  • Android 腾讯地图 选点定位,仿微信发送位置

    千次阅读 热门讨论 2019-03-29 15:10:27
    效果图: 不需要集成定位、地图,然后标记 回调等繁琐的操作,你只需要一个webview,使用腾讯地图...通过页面跳转的方式调用该组件的时候,开发者需要设置backurl参数,用户点击选中的位置点后,页面跳转至开发者...
  • Android高仿微信发送位置.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
  • 利用百度地图Android sdk高仿微信发送位置功能 [注意:本资源来自网络,如有侵权,请联系我删除,谢谢。]
  • 仿微信发送位置(高德地图定位)

    千次阅读 2019-07-11 11:33:27
    仿微信发送位置,可以定位以及附近周边位置,搜索功能,获取位置以及经纬度 **源码链接:**https://download.csdn.net/download/jiaosheng1/11328362
  • 主要介绍了Android仿微信发送语音消息的功能及示例代码,需要的朋友参考下吧
  • 1、这个Demo主要是实现仿微信发送语音以及播放语音的功能效果。 2、相应的博文地址:https://blog.csdn.net/lpCrazyBoy/article/details/82910825
  • (无法运行)仿微信发送位置、地图选点(百度地图).rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
  • 压缩包 : cf75407614893f5bafffe5dea3462dea.zip 列表BaiduWeChatPosition/BaiduWeChatPosition/.idea/BaiduWeChatPosition/.idea/workspace.xmlBaiduWeChatPosition/BaiduWeChatPosition/BaiduWeChatPosition/...
  • web仿微信发朋友圈选择位置.web仿微信发朋友圈选择位置.web仿微信发朋友圈选择位置.

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,412
精华内容 2,564
关键字:

仿微信发送位置