浅谈Android Location

第一次来写博客,记录下android开发过程中的心得体会,也不知从何写起。

笔者就浅谈一下android Location,大家都知道android Location 分为两大类:原生定位、第三方定位(百度地图等)。
而原生定位又细分为两小类:GPS定位、网络定位;
通过GPS定位,较精确,也比较耗电,而网络定位精度不高,省电。为了保证精确度,优先考虑GPS定位。
笔者今天写了一个小demo,从代码的角度,来了解一下原生定位。
首先创建一个Android 工程 Location。
第二步写布局文件xml,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.demo.location.MainActivity">
    <TextView
        android:id="@+id/tv_longitude"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:layout_centerHorizontal="true"
        android:text="longitude:" />
    <TextView
        android:id="@+id/tv_latitude"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="latitude:"
        android:textSize="20sp"
        android:layout_centerHorizontal="true"
        android:layout_below="@+id/tv_longitude"/>
    <TextView
        android:id="@+id/tv_address"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="地址"
        android:layout_centerHorizontal="true"
        android:textSize="20sp"
        android:layout_below="@+id/tv_latitude"/>
</RelativeLayout>
第三步增加权限,修改AndroidManifest.xml 代码如下:
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
第四步写定位工具类LocationUtils,代码如下图所示:
package com.demo.location;

import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import java.io.IOException;
import java.util.List;
import java.util.Locale;

/**
 * @className: LocationUtils
 * @classDescription: 定位工具类
 * @author: leibing
 * @createTime: 2016/5/12
 */
public class LocationUtils {
    // GPS定位
    private final static String GPS_LOCATION = LocationManager.GPS_PROVIDER;
    // 网络定位
    private final static String NETWORK_LOCATION = LocationManager.NETWORK_PROVIDER;
    // 解码经纬度最大结果数目
    private final static int MAX_RESULTS = 1;
    // 时间更新间隔,单位:ms
    private final static long MIN_TIME = 1000;
    // 位置刷新距离,单位:m
    private final static float MIN_DISTANCE = (float) 0.01;
    // singleton
    private static LocationUtils instance;
    // 定位回调
    private LocationCallBack mLocationCallBack;
    // 定位管理实例
    LocationManager mLocationManager;
    // 上下文
    private Context mContext;

    /**
     * 构造函数
     * @author leibing
     * @createTime 2016/5/12
     * @lastModify 2016/5/12
     * @param mContext 上下文
     * @return
     */
    private LocationUtils(Context mContext) {
        this.mContext = mContext;
    }

    /**
     * singleton
     * @author leibing
     * @createTime 2016/5/12
     * @lastModify 2016/5/12
     * @param mContext 上下文
     * @return
     */
    public static LocationUtils getInstance(Context mContext) {
        if (instance == null) {
            instance = new LocationUtils(mContext);
        }
        return instance;
    }

    /**
     * 获取定位
     * @author leibing
     * @createTime 2016/5/12
     * @lastModify 2016/5/12
     * @param mLocationCallBack 定位回调
     * @return
     */
    @SuppressWarnings("MissingPermission")
    public void getLocation(LocationCallBack mLocationCallBack) {
        this.mLocationCallBack = mLocationCallBack;
        if (mLocationCallBack == null)
            return;
        // 定位管理初始化
        mLocationManager = (LocationManager)
                mContext.getSystemService(Context.LOCATION_SERVICE);
        // 通过GPS定位,较精确,也比较耗电
        LocationProvider gpsProvider =
                mLocationManager.getProvider(LocationManager.GPS_PROVIDER);
        // 通过网络定位,对定位精度度不高或省点情况可考虑使用
        LocationProvider netProvider =
                mLocationManager.getProvider(LocationManager.NETWORK_PROVIDER);
        // 优先考虑GPS定位,其次网络定位。
        if (gpsProvider != null){
            gpsLocation();
        }else if(netProvider != null){
            netWorkLocation();
        }else {
            mLocationCallBack.setLocation(null);
        }
    }

    /**
     * GPS定位
     * @author leibing
     * @createTime 2016/5/12
     * @lastModify 2016/5/12
     * @return
     */
    @SuppressWarnings("MissingPermission")
    private void gpsLocation(){
        if (mLocationManager == null)
            mLocationManager = (LocationManager)
                    mContext.getSystemService(Context.LOCATION_SERVICE);
        mLocationManager.requestLocationUpdates(
                GPS_LOCATION, MIN_TIME, MIN_DISTANCE,mLocationListener);
    }

    /**
     * 网络定位
     * @author leibing
     * @createTime 2016/5/12
     * @lastModify 2016/5/12
     * @return
     */
    @SuppressWarnings("MissingPermission")
    private void netWorkLocation(){
        if (mLocationManager == null)
            mLocationManager = (LocationManager)
                    mContext.getSystemService(Context.LOCATION_SERVICE);
        mLocationManager.requestLocationUpdates(
                NETWORK_LOCATION, MIN_TIME, MIN_DISTANCE,mLocationListener);
    }

