【Android -- 项目必备】APP 实现定位功能

在这里插入图片描述

前言

Android 开发中。常需要用到定位功能,尤其是依赖于地理位置功能的应用。非常多人喜欢使用百度地图,高德地图提供的SDK。开放 API,可是在只须要经纬度,或者城市,街道地址等信息。并不须要提供预览地图,地图界面的应用中。这时,不须要使用百度地图、高德地图。这样做只加大 apk 的体积。

今天讲讲怎样利用 LocationManager 获取经纬度,并利用 Geocoder 将经纬度转换为城市街道等信息。

1. 添加权限

 	<!-- 定位权限 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

2. 定位大致分为三大类

  • GPS 定位
    需要GPS硬件支持,直接和卫星交互来获取当前经纬度。
    优点:速度快、精度高、可在无网络情况下使用。
    缺点:首次连接时间长、只能在户外已经开阔地使用,设备上方有遮挡物就不行了、比较耗电。

  • 网络定位
    优点:它的优势在于收环境影响较小
    缺点: 首先需要消耗流量、其实精度没有GPS那么准确,大概在十几米到几十米之间。

3. 实例代码

在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv_location"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:onClick="doClick"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
public class MainActivity extends AppCompatActivity {
    
    

    private List<Address> result;

    private TextView mLocation;

    private static final int WHAT_LOCATE = 3;

    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler(){
    
    
        @Override
        public void handleMessage(@NonNull Message msg) {
    
    
            if (msg.what == WHAT_LOCATE) {
    
    
                String location = result.get(0).getLocality();
                Log.e("TAG", "当前定位的城市: " + location);

                mLocation.setText("当前定位的城市: " + location);
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mLocation = findViewById(R.id.tv_location);
    }

    /**
     * 定位获取当前城市
     */
    private void location() {
    
    
        LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
        Criteria criteria = new Criteria();
        criteria.setAltitudeRequired(false);
        criteria.setBearingRequired(false);
        criteria.setCostAllowed(false);
        criteria.setPowerRequirement(Criteria.POWER_LOW);
        criteria.setAccuracy(Criteria.ACCURACY_COARSE);
        String providerName = "";
        List<String> providerList = locationManager.getProviders(true);
        if (providerList.contains(LocationManager.NETWORK_PROVIDER)){
    
    
            providerName = LocationManager.NETWORK_PROVIDER;
        }else if (providerList.contains(LocationManager.GPS_PROVIDER)){
    
    
            providerName = LocationManager.GPS_PROVIDER;
        }else {
    
    
            Toast.makeText(MainActivity.this,"provider 获取失败",Toast.LENGTH_SHORT).show();
            return;
        }
        // 权限复验
        if (ActivityCompat.checkSelfPermission(MainActivity.this,
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                ActivityCompat.checkSelfPermission(MainActivity.this,
                        Manifest.permission.ACCESS_COARSE_LOCATION)
                        != PackageManager.PERMISSION_GRANTED) {
    
    
            Toast.makeText(MainActivity.this,"权限未授权,请先授权UHello定位权限",Toast.LENGTH_SHORT).show();
            return;
        }
        Location location = locationManager.getLastKnownLocation(providerName);
        if (location != null){
    
    
            final double longitude = location.getLongitude();// 经度
            final double latitude = location.getLatitude();// 纬度
            Log.e("TAG", "longitude = " + longitude);
            Log.e("TAG", "latitude = " + latitude);

            // 因为这里 Geocoder对象的 getFromLocation 方法,源码说明中建议在工作线程执行 getFromLocation方法
            new Thread(){
    
    
                @Override
                public void run() {
    
    
                    super.run();
                    try {
    
    
                        Geocoder geocoder = new Geocoder(MainActivity.this, Locale.getDefault());
                        result = geocoder.getFromLocation(latitude, longitude, 1);
                        mHandler.sendEmptyMessage(WHAT_LOCATE);
                    }catch (Exception e){
    
    
                        e.printStackTrace();
                    }
                }
            }.start();
        }else {
    
    
            Toast.makeText(MainActivity.this,"UHello 定位失败",Toast.LENGTH_SHORT).show();
        }

    }

    public void doClick(View view) {
    
    
        location();
    }
}

猜你喜欢

转载自blog.csdn.net/duoduo_11011/article/details/126872088