Android中获取用户附近位置

版权声明:本文为博主原创文章,未经博主允许不得转载。 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

猜你喜欢

转载自blog.csdn.net/qq_29078329/article/details/78140752