文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android之 获取定位信息总结

2023-09-11 16:51

关注

一,概述:

1  android原生是有定位api的,但稳定性和准确度远远不够,所以通常需要借助三方SDK获取位置信息

2 国内SDK选择性较多,百度,腾讯,高德等定位api,但都是需要在平台建立应用,配置key的,包括基础的定位。

3 国外普遍的用google定位api和google地图,google定位是免费的,但地图是需要key的,包括地理编码webapi接口都需要key

4 国内就不说了,基本没限制,用哪个厂家的SDK都可以,我们主要说下不采用国内的SDK的方案

二,Android原生定位

1 定位普遍采用网络定位或者GPS定位,两者区别也比较大

GPS定位精确度高;但仅能在户外使用,获取定位信息速度慢,耗费电池
Network定位户内户外都能使用,定位速度快,电量耗费低;但精确度不太高

2 原生定位实践

public class AndroidLocationActivity extends Activity {    private static final String TAG = "MainActivity";    private Button btnLocation;    private TextView tvResult;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_location);        btnLocation = (Button) findViewById(R.id.btn_location);        tvResult = (TextView) findViewById(R.id.tv_result);        btnLocation.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                checkLocationServiceOpen();            }        });    }    //检查定位服务是否开启    private void checkLocationServiceOpen() {        if (isLocServiceEnable(this) && isLocServiceEnable(this, 1)) {            initLocation();        } else {            Intent intent = new Intent();            intent.setAction(Settings.ACTION_LOCATION_SOURCE_SETTINGS);            startActivityForResult(intent, LOCATION_SERVICCE);        }    }        private final static int LOCATION_SERVICCE = 1;// 定位    private final int REQUEST_CHECK_SETTINGS = 2;//google权限设置    public boolean isLocServiceEnable(Context context) {        int locationMode = 0;        String locationProviders;        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {            try {                locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);            } catch (Settings.SettingNotFoundException e) {                e.printStackTrace();                return false;            }            return locationMode != Settings.Secure.LOCATION_MODE_OFF;        } else {            locationProviders = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);            return !TextUtils.isEmpty(locationProviders);        }    }        public boolean isLocServiceEnable(Context context, int type) {        LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);        boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);        boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);        if (gps || network) {            return true;        }        return false;    }    public void initLocation() {        AndPermission.with(this)                .runtime()                .permission(Permission.Group.LOCATION)                .onGranted(new Action>() {                    @Override                    public void onAction(List permissions) {                        Log.e(TAG, "onAction: " + "开始定位");                        startLocation();                    }                })                .onDenied(new Action>() {                    @Override                    public void onAction(@NonNull List permissions) {                        Log.e(TAG, "onAction: " + "定位失败");                        startLocation();//                        // 判断用户是不是不再显示权限弹窗了,若不再显示的话进入权限设置页//                        if (AndPermission.hasAlwaysDeniedPermission(mContext, permissions)) {//// 打开权限设置页//AndPermission.permissionSetting(mContext).start();//return;//                        }                    }                })                .start();    }    private LocationManager locationManager;    public void startLocation() {        try {            if (locationManager == null) {                locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);            }            Criteria criteria = new Criteria();            criteria.setAltitudeRequired(true);            String bestProvider = locationManager.getBestProvider(criteria, false);            Log.e(TAG, "最佳的定位方式:" + bestProvider);            //最佳定位方式LocationManager.GPS_PROVIDER LocationManager.NETWORK_PROVIDER            locationManager.requestLocationUpdates(bestProvider, 0, 0, myLocationListener);        } catch (SecurityException e) {            e.printStackTrace();        }    }    private LocationListener myLocationListener = new LocationListener() {        @Override        public void onLocationChanged(final Location location) {            locationManager.removeUpdates(myLocationListener);            setLocationResult(location);        }        @Override        public void onStatusChanged(String provider, int status, Bundle extras) {        }        @Override        public void onProviderEnabled(String provider) {        }        @Override        public void onProviderDisabled(String provider) {        }    };    private void setLocationResult(Location location) {        if (location == null) {            tvResult.setText("定位失败");            return;        }        long time = location.getTime();        float accuracy = location.getAccuracy();//获取精确位置        double altitude = location.getAltitude();//获取海拔        double latitude = location.getLatitude();//获取纬度,平行        double longitude = location.getLongitude();//获取经度,垂直        StringBuffer sb = new StringBuffer();        sb.append("time : ");        sb.append(time);        sb.append("\nlatitude : ");        sb.append(latitude);        sb.append("\nlontitude : ");        sb.append(longitude);        Log.e(TAG, "Android定位:\n"+sb.toString() + "\n\n");        tvResult.setText("Android定位:\n"+sb.toString() + "\n\n");        geocoderAddress(location);    }    //获取地址信息:城市、街道等信息    public void geocoderAddress(Location location) {        try {            if (location != null) {                Geocoder gc = new Geocoder(this, Locale.getDefault());                List
result = gc.getFromLocation(location.getLatitude(), location.getLongitude(), 1); Log.e(TAG, "获取地址信息:" + result.toString()); } } catch (Exception e) { e.printStackTrace(); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == LOCATION_SERVICCE) {//开启定位服务 if (isLocServiceEnable(this) && isLocServiceEnable(this, 1)) { checkLocationServiceOpen(); } } else if (requestCode == REQUEST_CHECK_SETTINGS) { switch (resultCode) { case Activity.RESULT_OK: // All required changes were successfully made Log.e("locationSettingCallback", "RESULT_OK"); startLocation(); break; case Activity.RESULT_CANCELED: Log.e("locationSettingCallback", "RESULT_CANCELED"); // The user was asked to change settings, but chose not to// googleLocationStar();// checkLocationPermission(); break; default: break; } } }}

注意:

Geocoder的使用

1,Geocoder该类用于获取地理位置的前向编码和反向编码,前向编码是根据地址获取经纬度;反向编码是根据经纬度获取对应的详细地址

2,Geocoder 请求的是一个后台服务,但是该服务不包括在标准android framework中,因此如果当前设备不包含location services,则Geocoder返回的地址或者经纬度为空。大部分手机可能都用不了,不支持的会闪退,做好异常处理

监听设置
设置成功后需要取消监听,否则下载再定位不会更新位置
locationManager.removeUpdates(myLocationListener);

三 google定位实践

1 用google限制比较大

  • 首先手机要支持google服务,但国产手机由于各厂家的定制化严重,基本上都不会默认带google服务
  • 手机网络需要VPN,不然也用不了国外的服务

2 解决限制的方法

安装google三件套,谷歌服务框架、商店和google账户管理程序,方法可以自己去搜。同时安装翻网工具,这个也自己去搜

2 示例

module级build.gradle添加定位依赖

implementation 'com.google.android.gms:play-services-location:18.0.0'

在清单文件添加权限

               

 java源码

public class GoogleLocationActivity extends Activity {    private static final String TAG = "MainActivity";    private Button btnLocation;    private TextView tvResult;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_location);        btnLocation = (Button) findViewById(R.id.btn_location);        tvResult = (TextView) findViewById(R.id.tv_result);        btnLocation.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                checkLocationServiceOpen();            }        });    }    //检查定位服务是否开启    private void checkLocationServiceOpen() {        if (isLocServiceEnable(this) && isLocServiceEnable(this, 1)) {            initLocation();        } else {            Intent intent = new Intent();            intent.setAction(Settings.ACTION_LOCATION_SOURCE_SETTINGS);            startActivityForResult(intent, LOCATION_SERVICCE);        }    }        private final static int LOCATION_SERVICCE = 1;// 定位    private final int REQUEST_CHECK_SETTINGS = 2;//google权限设置    public boolean isLocServiceEnable(Context context) {        int locationMode = 0;        String locationProviders;        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {            try {                locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);            } catch (Settings.SettingNotFoundException e) {                e.printStackTrace();                return false;            }            return locationMode != Settings.Secure.LOCATION_MODE_OFF;        } else {            locationProviders = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);            return !TextUtils.isEmpty(locationProviders);        }    }        public boolean isLocServiceEnable(Context context, int type) {        LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);        boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);        boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);        if (gps || network) {            return true;        }        return false;    }    public void initLocation() {        AndPermission.with(this)                .runtime()                .permission(Permission.Group.LOCATION)                .onGranted(new Action>() {                    @Override                    public void onAction(List permissions) {                        Log.e(TAG, "onAction: " + "开始定位");                        initGooglePlayService();                    }                })                .onDenied(new Action>() {                    @Override                    public void onAction(@NonNull List permissions) {                        Log.e(TAG, "onAction: " + "定位失败");                        initGooglePlayService();//                        // 判断用户是不是不再显示权限弹窗了,若不再显示的话进入权限设置页//                        if (AndPermission.hasAlwaysDeniedPermission(mContext, permissions)) {//// 打开权限设置页//AndPermission.permissionSetting(mContext).start();//return;//                        }                    }                })                .start();    }    //连接google服务    private void initGooglePlayService() {        GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this)                .addApi(LocationServices.API)                .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {                    @Override                    public void onConnected(@Nullable Bundle bundle) {                        Log.e(TAG, "onConnected");                        initGoogleLocation();                    }                    @Override                    public void onConnectionSuspended(int i) {                        Log.e(TAG, "onConnectionSuspended" + "---i");                        //startBaiduLocation();                    }                })                .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {                    @Override                    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {                        Log.e(TAG, "onConnectionFailed---" + connectionResult.getErrorCode() + "---" + connectionResult.getErrorMessage());                        //startBaiduLocation();                    }                })                .build();        mGoogleApiClient.connect();    }    private LocationRequest locationRequest;    private void initGoogleLocation() {        try {            locationRequest = LocationRequest.create();//            locationRequest.setInterval(20000);//            locationRequest.setFastestInterval(10000);//            locationRequest.setNumUpdates(1);//            locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);            LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()                    .addLocationRequest(locationRequest);            SettingsClient client = LocationServices.getSettingsClient(this);            Task task = client.checkLocationSettings(builder.build());            task.addOnSuccessListener(this, new OnSuccessListener() {                @Override                public void onSuccess(LocationSettingsResponse locationSettingsResponse) {                    Log.e(TAG, "onSuccess");                    startLocation();                }            });            task.addOnFailureListener(this, new OnFailureListener() {                @Override                public void onFailure(@NonNull Exception e) {                    Log.e(TAG, "onFailure");                    if (e instanceof ResolvableApiException) {                        // Location settings are not satisfied, but this can be fixed                        // by showing the user a dialog.                        try {// Show the dialog by calling startResolutionForResult(),// and check the result in onActivityResult().ResolvableApiException resolvable = (ResolvableApiException) e;resolvable.startResolutionForResult(GoogleLocationActivity.this,        REQUEST_CHECK_SETTINGS);                        } catch (IntentSender.SendIntentException sendEx) {// Ignore the error.                        }                    }                }            });        } catch (Exception e) {        }    }    private Location lastKnownLocation;    private FusedLocationProviderClient locationProviderClient;    private void startLocation() {        // Construct a FusedLocationProviderClient.        if (locationProviderClient == null) {            locationProviderClient = LocationServices.getFusedLocationProviderClient(this);        }                try {            Task locationResult = locationProviderClient.getLastLocation();            locationResult.addOnCompleteListener(this, new OnCompleteListener() {                @Override                public void onComplete(Task task) {                    if (task.isSuccessful()) {                        // Set the map's camera position to the current location of the device.                        lastKnownLocation = task.getResult();                        if(lastKnownLocation!=null){updateLocation();                        }else {startNewLocation();                        }                    } else {                        Log.d(TAG, "Current location is null. Using defaults.");                        Log.e(TAG, "Exception: %s", task.getException());                    }                }            });        } catch (SecurityException e) {            Log.e(TAG, e.getMessage());        }    }    //开始google定位    private void startNewLocation() {        if (locationProviderClient == null) {            locationProviderClient = LocationServices.getFusedLocationProviderClient(this);        }        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {            // TODO: Consider calling            //    ActivityCompat#requestPermissions            // here to request the missing permissions, and then overriding            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,            //              int[] grantResults)            // to handle the case where the user grants the permission. See the documentation            // for ActivityCompat#requestPermissions for more details.            return;        }        Log.e(TAG, "startGoogleLocation11: " + "开始Google定位");        locationProviderClient.requestLocationUpdates(locationRequest,                locationCallback,                Looper.getMainLooper())                .addOnSuccessListener(new OnSuccessListener() {            @Override            public void onSuccess(Void unused) {                Log.e(TAG, "onSuccess: ");            }        });    }    //定期接受位置信息    LocationCallback locationCallback = new LocationCallback() {        @Override        public void onLocationResult(LocationResult locationResult) {            locationProviderClient.removeLocationUpdates(locationCallback);            lastKnownLocation=locationResult.getLastLocation();            updateLocation();        }        @Override        public void onLocationAvailability(@NonNull LocationAvailability locationAvailability) {            super.onLocationAvailability(locationAvailability);            Log.e(TAG, "数量3:"+locationAvailability.isLocationAvailable());        }    };    private void updateLocation(){        if (lastKnownLocation != null) {            StringBuffer sb = new StringBuffer();            sb.append("time : ");            sb.append(lastKnownLocation.getTime());            sb.append("\nlatitude : ");            sb.append(lastKnownLocation.getLatitude());            sb.append("\nlontitude : ");            sb.append(lastKnownLocation.getLongitude());            Log.e(TAG, "google定位:\n"+sb.toString() + "\n\n");            tvResult.setText("google定位:\n"+sb.toString() + "\n\n");        }    }    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        if (requestCode == LOCATION_SERVICCE) {//开启定位服务            if (isLocServiceEnable(this) && isLocServiceEnable(this, 1)) {                checkLocationServiceOpen();            }        } else if (requestCode == REQUEST_CHECK_SETTINGS) {            switch (resultCode) {                case Activity.RESULT_OK:                    // All required changes were successfully made                    Log.e("locationSettingCallback", "RESULT_OK");                    startLocation();                    break;                case Activity.RESULT_CANCELED:                    Log.e("locationSettingCallback", "RESULT_CANCELED");                    // The user was asked to change settings, but chose not to//                    googleLocationStar();//                    checkLocationPermission();                    break;                default:                    break;            }        }    }}

3 注意:

流程上可以先调android原生->再调google最后一次位置->没最后位置就更新位置来确保能获取到定位信息。

4 一定要先请求位置权限,不然会报无权限

 3.5 定位精度可以去掉,经尝试加上的话室内一直加载失败

locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

四 总结

国内哪个都可以,国外可以原生和google共用,毕竟google限制条件多,对定位要求不高可以用原生,要求高只能用google定位了

来源地址:https://blog.csdn.net/qq_29848853/article/details/129636031

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