Android特色开发(基于位置的服务)

利用手机内置得芯片,实现当前位置的定位,拿到经纬度,定位功能必须要由用户主动去启用才行,不然任何应用程序都无法获取到手机当前的位置信息。进入手机的设置→定位服务,选择定位方式。
拿到经纬度后,根据google提供的API,把经纬度转换成我们看得到的城市名称。
Geocoding API,更详细的用法请参考官方文档:https://developers. google.com/maps/documentation/geocoding/。

详细代码:

public class MainActivity extends Activity {
private LocationManager manager;
private String provider;
private TextView tv;
private static final int MSG_WHAT=111;
Location location;
private String address;//详细地址
protected Address l;    
Handler hander=new Handler(){
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case MSG_WHAT:
             Address location=(Address) msg.obj;
             tv.setText(location.guojia+location.province+location.city+location.qu+location.jie+location.jiehao);
            break;

        default:
            break;
        }
    };
};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tv=(TextView) findViewById(R.id.tv);
        manager=(LocationManager) getSystemService(Context.LOCATION_SERVICE);
    List<String> providers= manager.getProviders(true);//获取所有可用的位置提供器
//  Android中一般有三种位置提供器可供选择,GPS_PROVIDER、NETWORK_PROVIDER和PASSIVE_PROVIDER。
//  其中前两种使用的比较多,分别表示使用GPS定位和使用网络定位。这两种定位方式各有特点,
//  GPS定位的精准度比较高,但是非常耗电,而网络定位的精准度稍差,但耗电量比较少。
//  我们应该根据自己的实际情况来选择使用哪一种位置提供器,当位置精度要求非常高的时候,最好使用GPS_PROVIDER,
//  而一般情况下,使用NETWORK_PROVIDER会更加得划算。
//  定位功能必须要由用户主动去启用才行,不然任何应用程序都无法获取到手机当前的位置信息。进入手机的设置→定位服务

    //判断哪个位置提供器可用
    if(providers.contains(LocationManager.GPS_PROVIDER)){
        provider=LocationManager.GPS_PROVIDER;
        Toast.makeText(getApplicationContext(), provider, 0).show();
    }else if(providers.contains(LocationManager.NETWORK_PROVIDER)){
        provider=LocationManager.NETWORK_PROVIDER;
        Toast.makeText(getApplicationContext(), provider, 0).show();
    }else{
        Toast.makeText(getApplicationContext(), "定位功能没有打开,请到设置打开...", 0).show();
        return;
    }
    //获取位置信息
    Log.d("provide", provider);
    location=manager.getLastKnownLocation(provider);
    if(location!=null){
        //显示位置信息
        showLocation(location);
    }
    //设备位置发生改变的时候获取到最新的位置信息
//  第一个参数是位置提供器的类型,第二个参数是监听位置变化的时间间隔,以毫秒为单位,
//  第三个参数是监听位置变化的距离间隔,以米为单位,第四个参数则是LocationListener监听器。
//  这样的话,LocationManager每隔5秒钟会检测一下位置的变化情况,当移动距离超过10米的时候,
//  就会调用LocationListener的onLocationChanged()方法,并把新的位置信息作为参数传入。
    manager.requestLocationUpdates(provider, 5000, 10, listener);

    //谷歌又提供了一套Geocoding API,使用它的话也可以完成反向地理编码的工作
//  Geocoding API中规定了很多接口,其中反向地理编码的接口如下:
//  http://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&sensor=true_or_false
//  我们来仔细看下这个接口的定义,其中http://maps.googleapis.com/maps/api/geocode/是固定的,表示接口的连接地址。
//  json表示希望服务器能够返回JSON格式的数据,这里也可以指定成xml。
//  latlng=40.714224,-73.96145表示传递给服务器去解码的经纬值是北纬40.714224度,西经73.96145度。
//  sensor=true_or_false表示这条请求是否来自于某个设备的位置传感器,通常指定成false即可。

    tv.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            showLocation(location);
        }
    });
    }

    private void showLocation(final Location location) {
        // TODO Auto-generated method stub
        tv.setText("纬度:"+location.getLatitude()+";经度:"+location.getLongitude());
        Log.d("show", location.toString());
        new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                // 组装反向地理编码的接口地址
                StringBuilder url = new StringBuilder();
                url.append("http://maps.google.cn/maps/api/geocode/json?latlng=");
                url.append(location.getLatitude()).append(",");
                url.append(location.getLongitude());
                url.append("&sensor=false");
                HttpClient httpClient = new DefaultHttpClient();
                HttpGet httpGet = new HttpGet(url.toString());
                // 在请求消息头中指定语言,保证服务器会返回中文数据
                httpGet.addHeader("Accept-Language", "zh-CN");
                HttpResponse httpResponse=null;
                try {
                    httpResponse = httpClient.execute(httpGet);
                    if (httpResponse.getStatusLine().getStatusCode() == 200) {
                        HttpEntity entity = httpResponse.getEntity();
                        String response = EntityUtils.toString(entity, "utf-8");
                        writeJsonToSDCard(response);
                        JSONObject jsonObject = new JSONObject(response);
                        // 获取results节点下的位置信息
                        JSONArray resultArray = jsonObject.getJSONArray ("results");
                        if (resultArray.length() > 0) {
                        JSONObject subObject = resultArray. getJSONObject(0);
                        // 取出格式化后的位置信息
                        address = subObject.getString ("formatted_address");
                        //取出省市区街道地址
                        JSONArray addArray=subObject.getJSONArray("address_components");
                        //创建对象放置这些信息
                        l=new com.example.androidlocation.Address();
                        //国家
                        JSONObject guojia=addArray.getJSONObject(5);
                        l.guojia=guojia.getString("long_name");
                        //省份
                        JSONObject province=addArray.getJSONObject(4);
                        l.province=province.getString("long_name");
                        //市
                        JSONObject city=addArray.getJSONObject(3);
                        l.city=city.getString("long_name");
                        //区
                        JSONObject qu=addArray.getJSONObject(2);
                        l.qu=qu.getString("long_name");
                        //街道
                        JSONObject jie=addArray.getJSONObject(1);
                        l.jie=jie.getString("long_name");
                        //街道号
                        JSONObject jiehao=addArray.getJSONObject(0);
                        l.jiehao=jiehao.getString("long_name");

                        }
                        Message message=hander.obtainMessage();
                        message.what=MSG_WHAT;
                        message.obj=l;
                        hander.sendMessage(message);
                    }
                } 
                catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }).start();
    }
    protected void onDestroy() {
        super.onDestroy();
        if (manager != null) {
        // 关闭程序时将监听器移除
        manager.removeUpdates(listener);
        }
        }
LocationListener listener=new LocationListener() {

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onLocationChanged(Location location) {
        // TODO Auto-generated method stub
        // 更新当前设备的位置信息
        showLocation(location);
    }
};

public void writeJsonToSDCard(String  s) {
    // TODO Auto-generated method stub
    File file=new File(Environment.getExternalStorageDirectory()+File.separator+"json"+File.separator+"json.txt");
    if(!file.getParentFile().exists()){
        file.getParentFile().mkdirs();
    }
    Log.d("file", file.getAbsolutePath());
    PrintStream output=null;
    try{
        output=new PrintStream(new FileOutputStream(file));
        output.print(s);
    }catch(Exception e){
        e.printStackTrace();
    }finally{
        if(output!=null){
            output.close();
        }
    }
}
}

保存位置名称的实体类

public class Address {
public String guojia;
public String province;
public String city;
public String qu;
public String jie;
public String jiehao;
}

需要的一些权限

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值