Android 原生定位开发(解决个别手机定位失败问题)

这篇具有很好参考价值的文章主要介绍了Android 原生定位开发(解决个别手机定位失败问题)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。



前言

在android开发中地图和定位是很多软件不可或缺的内容,这些特色功能也给人们带来了很多方便。定位一般分为三种发方案:即GPS定位、Google网络定位以及基站定位。


本文分别介绍GPS定位、以及基于Google的网络Wifi定位的详细步骤,(小米手机获取位置信息locationManager.getLastKnownLocation(provider)的Location一直为空,查了资料换了种获取手机getProviders的方式就可以了)

一、实现步骤

一般来说我们实现原生定位的流程大概是:先判断有无权限》有权限启动一个LocationSrevice去获取定位》最后携带所需的定位信息返回,进行开发。

二、使用步骤

1.服务启动工具类

代码如下(示例):大概步骤如下,权限请求可自定义开发关键的是LocationService

/**
 * 获取定位
 */
public class MyLocationManager implements LocationService.LocationCallBack {
    private Activity context;
    private OnLocationListener onLocationListener;
    private String[] stringsLocation = new String[]{Permission.ACCESS_FINE_LOCATION, Permission.ACCESS_COARSE_LOCATION};

    @Override
    public void Location_Return(double Location_latitude, double Location_longitude, String province, String city, String area, String featureName) {
        onLocationListener.OnLocation(Location_latitude, Location_longitude, province, city, area, featureName);
    }

    public interface OnLocationListener {
        void OnLocation(double Location_latitude, double Location_longitude, String province, String city, String area, String featureName);
    }

    public void setOnLocationListener(OnLocationListener onLocationListener) {
        this.onLocationListener = onLocationListener;
    }

    public MyLocationManager(@NonNull Activity context) {
        this.context = context;
        if (!XXPermissions.isGranted(context, stringsLocation)) {
            MessageDialog codeDialog = new MessageDialog(context, "位置信息权限使用说明", "为确保你能在******内使用位置信息******,******需要获取你的位置信息权限。允许后,你可以随时通过手机系统设置对授权进行管理。", "取消", "去授权");
            codeDialog.setCancelable(false);
            codeDialog.show();
            codeDialog.setOnSumbitTextCodeListener(() -> {
                doMainPermission();
                codeDialog.dismiss();
            });
            codeDialog.setOnCancelListener(() -> {
                codeDialog.dismiss();
            });
        } else {
            initData();
        }

    }

    private void doMainPermission() {
        XXPermissions.with(context).permission(stringsLocation).request(new OnPermissionCallback() {
            @Override
            public void onGranted(@NonNull List<String> permissions, boolean allGranted) {
                if (allGranted) {
                    initData();
                }
            }

            @Override
            public void onDenied(@NonNull List<String> permissions, boolean doNotAskAgain) {
                if (doNotAskAgain) {

                }
            }
        });
    }

    @SuppressLint("MissingPermission")
    private void initData() {
        // 创建 Service 实例
        LocationService myService = new LocationService();
        // 设置回调接口
        myService.setCallback(this);
        // 启动 Service 并执行操作
        Intent serviceIntent = new Intent(context, LocationService.class);
        context.startService(serviceIntent);
    }
}
/**-------------------------/
不要忘了注册
      <service
            android:name=".utils.LocationService"
            android:enabled="true"
            android:exported="false" />

2.实现LocationService

代码如下(示例):

/**
 * 获取定位服务
 */
public class LocationService extends Service {
    private LocationManager locationManager;
    private MyLocationListener myLocationListener;
    public static LocationCallBack mCallBack = null;

    public interface LocationCallBack {
        void Location_Return(double Location_latitude, double Location_longitude, String province, String city, String area, String featureName);
    }

