Android 定位2

1.思路分析
  • 首先获得当前自己所在位置的经纬度。
  • 把我们获得的经纬度转换成我们能看得懂的具体位置信息
2.具体逻辑
  • 借助Android本身的LocationManager这个类提供的方法来获取经纬度。
  • 毫无疑问,要想使用LocationManager就必须要先获取它的实例,我们可以调用Context的getSystemService()方法获取,即:LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
  • 其次我们要选择要使用的位置提供器,只要有GPS和无线网络两种(GPS_PROVIDER和NETWORK_PROVIDER),虽然两者都能实现定位的功能,但是各有自己的特点,GPS定位精度高,但是非常耗电,网络定位精度稍差,但耗电量比较少。具体如:List providers = lm.getProviders(true); 先判断有哪些位置提供器可供使用,最后通过List 容器的contains()方法来判断具体是哪一种
  • 之后再获得一个Location这个类的对象,Location这个类是这个demo的核心类,因为它的对象包含了一系列的地理位置信息,如精度、纬度、海拔,有了其之后我们只需要从中取出我们所需要的信息即可。具体代码:Location location = lm.getLastKnownLocation(provider); 纬度即:double latitude = location.getLatitude(); 精度即:double longitude = location.getLongitude.
  • 有了经纬度之后,我们只要通过百度GeoCoding API进行反向地理编码,就可以把我们获得的经纬度转换成我们能够看得懂的地理位置信息。本来Geogle 自己就提供了GeoCoding供我们反向地理编码,但现在服务器好像访问不了了,翻墙也没用,所以这里我选择了百度GeoCoding ,但是它们的原理都是一样的,我们向百度的服务器发起一条http请求,并将经纬度作为参数一同传递过去,然后服务器会帮我们把这个经纬值转换成看得懂的位置信息,再将这些信息返回给手机端,我们只需要去解析处理这些数据即可。
  • 要想使用百度GeoCoding,首先需要拥有一个百度账号,其次再申请一个key,网址如下:http://lbsyun.baidu.com/apiconsole/key,随后选择创建应用,应用类型:服务端,写IP白名单, 格式如: 202.198.16.3,202.198.0.0/16 填写IP地址或IP前缀网段,英文半角逗号分隔 ,如果没有限制,直接设置0.0.0.0/0即可,因为只有IP白名单内的服务器才能成功发起调用 ,之后提交。之后会出现一个访问应用(ak),例如我的:pPGNKs75nVZPloDFuppTLFO3WXebPgXg
  • 之后向服务器发起网络请求,String url = "http://api.map.baidu.com/geocoder/v2/?ak=pPGNKs75nVZPloDFuppTLFO3WXebPgXg&callback=renderReverse&location="+latitude+","+longitude+"&output=json&pois=0";
  • 之后解析服务器给我们返回的数据,数据格式自己可以把上述网址在浏览器打开看一下,如果太多不好分析,可以在线解析一下即可。
3.demo:

public class ShowLocation extends AppCompatActivity {
    private String provider;//位置提供器
    private LocationManager locationManager;//位置服务
    private Location location;
    private Button btn_show;
    private TextView tv_show;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.location_show);
        init();//关联控件
        locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);//获得位置服务
        provider = judgeProvider(locationManager);

        if (provider != null) {//有位置提供器的情况
            //为了压制getLastKnownLocation方法的警告
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            location = locationManager.getLastKnownLocation(provider);
            if (location != null) {
                getLocation(location);//得到当前经纬度并开启线程去反向地理编码
            } else {
                tv_show.setText("暂时无法获得当前位置");
            }
        }else{//不存在位置提供器的情况

        }
    }
    private void init() {
        btn_show = (Button) findViewById(R.id.btn_show_location);
        tv_show = (TextView) findViewById(R.id.tv_location_show);
    }

    /**
     * 得到当前经纬度并开启线程去反向地理编码
     */
    public void getLocation(Location location) {
        String latitude = location.getLatitude()+"";
        String longitude = location.getLongitude()+"";
        String url = "http://api.map.baidu.com/geocoder/v2/?ak=pPGNKs75nVZPloDFuppTLFO3WXebPgXg&callback=renderReverse&location="+latitude+","+longitude+"&output=json&pois=0";
        new MyAsyncTask(url).execute();
    }

    /**
     * 判断是否有可用的内容提供器
     * @return 不存在返回null
     */
    private String judgeProvider(LocationManager locationManager) {
        List<String> prodiverlist = locationManager.getProviders(true);
        if(prodiverlist.contains(LocationManager.NETWORK_PROVIDER)){
            return LocationManager.NETWORK_PROVIDER;
        }else if(prodiverlist.contains(LocationManager.GPS_PROVIDER)) {
            return LocationManager.GPS_PROVIDER;
        }else{
            Toast.makeText(ShowLocation.this,"没有可用的位置提供器",Toast.LENGTH_SHORT).show();
        }
        return null;
    }

    class MyAsyncTask extends AsyncTask<Void,Void,Void>{
        String url = null;//要请求的网址
        String str = null;//服务器返回的数据
        String address = null;
        public MyAsyncTask(String url){
            this.url = url;
        }
        @Override
        protected Void doInBackground(Void... params) {
            str = GetHttpConnectionData.getData(url);
            return null;
        }
        @Override
        protected void onPostExecute(Void aVoid) {
            try {
                str = str.replace("renderReverse&&renderReverse","");
                str = str.replace("(","");
                str = str.replace(")","");
                JSONObject jsonObject = new JSONObject(str);
                JSONObject address = jsonObject.getJSONObject("result");
                String city = address.getString("formatted_address");
                String district = address.getString("sematic_description");
                tv_show.setText("当前位置:"+city+district);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            super.onPostExecute(aVoid);
        }
    }
}
 
 
效果图如下:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值