版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29078329/article/details/78140752
最近项目中要获取用户附近位置,供用户选择,该功能分两步实现,第一,获取用户经纬度,第二利,用经纬度通过现有的地理位置接口获取附近位置,实现截图如下:
一、获取用户的经纬度
获取用户的经纬度,之前已经介绍过,通过simple-location-tracker实现,具体请看:http://blog.csdn.net/qq_29078329/article/details/56668205。
注意,要在程序启动时获取用户的经纬度,并保存在sharedPreference中,如下:
private void getLocation() {
//允许GPS、WiFi、基站定位,设置超时时间5秒
TrackerSettings trackerSettings = new TrackerSettings();
trackerSettings.setUseGPS(true).setUseNetwork(true).setUsePassive(true).setTimeout(5000);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationTracker locationTracker = new LocationTracker(this, trackerSettings) {
@Override
public void onLocationFound(@NonNull Location location) {
Log.i(TAG, "latitude:" + location.getLatitude() + "longitude" + location.getLongitude());
SharedPrefUtil.getInstance(SplashActivity.this).putString(Constants.LOCATION_LATITUDE_SP_KEY, location.getLatitude() + "");
SharedPrefUtil.getInstance(SplashActivity.this).putString(Constants.LOCATION_lONGITUDE_SP_KEY, location.getLongitude() + "");
}
@Override
public void onTimeout() {
Log.i(TAG, "location time out");
}
};
locationTracker.startListening();
}
二、获取用户附近位置
从sharedPreference中取得经纬度,利用地理位置接口,获取附近位置数据:
//获取附近位置
private void getAddresses() {
String latitude = SharedPrefUtil.getInstance(this).getString(Constants.LOCATION_LATITUDE_SP_KEY);
String longitude = SharedPrefUtil.getInstance(this).getString(Constants.LOCATION_lONGITUDE_SP_KEY);
if (!TextUtils.isEmpty(latitude) && !TextUtils.isEmpty(longitude)) {
mAddressesList = new ArrayList<>();
HttpClient httpClient = new HttpClient();
httpClient.setCallback(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i(TAG, "getLocation onFailure");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String jsonResponse = response.body().string();
JsonUtil.getAddresses(jsonResponse, mAddressesList);
}
}).requestAddresses(latitude, longitude);
}
}
//网络请求
public void requestAddresses(String latitude, String longitude) {
if (TextUtils.isEmpty(latitude) || TextUtils.isEmpty(longitude)) {
throw new NullPointerException("HttpClient.requestAddresses(),latitude is null or longitude is null");
}
OkHttpClient okHttpClient = new OkHttpClient();
Request.Builder builder = new Request.Builder().get().url(Constants.GET_NEARBY_ADDRESSES_URL + "&location=" + latitude + "," + longitude + "&output=json&pois=1");
Request request = builder.build();
Call call = okHttpClient.newCall(request);
call.enqueue(mCallback);
}
//附近位置接口
String GET_NEARBY_ADDRESSES_URL = "http://api.map.baidu.com/geocoder/v2/?ak=6eea93095ae93db2c77be9ac910ff311&location=39.908853,116.366893&output=json&pois=1";
{
"status": 0,
"result": {
"location": {
"lng": 116.36689299999995,
"lat": 39.90885307752264
},
"formatted_address": "北京市西城区鲍家街43",
"business": "复兴门,西便门,长椿街",
"addressComponent": {
"country": "中国",
"country_code": 0,
"province": "北京市",
"city": "北京市",
"district": "西城区",
"town": "",
"adcode": "110102",
"street": "鲍家街",
"street_number": "43",
"direction": "附近",
"distance": "24"
},
"pois": [
{
"addr": "鲍家街43号及宗帽胡同甲2号",
"cp": " ",
"direction": "附近",
"distance": "35",
"name": "醇亲王南府",
"poiType": "旅游景点",
"point": {
"x": 116.36717845491187,
"y": 39.90874097912572
},
"tag": "旅游景点;文物古迹",
"tel": "",
"uid": "c1820fb2f1833759cac3db1e",
"zip": "",
"parent_poi": {
"name": "",
"tag": "",
"addr": "",
"point": {
"x": 0,
"y": 0
},
"direction": "",
"distance": "",
"uid": ""
}
},
{
"addr": "北京市西城区鲍家街43号院新2号楼",
"cp": " ",
"direction": "附近",
"distance": "16",
"name": "鲍家街43号院新2号楼",
"poiType": "房地产",
"point": {
"x": 116.36703472603027,
"y": 39.90881707969393
},
"tag": "房地产;住宅区",
"tel": "",
"uid": "00a6781672e427648a2fb556",
"zip": "",
"parent_poi": {
"name": "",
"tag": "",
"addr": "",
"point": {
"x": 0,
"y": 0
},
"direction": "",
"distance": "",
"uid": ""
}
},
{
"addr": "太平湖东里与鲍家街交叉口西50米",
"cp": " ",
"direction": "附近",
"distance": "17",
"name": "音苑美食楼-南门",
"poiType": "出入口",
"point": {
"x": 116.36673828521198,
"y": 39.908844752606704
},
"tag": "出入口;门",
"tel": "",
"uid": "d78e3da9fe40c2d4441a32a8",
"zip": "",
"parent_poi": {
"name": "",
"tag": "",
"addr": "",
"point": {
"x": 0,
"y": 0
},
"direction": "",
"distance": "",
"uid": ""
}
},
{
"addr": "北京市西城区鲍家街43号",
"cp": " ",
"direction": "附近",
"distance": "37",
"name": "中央音乐学院-东门",
"poiType": "出入口",
"point": {
"x": 116.36716048880167,
"y": 39.908692551447025
},
"tag": "出入口;门",
"tel": "",
"uid": "3dc9befd8e0d7716bea24001",
"zip": "",
"parent_poi": {
"name": "中央音乐学院",
"tag": "教育培训;高等院校",
"addr": "北京市西城区鲍家街43号",
"point": {
"x": 116.36568726776531,
"y": 39.90823594592287
},
"direction": "东北",
"distance": "161",
"uid": "74f24595717502a1441a32c6"
}
},
{
"addr": "鲍家街43号西门",
"cp": " ",
"direction": "东北",
"distance": "51",
"name": "鲍家街43号院",
"poiType": "房地产",
"point": {
"x": 116.36654065799979,
"y": 39.90862336898905
},
"tag": "房地产;住宅区",
"tel": "",
"uid": "1f86b02d1d7152d8ce04ef76",
"zip": "",
"parent_poi": {
"name": "",
"tag": "",
"addr": "",
"point": {
"x": 0,
"y": 0
},
"direction": "",
"distance": "",
"uid": ""
}
},
{
"addr": "西城区鲍家街43号中央音乐学院内",
"cp": " ",
"direction": "东南",
"distance": "65",
"name": "中央音乐学院-音乐厅",
"poiType": "休闲娱乐",
"point": {
"x": 116.36657659022019,
"y": 39.90923909038928
},
"tag": "休闲娱乐;剧院",
"tel": "",
"uid": "fa18761b28eae24fe01103fc",
"zip": "",
"parent_poi": {
"name": "中央音乐学院",
"tag": "教育培训;高等院校",
"addr": "北京市西城区鲍家街43号",
"point": {
"x": 116.36568726776531,
"y": 39.90823594592287
},
"direction": "东北",
"distance": "161",
"uid": "74f24595717502a1441a32c6"
}
},
{
"addr": "北京市西城区鲍家街43号",
"cp": " ",
"direction": "东北",
"distance": "161",
"name": "中央音乐学院",
"poiType": "教育培训",
"point": {
"x": 116.36568726776531,
"y": 39.90823594592287
},
"tag": "教育培训;高等院校",
"tel": "",
"uid": "74f24595717502a1441a32c6",
"zip": "",
"parent_poi": {
"name": "",
"tag": "",
"addr": "",
"point": {
"x": 0,
"y": 0
},
"direction": "",
"distance": "",
"uid": ""
}
},
{
"addr": "鲍家街43号西门",
"cp": " ",
"direction": "北",
"distance": "74",
"name": "北京市西城区鲍家街43号院新1栋号",
"poiType": "房地产",
"point": {
"x": 116.36689099714867,
"y": 39.908339720175015
},
"tag": "房地产;住宅区",
"tel": "",
"uid": "2e9f702a2af312aedf1e5289",
"zip": "",
"parent_poi": {
"name": "",
"tag": "",
"addr": "",
"point": {
"x": 0,
"y": 0
},
"direction": "",
"distance": "",
"uid": ""
}
},
{
"addr": "太平湖东里甲1号",
"cp": " ",
"direction": "北",
"distance": "201",
"name": "卓越烤鸭店",
"poiType": "美食",
"point": {
"x": 116.36708862436087,
"y": 39.90746801153214
},
"tag": "美食;中餐厅",
"tel": "",
"uid": "5ce2637d87b72748ae31e53f",
"zip": "",
"parent_poi": {
"name": "",
"tag": "",
"addr": "",
"point": {
"x": 0,
"y": 0
},
"direction": "",
"distance": "",
"uid": ""
}
},
{
"addr": "鲍家街43号中央音乐学院图书馆楼2楼",
"cp": " ",
"direction": "东",
"distance": "247",
"name": "中央音乐学院-查阜西纪念馆",
"poiType": "旅游景点",
"point": {
"x": 116.36480692836552,
"y": 39.90827053735785
},
"tag": "旅游景点;文物古迹",
"tel": "",
"uid": "c0943a233e42f877ed74f8af",
"zip": "",
"parent_poi": {
"name": "中央音乐学院",
"tag": "教育培训;高等院校",
"addr": "北京市西城区鲍家街43号",
"point": {
"x": 116.36568726776531,
"y": 39.90823594592287
},
"direction": "东北",
"distance": "161",
"uid": "74f24595717502a1441a32c6"
}
}
],
"roads": [],
"poiRegions": [],
"sematic_description": "醇亲王南府附近35米",
"cityCode": 131
}
}
四、解析json数据,RecyclerView+Recycler.Adapter展示附近位置
解析json数据,获取附近位置List:
public static void getAddresses(String jsonStr, ArrayList list) {
if (!TextUtils.isEmpty(jsonStr) && list != null) {
try {
JSONObject addresses = new JSONObject(jsonStr);
JSONObject result = addresses.getJSONObject("result");
JSONArray pois = result.optJSONArray("pois");
if (pois != null && pois.length() > 0) {
for (int i = 0; i < pois.length(); i++) {
JSONObject address = pois.getJSONObject(i);
if (address != null) {
String name = address.getString("name");
String number = address.getString("addr");
Address each = new Address(name, number);
list.add(each);
}
}
}
} catch (Exception e) {
Log.i("TAG", e.getMessage());
}
}
}
AddressListActivity中Recycler展示附近位置列表:
package com.xi.liuliu.topnews.activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.KeyEvent;
import android.view.View;
import android.widget.TextView;
import com.xi.liuliu.topnews.R;
import com.xi.liuliu.topnews.adapter.AddressListAdapter;
import com.xi.liuliu.topnews.bean.Address;
import com.xi.liuliu.topnews.constants.Constants;
import com.xi.liuliu.topnews.impl.OnItemClickListener;
import com.xi.liuliu.topnews.utils.SharedPrefUtil;
import java.util.ArrayList;
public class AddressListActivity extends AppCompatActivity implements View.OnClickListener {
private TextView mCancle;
private RecyclerView mRecyclerView;
private ArrayList<Address> mAddressList;
private LinearLayoutManager mLinearLayoutManager;
private AddressListAdapter mAddressListAdapter;
private SharedPrefUtil mSharedPrefUtil;
private String mLastTimeAddress;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_address_list);
initData();
initView();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
//AddressListActivity是由startActivityForResult启动的,所以AddressListActivity关闭前,必须setResult,否则crash
Intent intent = new Intent();
if (mLastTimeAddress != null) {
if (mLastTimeAddress.equals("")) {
intent.putExtra("address_name", "");
} else {
intent.putExtra("address_name", mLastTimeAddress);
}
}
setResult(0, intent);
}
return super.onKeyDown(keyCode, event);
}
private void initData() {
mAddressList = getIntent().getParcelableArrayListExtra("addressList");
mSharedPrefUtil = SharedPrefUtil.getInstance(this);
mLastTimeAddress = mSharedPrefUtil.getString(Constants.LOCATION_ADDRESS_SP_KEY);
mLinearLayoutManager = new LinearLayoutManager(this);
mAddressListAdapter = new AddressListAdapter(mAddressList, mLastTimeAddress);
}
private void initView() {
mCancle = (TextView) findViewById(R.id.go_back_btn_address_list);
mCancle.setOnClickListener(this);
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view_address_list);
mRecyclerView.setLayoutManager(mLinearLayoutManager);
//如果每个item的高度是固定的,设置这个选项可以提高性能
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setAdapter(mAddressListAdapter);
mAddressListAdapter.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Intent intent = new Intent();
String addressName;
if (position == 0) {
addressName = "";
} else {
Address selectedAddress = mAddressList.get(position - 1);
addressName = selectedAddress.getName();
}
intent.putExtra("address_name", addressName);
mSharedPrefUtil.putString(Constants.LOCATION_ADDRESS_SP_KEY, addressName);
setResult(0, intent);
finish();
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.go_back_btn_address_list:
//AddressListActivity是由startActivityForResult启动的,所以AddressListActivity关闭前,必须setResult,否则crash
Intent intent = new Intent();
if (mLastTimeAddress != null) {
if (mLastTimeAddress.equals("")) {
intent.putExtra("address_name", "");
} else {
intent.putExtra("address_name", mLastTimeAddress);
}
}
setResult(0, intent);
finish();
break;
}
}
}
AddressListAdapter:
package com.xi.liuliu.topnews.adapter;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.xi.liuliu.topnews.R;
import com.xi.liuliu.topnews.bean.Address;
import com.xi.liuliu.topnews.impl.OnItemClickListener;
import java.util.ArrayList;
/**
* Created by zhangxb171 on 2017/9/6.
*/
public class AddressListAdapter extends RecyclerView.Adapter implements View.OnClickListener {
private static final String TAG = "AddressListAdapter";
private static final int TYPE_NOT_SHOW_ADDRESS = 0;
private static final int TYPE_SHOW_ADDRESS = 1;
private ArrayList<Address> mAddressList;
private OnItemClickListener mOnItemClickListener;
private String mLastTimeAddress;
public AddressListAdapter(ArrayList<Address> list, String lastTimeAddress) {
this.mAddressList = list;
this.mLastTimeAddress = lastTimeAddress;
reorderAddressList();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_SHOW_ADDRESS) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_address_list, parent, false);
view.setOnClickListener(this);
AddressListHolder holder = new AddressListHolder(view);
holder.addressName = (TextView) view.findViewById(R.id.address_name_item_address_list);
holder.addressNumber = (TextView) view.findViewById(R.id.address_number_item_address_list);
holder.itemSelected = (ImageView) view.findViewById(R.id.location_selected_item_address_list);
return holder;
} else {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_address_not_show, parent, false);
view.setOnClickListener(this);
AddressNoHolder holder = new AddressNoHolder(view);
holder.textView = (TextView) view.findViewById(R.id.address_not_show);
holder.itemSelected = (ImageView) view.findViewById(R.id.location_selected_not_show);
return holder;
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
//将position保存在itemView的Tag中,以便点击时进行获取
holder.itemView.setTag(position);
if (getItemViewType(position) == TYPE_SHOW_ADDRESS) {
AddressListHolder addressListHolder = (AddressListHolder) holder;
if (mAddressList != null && mAddressList.size() > 0) {
String addressName = mAddressList.get(position - 1).getName();
String addressNumber = mAddressList.get(position - 1).getNumber();
addressListHolder.addressName.setText(addressName);
addressListHolder.addressNumber.setText(addressNumber);
if (mLastTimeAddress != null && mLastTimeAddress.equals(addressName)) {
addressListHolder.itemSelected.setVisibility(View.VISIBLE);
}
}
} else {
//上次没有选择位置的话,让对勾出现
AddressNoHolder addressNoHolder = (AddressNoHolder) holder;
if (mLastTimeAddress != null && mLastTimeAddress.equals("")) {
addressNoHolder.itemSelected.setVisibility(View.VISIBLE);
}
}
}
@Override
public int getItemCount() {
return mAddressList.size() + 1;
}
@Override
public int getItemViewType(int position) {
if (position == 0) {
return TYPE_NOT_SHOW_ADDRESS;
} else {
return TYPE_SHOW_ADDRESS;
}
}
@Override
public void onClick(View v) {
if (mOnItemClickListener != null) {
//使用getTag方法获取position
mOnItemClickListener.onItemClick(v, (int) v.getTag());
}
}
private static class AddressListHolder extends RecyclerView.ViewHolder {
TextView addressName;
TextView addressNumber;
ImageView itemSelected;
View addressItemView;
public AddressListHolder(View itemView) {
super(itemView);
addressItemView = itemView;
}
}
private static class AddressNoHolder extends RecyclerView.ViewHolder {
TextView textView;
ImageView itemSelected;
View view;
public AddressNoHolder(View itemView) {
super(itemView);
view = itemView;
}
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.mOnItemClickListener = listener;
}
/**
* 将上次选择的位置放在数组顶部(地址列表的第二个位置)
*/
private void reorderAddressList() {
if (!TextUtils.isEmpty(mLastTimeAddress)) {
if (mAddressList != null && mAddressList.size() > 0) {
for (int i = 0; i < mAddressList.size(); i++) {
Address address = mAddressList.get(i);
if (address.getName().equals(mLastTimeAddress)) {
//将上次选择的位置放在数组顶部
mAddressList.add(0, address);
mAddressList.remove(i + 1);
return;
}
}
}
}
}
}
个人水平有限,希望大家批评指正,代码地址: https://github.com/xiyy/TopNews