    public void setCallback(LocationCallBack callback) {
        this.mCallBack = callback;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @SuppressLint("MissingPermission")
    @Override
    public void onCreate() {
        super.onCreate();
        myLocationListener = new MyLocationListener();
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        try {
            GPSLocation();
        } catch (Exception e) {
            if (ObjectUtils.isNotEmpty(locationManager) && ObjectUtils.isNotEmpty(myLocationListener))
                locationManager.removeUpdates(myLocationListener); // 停止所有的定位服务
            stopSelf();  // 获取到经纬度以后,停止该service
        }
    }

    class MyLocationListener implements LocationListener {
        // 位置改变时获取经纬度
        @Override
        public void onLocationChanged(Location location) {
            if (ObjectUtils.isNotEmpty(location)) {
                toGeocoder(location);
            }
        }

        // 状态改变时
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
        }

        // 提供者可以使用时
        @Override
        public void onProviderEnabled(String provider) {
        }

        // 提供者不可以使用时
        @Override
        public void onProviderDisabled(String provider) {
        }

    }
/*
**系统内容提供器介绍
**一共为四种方式"passive","network","fused","gps"
** "gps":GPS_PROVIDER(GNSS) GNSS HAL 接口和芯片打交道
** "network":NETWORK_PROVIDER 依赖设备厂商的具体实现,Android 默认实现依赖 Google 提供的 GMS **  实现国内无法使用;一般厂商会实现为通过基站 / WIFI / 蓝牙进行融合定位
** "fused":调用 GMS(谷歌移动服务) 进行定位,国内用不了
** "passive":使用 PassiveProvider 在系统位置更新时通知给应用,分享其他 PROVIDER 的定位结果
*/
    @SuppressLint("MissingPermission")
    private Location getLastKnownLocation(LocationManager locationManager) {
        Location bestLocation = null;
        List<String> providers = locationManager.getProviders(true);
         //由于国内用不了fused 剔除他
        if (providers.contains("fused")) providers.remove("fused");
        //这里我们按照首字母排序,使内容提供者调用顺序为gps network passive
        Collections.sort(providers);
        LogUtils.e("provider:" + GsonUtils.toJson(providers));
        for (String provider : providers) {
            Location location = locationManager.getLastKnownLocation(provider);
            if (ObjectUtils.isEmpty(location)) {
                LogUtils.e(provider + "定位服务不可用");
                //执行下一个
                continue;
            } else {
                bestLocation = location;
                LogUtils.e(provider + "定位服务成功");
                //定位成功返回
                break;
            }
        }
        return bestLocation;
    }
    @SuppressLint("MissingPermission")
    private void GPSLocation() {
        Location location = getLastKnownLocation(locationManager);
        if (location != null) {
            //不为空,显示地理位置经纬度
            String longitude = "Longitude:" + location.getLongitude();
            String latitude = "Latitude:" + location.getLatitude();
            LogUtils.e("Location:" + longitude + latitude);
            toGeocoder(location);
        } else {
            LogUtils.e("Location:" + "Location为空");
            if (ObjectUtils.isNotEmpty(locationManager) && ObjectUtils.isNotEmpty(myLocationListener))
                locationManager.removeUpdates(myLocationListener); // 停止所有的定位服务
            stopSelf();  // 获取到经纬度以后,停止该service
        }
    }

    @SuppressLint("MissingPermission")
    private void toGeocoder(Location location) {
        String province = "";
        String city = "";
        String area = "";
        String featureName = "";
        try {
            Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
            List<Address> addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
            if (ObjectUtils.isNotEmpty(addresses) && 0 < addresses.size()) {
                Address address = addresses.get(0);
                if (ObjectUtils.isNotEmpty(address)) {
                    // 获取省份(province)
                    province = address.getAdminArea();
                    // 获取城市(City)
                    city = address.getLocality();
                    // 获取区县(area)
                    area = address.getSubLocality();
                    //  获取详细地址
                    featureName = address.getFeatureName();
                    // 获取街道地址
                    String addressLine = address.getAddressLine(0);
                    // 打印详细地址信息
                    LogUtils.e("AddressInfo", "province: " + province);
                    LogUtils.e("AddressInfo", "City: " + city);
                    LogUtils.e("AddressInfo", "area: " + area);
                    LogUtils.e("AddressInfo", "FeatureName: " + featureName);
                    LogUtils.e("AddressInfo", "Address Line: " + addressLine);
                }
                mCallBack.Location_Return(location.getLatitude(), location.getLongitude(), province, city, area, featureName);
            }
            if (ObjectUtils.isNotEmpty(locationManager) && ObjectUtils.isNotEmpty(myLocationListener))
                locationManager.removeUpdates(myLocationListener); // 停止所有的定位服务
            stopSelf();  // 获取到经纬度以后,停止该service
        } catch (Exception e) {
            if (ObjectUtils.isNotEmpty(locationManager) && ObjectUtils.isNotEmpty(myLocationListener))
                locationManager.removeUpdates(myLocationListener); // 停止所有的定位服务
            stopSelf();  // 获取到经纬度以后,停止该service
            e.printStackTrace();
        }
    }

    @SuppressLint("MissingPermission")
    @Override
    public void onDestroy() {
        super.onDestroy();
        if (ObjectUtils.isNotEmpty(locationManager) && ObjectUtils.isNotEmpty(myLocationListener))
            locationManager.removeUpdates(myLocationListener); // 停止所有的定位服务
        stopSelf();
    }

}

该处使用原生定位获取经纬度、省市县等数据的详细步骤。


总结