    // 定位监听
    private LocationListener mLocationListener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            if (mLocationCallBack != null){
                mLocationCallBack.setLocation(location);
            }
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
        }

        @Override
        public void onProviderEnabled(String provider) {
        }

        @Override
        public void onProviderDisabled(String provider) {
            // 如果gps定位不可用,改用网络定位
            if (provider.equals(LocationManager.GPS_PROVIDER)){
                netWorkLocation();
            }
        }
    };

    /**
     * 根据经纬度获取地址
     * @author leibing
     * @createTime 2016/5/12
     * @lastModify 2016/5/12
     * @param latitude 纬度
     * @param longitude 经度
     * @return
     */
    public void getAddress(double latitude, double longitude){
        // Address列表
        List<Address> locationList = null;
        // 经纬度解码实例
        Geocoder gc = new Geocoder(mContext, Locale.getDefault());
        try {
            // 获取Address列表
            locationList = gc.getFromLocation(latitude, longitude, MAX_RESULTS);
            // 获取Address实例
            Address address = locationList.get(0);
            if (mLocationCallBack != null)
                mLocationCallBack.setAddress(address);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取地址周边信息
     * @author leibing
     * @createTime 2016/5/12
     * @lastModify 2016/5/12
     * @param
     * @return
     */
    public String getAddressLine(Address address){
        String result = "";
        for (int i = 0; address.getAddressLine(i) != null; i++) {
            String addressLine = address.getAddressLine(i);
            result = result + addressLine;
        }
        return result;
    }

    /**
     * @className: LocationCallBack
     * @classDescription: 定位回调
     * @author: leibing
     * @createTime: 2016/5/12
     */
    public interface LocationCallBack{
        void setLocation(Location location);
        void setAddress(Address address);
    }
}

看上面代码可知,使用LocationProvider方法设置Location定位方法并在onLocationChanged监听方法中拿到Location,有同学会问,如果不移动是不是拿不到Location,定位经纬度会飘还有就是在mLocationManager.requestLocationUpdates方法中可以设置位置刷新距离参数,把这个距离参数设置足够小,就能实时地拿到当前经纬度坐标。
从定位工具类中可知,优先是考虑GPS定位的,如果GPS定位 disabled,改用网络定位。

第五步写Demo Activity类,代码如下:
package com.demo.location;

import android.location.Address;
import android.location.Location;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    /**
     * 经度显示控件
     */
    private TextView longitudeTv;

    /**
     * 纬度显示控件
     */
    private TextView latitudeTv;

    /**
     * 地址显示控件
     */
    private TextView addressTv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // FindViewById
        longitudeTv = (TextView) findViewById(R.id.tv_longitude);
        latitudeTv = (TextView) findViewById(R.id.tv_latitude);
        addressTv = (TextView) findViewById(R.id.tv_address);
        // 获取定位信息
        LocationUtils.getInstance(this).getLocation(new LocationUtils.LocationCallBack() {
            @Override
            public void setLocation(Location location) {
                if (location != null){
                    longitudeTv.setText("经度:" + String.valueOf(location.getLongitude()));
                    latitudeTv.setText("纬度:" + String.valueOf(location.getLatitude()));
                    LocationUtils.getInstance(MainActivity.this).getAddress(location.getLatitude(),
                            location.getLongitude());
                }
            }

            @Override
            public void setAddress(Address address) {
                if (address != null){
                    addressTv.setText(
                            "国家:" + address.getCountryName() + "\n"
                                    + "城市名:" + address.getLocality() + "\n"
                                    + "周边信息:" + LocationUtils.getInstance(MainActivity.this).
                                    getAddressLine(address));
                }
            }
        });
    }
}
第六步 运行Location Demo,运行结果如下:

这里写图片描述

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android中的Location是一个常用的功能,可以通过经纬度获取天气信息,或者获取所在地区的详细地址。在Android开发中,可以使用LocationManager来获取Location,通常可以通过GPS或WIFI来获取位置信息。\[2\] 要在Android中使用Location功能,需要进行一些设置。首先,需要在AndroidManifest.xml文件中添加权限,例如ACCESS_FINE_LOCATION权限。\[3\]然后,可以使用LocationManager来获取位置信息,并进行相应的处理。具体的实现可以参考相关的教程和文档,例如参考\[1\]中提供的Android接入Google地图的教程。 总之,Android中的Location功能可以帮助开发者获取设备的位置信息,从而实现一些基于位置的功能。 #### 引用[.reference_title] - *1* [Android定位功能实现](https://blog.csdn.net/weixin_40239288/article/details/125199850)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Android 高手进阶教程(十四)之----Android Location的使用!!](https://blog.csdn.net/weixin_30487317/article/details/97207236)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值