Android 仿微信发送地理位置地图

归纳下最近做的仿微信地理位置选择,T^T。避免下次再遇上类似功能需求又得重新去看高德开发文档。(此次这下本文也是基于本人刚删完代码就遇上需求,又重新看了一遍开发文档)。

先上效果图:

GIF.gif

本文使用的是高德地图,jar包如下图,若高德以后更新版本可能会有些方法改变,所以本文只只对当前版本。


850085424713306039.jpg

接下来归纳下本文所使用功能。

1.地图(这是必须的)

2.定位

3.添加标注(mark)

4.poi索引(地图下面的列表,PoiSearch)

5.逆地理编码(坐标转地址,用于移动地图后poi检索出周边,GeocodeSearch)

ok大概就这些了。

接下来上布局预览:

Paste_Image.png

,这里的重新定位是自己定义的一个按钮,并不是用地图自带的(自带的在地图的右上角),自定义的原因是自己之前封装好了一个定位,这里只要重新调用就行,纯属为了自己方便

地图跟定位是相对简单的,这里就不介绍了,

定位后把地图移动到当前地理位置,

Paste_Image.png

重点看POI 和地理的逆编码

Paste_Image.png

下面上一张poiItems的返回参数图,供参考

Paste_Image.png

地理的逆编码:

Paste_Image.png

只需传入经纬度,范围,第三个参数表示是火系坐标系还是GPS原生坐标系(具体的参考开发文档)

OK ,至此地图+地理列表页完成,剩下的就是手动输入地址检索出附近地址列表了(poi)因为这里已有类似代码,就不再介绍。

附送源码:
地图+列表选择页

public class MapLocationActivity extends BaseActivity {
private TextView tvTitle, tvBack;
private LinearLayout llBack;
private MapView mMapView;
private AMap aMap;
private UiSettings mUiSettings;

private ImageView ivLocation;

private PoiSearch.Query poiquery;
private RecyclerView recyclerView;
private LoactionAddressAdapter loactionAddressAdapter;
private List<LocationAddress> locationAddressList;

private TextView tvSearch;
private Marker marker;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_map_location);
    mMapView = getView(R.id.gs_map);
    //在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),实现地图生命周期管理
    mMapView.onCreate(savedInstanceState);
    initView();
    initListener();
}

private void initListener() {
    //监测地图画面的移动
    aMap.setOnCameraChangeListener(new AMap.OnCameraChangeListener() {
        @Override
        public void onCameraChangeFinish(CameraPosition cameraPosition) {
            //     ToastUtil.showToast(getApplicationContext(), cameraPosition.target.longitude+"当前地图中心位置: "+cameraPosition.target.latitude);
            //addMark(cameraPosition.target.latitude,cameraPosition.target.longitude);
            latSearchList(cameraPosition.target.latitude, cameraPosition.target.longitude);

        }

        @Override
        public void onCameraChange(CameraPosition cameraPosition) {
        }
    });
    //是否显示地图中放大缩小按钮
    mUiSettings.setZoomControlsEnabled(false);
    mUiSettings.setMyLocationButtonEnabled(false); // 是否显示默认的定位按钮
    aMap.setMyLocationEnabled(false);// 是否可触发定位并显示定位层

    //不设置触摸地图的时候会报错
    aMap.setOnMapClickListener(new AMap.OnMapClickListener() {
        @Override
        public void onMapClick(LatLng latLng) {

        }
    });
    ivLocation.setOnClickListener(onClickListener);
    llBack.setOnClickListener(onClickListener);
    tvSearch.setOnClickListener(onClickListener);
    loactionAddressAdapter.setItemListener(new LoactionAddressAdapter.OnItemListener() {
        @Override
        public void onItemClick(int position, RecyclerView.ViewHolder viewHolder) {

            Intent data = new Intent();
            data.putExtra("data", locationAddressList.get(position).getPoiItem());
            setResult(RESULT_OK, data);
            finish();

        }
    });
}