以上就是今天要讲的使用Android原生获取定位内容,本文详细展现了完整流程,希望对大家会有帮助,公司如果有实力大可不必如此,直接给第三方地图交钱就好了,毕竟人家又快又准(本文仅仅适用于只需经纬度或者地址信息的同学,有地图展现需求的只能想别的方法了哈哈)。文章来源地址https://www.toymoban.com/news/detail-735340.html

到了这里,关于Android 原生定位开发(解决个别手机定位失败问题)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 解决高通 Android 12/13 ota升级失败问题

    1、 Android adb push ota全量包 如下图所示 2、当前设备是a分区 如下图所示  3、adb root -adb enable-verity-adb reboot  如下图所示  4、adb ota包升级成功 升级完成之后记得 reboot 重启一下 如下图所示 5、当前设备成功切换b分区 如下图所示  6、到这里基本就结束了, ota 升级相关 Andr

    2024年02月06日
    浏览(52)
  • 远程桌面连接不上个别服务器的问题分析与解决方案

    在日常的IT运维工作中,远程桌面连接(RDP,Remote Desktop Protocol)是我们经常使用的工具之一,用于管理和维护远程服务器。然而,有时我们可能会遇到无法连接到个别服务器的情况。针对这一问题,我将从多个角度进行分析,并提供相应的解决方案。 一、问题分析 远程桌面

    2024年04月28日
    浏览(39)
  • 解决Android Studio的模拟器运行失败的问题

     前面搭建了Android Studio的开发环境,第一次安装在默认路径下。新建工程之后想用模拟器运行测试一下,但是模拟器总是运行不成功。在网上也按照一些建议,重新安装HAXM,怎么折腾都不成功。 后来,干脆卸载了Android Studio,重新安装,并指定路径到E盘下,进行正常的设定

    2024年02月14日
    浏览(44)
  • 【问题解决】Android Studio 无法连接手机(荣耀90)无法识别手机usb

    问题描述: 使用AS调试的时候遇到一个问题,由于是重装后的电脑,什么都没配置,但是两个旧手机都在安装SDK tools里的Google usb driver后直接连上AS,而我的新手机却死活连不上,查了一下午,啥方法都试了,还是连不上 问题解决: 最终发现在开发人员选项-网络 里面有一个

    2024年02月07日
    浏览(63)
  • Android Studio 无法安装apk到小米手机问题解决

    以前开发都是用自己的samsung手机,打开开发者选项和usb调试,直接可以连上Android Studio,进行调试,后来我的samsung退伍了,换上了Apple,就无法使用了,用公司的小米手机打开开发者选项和usb调试,然后进行调试,将apk安装小米手机安装应用报错(Failed to establish session Erro

    2024年02月15日
    浏览(58)
  • android 获取手机当前时区,解决时间偏移量和夏令时差问题

     //获取当前时区     public static int getTimeZone() {         Date date=new Date();         //取得本地时间         Calendar cal = Calendar.getInstance();         //取得时间偏移量         int offset = cal.get(Calendar.ZONE_OFFSET)/(1000*60*60);         //取得夏令时差         int dstOffset=cal.get(Calenda

    2024年02月08日
    浏览(35)
  • uniapp,小程序获取定位,打开地图选择位置失败问题

    场景: 调用api报错 chooseLocation:fail the api need to be declared in the requiredPrivateInfos field in app.json/ext.json 说明: 1.以下 8 个接口需完成准入开通流程:getFuzzylocation、getLocation、onLocationChange、chooseAddress、choosePoi、chooseLocation、startLocationUpdate、startLocationUpdateBackground 首先需要开通权限

    2024年02月13日
    浏览(27)
  • HarmonyOS开发:解决DevEco Studio低版本导入高版本项目运行失败问题

    基于 DevEco Studio 4.0 Beta2,hvigorVersion为3.0.2 ,开发了一个项目,上传到了远程仓库,当同事下载后,却始终无法运行,频繁报错,由于API都是使用的9,第一感觉就是开发环境不同,于是,让其发来了他的开发环境, DevEco Studio 3.1.1 Release,hvigorVersion为2.4.2 ,果然是环境不同

    2024年02月05日
    浏览(33)
  • 关于腾讯地图geolocation.getLocation 经常定位失败,定位时间过长的解决方法

    今天遇到个项目,腾讯地图定位出现问题,导致地图无法呈现出最近的目标  这是正常的效果,之前一直出现贵州等地点的信息,查看控制台的网络后,发现腾讯的定位失败,要么就是定位时间过长,要20S左右,但是换EDGE浏览器却能正常加载, 除了EDGE浏览器都会出现这个问

    2024年02月03日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包