private void initView() {
    tvTitle = getView(R.id.tv_top_title_center);
    tvBack = getView(R.id.tv_title_left);
    tvBack.setVisibility(View.VISIBLE);
    llBack = getView(R.id.ll_title_left);
    tvSearch = getView(R.id.tv_search);
    ivLocation = getView(R.id.iv_loaction);
    if (aMap == null) {
        aMap = mMapView.getMap();
        mUiSettings = aMap.getUiSettings();
    }
    aMap.setTrafficEnabled(true);// 显示实时交通状况
    //地图模式可选类型:MAP_TYPE_NORMAL,MAP_TYPE_SATELLITE,MAP_TYPE_NIGHT
    aMap.setMapType(AMap.MAP_TYPE_NORMAL);//

    recyclerView = getView(R.id.map_recyler);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    locationAddressList = new ArrayList<>();
    loactionAddressAdapter = new LoactionAddressAdapter(this, locationAddressList);
    recyclerView.setAdapter(loactionAddressAdapter);

    tvTitle.setText("位置");
    location();

}

//定位
private void location() {
    GooleMapUtils.getInstence().init(this, new GooleMapUtils.GetGooleMapListener() {
        @Override
        public void onMapListener(String cityName, AMapLocation aMapLocation, boolean location) {
            if (true) {
                if (!TextUtils.isEmpty(aMapLocation.getCityCode()) && !TextUtils.isEmpty(aMapLocation.getRoad())) {
                    searchList(aMapLocation.getCityCode(), aMapLocation.getRoad());
                    //把地图移动到定位地点
                    moveMapCamera(aMapLocation.getLatitude(), aMapLocation.getLongitude());
                    addmark(aMapLocation.getLatitude(), aMapLocation.getLongitude());
                }
            } else {
                ToastUtil.showToast(MapLocationActivity.this, "定位失败");
            }
        }
    });
}

//把地图画面移动到定位地点
private void moveMapCamera(double latitude, double longitude) {
    aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude, longitude), 14));
}

private void addmark(double latitude, double longitude) {

    if (marker == null) {
        marker = aMap.addMarker(new MarkerOptions()
                .position(new LatLng(latitude, longitude))
                .icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
                        .decodeResource(getResources(), R.mipmap.myselfe_location_icon)))
                .draggable(true));
    } else {
        marker.setPosition(new LatLng(latitude, longitude));
        aMap.invalidate();
    }


}

//poi搜索
private void searchList(String cityCode, String road) {
    if (TextUtils.isEmpty(road)) {
        locationAddressList.clear();
        loactionAddressAdapter.notifyDataSetChanged();
    }
    poiquery = new PoiSearch.Query(road, "", cityCode);
    poiquery.setPageSize(15);
    poiquery.setPageNum(2);
    PoiSearch poiSearch = new PoiSearch(this, poiquery);
    poiSearch.setOnPoiSearchListener(onPoiSearchListener);
    poiSearch.searchPOIAsyn();
}

private void latSearchList(double latitude, double longitude) {
    //设置周边搜索的中心点以及半径
    GeocodeSearch geocodeSearch = new GeocodeSearch(this);
    //地点范围500米
    RegeocodeQuery query = new RegeocodeQuery(new LatLonPoint(latitude, longitude), 500, GeocodeSearch.AMAP);

    geocodeSearch.getFromLocationAsyn(query);

    geocodeSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
        @Override
        public void onRegeocodeSearched(RegeocodeResult result, int rCode) {
            if (rCode == 1000) {
                if (result != null && result.getRegeocodeAddress() != null
                        && result.getRegeocodeAddress().getFormatAddress() != null) {
                  /* String addressName = result.getRegeocodeAddress().getFormatAddress()
                            + "附近";
                    Log.v("sssssssss","ssssssssssssss"+addressName);*/
                    searchList(result.getRegeocodeAddress().getCityCode(), result.getRegeocodeAddress().getTownship());
                }
            }
        }

        @Override
        public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {
        }
    });

}

View.OnClickListener onClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.iv_loaction:
                location();
                break;
            case R.id.ll_title_left:
                finish();
                break;
            case R.id.tv_search:
                Intent intent = new Intent();
                intent.setClass(MapLocationActivity.this, LocationActivity.class);
                startActivityForResult(intent, 1);
                break;

        }
    }
};

//索引搜索
PoiSearch.OnPoiSearchListener onPoiSearchListener = new PoiSearch.OnPoiSearchListener() {
    @Override
    public void onPoiSearched(PoiResult result, int rCode) {
        if (rCode == 1000) {
            if (result != null && result.getQuery() != null) {// 搜索poi的结果
                if (result.getQuery().equals(poiquery)) {// 是否是同一条
                    //     poiResult = result;
                    // 取得搜索到的poiitems有多少页
                    List<PoiItem> poiItems = result.getPois();// 取得第一页的poiitem数据,页数从数字0开始
                    List<SuggestionCity> suggestionCities = result
                            .getSearchSuggestionCitys();// 当搜索不到poiitem数据时,会返回含有搜索关键字的城市信息
                    locationAddressList.clear();
                    if (poiItems != null && poiItems.size() > 0) {
                        for (int i = 0; i < poiItems.size(); i++) {
                            LocationAddress locationAddress = new LocationAddress();
                            locationAddress.setPoiItem(poiItems.get(i));
                            locationAddressList.add(locationAddress);
                        }
                     /*   if (isSearch){
                                moveMapCamera(poiItems.get(0).getLatLonPoint().getLatitude(),poiItems.get(0).getLatLonPoint().getLongitude());
                        }*/
                    }
                    loactionAddressAdapter.notifyDataSetChanged();
                }
            }
        }
    }

    @Override
    public void onPoiItemSearched(PoiItem poiItem, int i) {

    }
};


@Override
protected void onDestroy() {
    super.onDestroy();
    //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
    mMapView.onDestroy();
}

@Override
protected void onResume() {
    super.onResume();
    //在activity执行onResume时执行mMapView.onResume (),实现地图生命周期管理
    mMapView.onResume();
}

@Override
protected void onPause() {
    super.onPause();
    //在activity执行onPause时执行mMapView.onPause (),实现地图生命周期管理
    mMapView.onPause();
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),实现地图生命周期管理
    mMapView.onSaveInstanceState(outState);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 1) {
        if (resultCode == RESULT_OK) {
            if (data != null) {
                // 获取返回的数据
                PoiItem poiItem = (PoiItem) data.getParcelableExtra("data");
                // 处理自己的逻辑 ....
                searchList(poiItem.getCityCode(), poiItem.getBusinessArea());
                moveMapCamera(poiItem.getLatLonPoint().getLatitude(), poiItem.getLatLonPoint().getLongitude());
            }

        }
    }
}}

手动输入POI索引页:

public class LocationActivity extends BaseActivity {
private PoiSearch.Query poiquery;
private EditText etSearch;
private RecyclerView recyclerView;
private LoactionAddressAdapter loactionAddressAdapter;
private List<LocationAddress> locationAddressList;
private String code;
private LinearLayout llBack;
private TextView tvTitle,tvBack;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_location);

    initView();
    initData();
    initListener();
}

private void initListener() {
    loactionAddressAdapter.setItemListener(new LoactionAddressAdapter.OnItemListener() {
        @Override
        public void onItemClick(int position, RecyclerView.ViewHolder viewHolder) {
            Intent data = new Intent();
            data.putExtra("data", locationAddressList.get(position).getPoiItem());
            setResult(RESULT_OK, data);
            finish();
        }
    });
}

private void initData() {
    tvBack.setVisibility(View.VISIBLE);
    tvTitle.setText("位置");
    GooleMapUtils.getInstence().init(this, new GooleMapUtils.GetGooleMapListener() {
        @Override
        public void onMapListener(String cityName, AMapLocation aMapLocation, boolean location) {
            if (true){
                if (!TextUtils.isEmpty(aMapLocation.getCityCode())&&!TextUtils.isEmpty(aMapLocation.getRoad())){
                    code =aMapLocation.getCityCode();
                    searchList(aMapLocation.getCityCode(),aMapLocation.getRoad());
                }
            }else {
                ToastUtil.showToast(LocationActivity.this,"定位失败");
            }
        }
    });

    etSearch.addTextChangedListener(textWatcher);
}
TextWatcher textWatcher = 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) {

    }

    @Override
    public void afterTextChanged(Editable s) {
        searchList(code,etSearch.getText().toString().trim());
    }
};

private void initView() {
    tvTitle = getView(R.id.tv_top_title_center);
    tvBack = getView(R.id.tv_title_left);
    llBack = getView(R.id.ll_title_left);
    etSearch = getView(R.id.et_search);
    recyclerView = getView(R.id.search_list);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    locationAddressList = new ArrayList<>();
    loactionAddressAdapter = new LoactionAddressAdapter(this,locationAddressList);
    recyclerView.setAdapter(loactionAddressAdapter);

    llBack.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            finish();
        }
    });
}

private void searchList(String cityCode, String road) {
    if (TextUtils.isEmpty(road)){
        locationAddressList.clear();
        loactionAddressAdapter.notifyDataSetChanged();
    }
    poiquery = new PoiSearch.Query(road,"",cityCode);
    poiquery.setPageSize(15);
    poiquery.setPageNum(2);
    PoiSearch poiSearch = new PoiSearch(this,poiquery);
    poiSearch.setOnPoiSearchListener(onPoiSearchListener);
    poiSearch.searchPOIAsyn();
}


//索引搜索
PoiSearch.OnPoiSearchListener onPoiSearchListener = new PoiSearch.OnPoiSearchListener() {
    @Override
    public void onPoiSearched(PoiResult result, int rCode) {
        if (rCode == 1000) {
            if (result != null && result.getQuery() != null) {// 搜索poi的结果
                if (result.getQuery().equals(poiquery)) {// 是否是同一条
               //     poiResult = result;
                    // 取得搜索到的poiitems有多少页
                    List<PoiItem> poiItems = result.getPois();// 取得第一页的poiitem数据,页数从数字0开始
                    List<SuggestionCity> suggestionCities = result
                            .getSearchSuggestionCitys();// 当搜索不到poiitem数据时,会返回含有搜索关键字的城市信息
                    locationAddressList.clear();
                    if (poiItems != null && poiItems.size() > 0) {
                        for (int i=0;i<poiItems.size();i++){
                            LocationAddress locationAddress = new LocationAddress();
                            locationAddress.setPoiItem(poiItems.get(i));
                            locationAddressList.add(locationAddress);
                        }
                    }
                    loactionAddressAdapter.notifyDataSetChanged();
                }
            }
        }
    }
    @Override
    public void onPoiItemSearched(PoiItem poiItem, int i) {

    }
};}

定位:

public class GooleMapUtils {

//声明AMapLocationClient类对象
public AMapLocationClient mLocationClient = null;
//声明定位回调监听器
public AMapLocationListener mLocationListener;

//声明mLocationOption对象
public AMapLocationClientOption mLocationOption = null;

public static GooleMapUtils amap;
private GetGooleMapListener getGooleMapListener1;
private boolean isfirst=true;
private Context context;

public static GooleMapUtils getInstence() {
    if (amap == null) {
        amap = new GooleMapUtils();
    }
    return amap;
}

public void init(final Context context ,GetGooleMapListener getGooleMapListener) {

    this.context =context;
    this.getGooleMapListener1=getGooleMapListener;
    mLocationListener = new AMapLocationListener() {
        @Override
        public void onLocationChanged(AMapLocation aMapLocation) {

       //    Log.v("sssssss","sssssss这个是地区id  比如海珠区"+aMapLocation);
                if (aMapLocation != null && aMapLocation.getErrorCode() == 0) {
                    if (getGooleMapListener1!=null)
                    getGooleMapListener1.onMapListener(aMapLocation.getCity(),aMapLocation,true);
                    

                } else {
                    if (getGooleMapListener1!=null)
                    getGooleMapListener1.onMapListener("定位失败", null,false);
                }

        }
    };
    mLocationClient = new AMapLocationClient(context);
    //设置定位回调监听
    mLocationClient.setLocationListener(mLocationListener);

    mLocationOption = new AMapLocationClientOption();

    //设置定位模式为高精度模式,Battery_Saving为低功耗模式,Device_Sensors是仅设备模式
    mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
    //设置是否返回地址信息(默认返回地址信息)
    mLocationOption.setNeedAddress(true);
    //设置是否只定位一次,默认为false
    mLocationOption.setOnceLocation(true);
    //设置是否强制刷新WIFI,默认为强制刷新
    mLocationOption.setWifiActiveScan(true);
    //设置是否允许模拟位置,默认为false,不允许模拟位置
    mLocationOption.setMockEnable(false);
    //设置定位间隔,单位毫秒,默认为2000ms
    mLocationOption.setInterval(30*60*1000);
    //给定位客户端对象设置定位参数
    mLocationClient.setLocationOption(mLocationOption);
    //启动定位
    mLocationClient.startLocation();
}

public interface GetGooleMapListener{

    void onMapListener(String cityName, AMapLocation  aMapLocation,boolean location);
}}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容