【原创】通过Android自带的工具实现当前定位 + 2步搞定getBestProvider返回null的问题

通过Android自带的工具实现当前定位 + 2步搞定getBestProvider返回null的问题

今天用Android自带的LocationManager和Location类实现定位,然而中间却出了点问题,那就是getBestProvider在真机上测试返回null值。查阅了很多方法都没有效果,于是我自己灵机一动想出了较好的解决办法。

基本代码如下

import .... //导入包就不写了
public class MainActivity extends AppCompatActivity {  
    //设置权限用的
    private static final int BAIDU_READ_PHONE_STATE = 100;//定位权限请求
    private static final int PRIVATE_CODE = 1315;//开启GPS权限
    private static final String perms[] = {
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.INTERNET
    };
    //监听类实现动态获取当前位置
    private LocationListener locationListener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            Toast.makeText(MainActivity.this, "long= " + location.getLongitude() + " latitude= " + location.getLatitude(), Toast.LENGTH_LONG).show();
            //根据个人需要添加动态获取位置的代码块
        }
 	@Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
        }
        @Override
        public void onProviderEnabled(String provider) {
        }
        @Override
        public void onProviderDisabled(String provider) {
        }
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    	...
    	getMyLocation(this);//获取当前位置的方法
    }
    public void getMyLocation(Context context){
        LocationManager lm = (LocationManager)context.getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
        // 检查是否有相关定位权限
        if(!checkPermission(context)){
            Toast.makeText(context, "请打开权限", Toast.LENGTH_SHORT).show();
            return;
        }
        //定位要求
        Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_FINE);//高精度
        criteria.setAltitudeRequired(false);
        criteria.setBearingRequired(false);
        criteria.setCostAllowed(true);
        criteria.setPowerRequirement(Criteria.POWER_LOW); // 低功耗
        List<String> provider = lm.getProviders(true); // 获取GPS信息
//        String provider = lm.getBestProvider(criteria,true); // 获取GPS信息
        Location location = null;
        int i = 0;
        do {
            location = lm.getLastKnownLocation(provider.get(i));
            lm.requestLocationUpdates(provider.get(i), 1000, 0,
                    locationListener);
            i++}while(location == null && i<provider.size());
        if(i == provider.size()){
            new AlertDialog.Builder(MainActivity.this).setTitle("WRONG").setMessage("请打开gps或者网络")
                    .setCancelable(false).setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            return;
                        }
                    }).create().show();
        }
        //打印结果
        Toast.makeText(context, "long= " + location.getLongitude() + " latitude= " + location.getLatitude(), Toast.LENGTH_LONG).show();
    }
}

注意了,在getMyLocation方法中,我注释掉了一句代码,那就是:

	 // String provider = lm.getBestProvider(criteria,true); // 获取GPS信息

为什么要注释掉这句话呢,我测试过在大部分情况下getBestProvider方法返回的都是"gps"(也就是说provider的值为"gps")然而gps不总是那么靠谱,有时候会“挂掉”,因此我在这里选择了另一种方法,那就是遍历所有可用的Provider之后当location的值不为null时结束遍历,代码如下:

	List<String> provider = lm.getProviders(true); // 获取GPS信息
        Location location = null;
        int i = 0;
        do {
            location = lm.getLastKnownLocation(provider.get(i));
            lm.requestLocationUpdates(provider.get(i), 1000, 0,
                    locationListener);
        }while(location == null && i<provider.size());
       

最后放上检查权限的代码

public boolean checkPermission(Context context){
        LocationManager lm = (LocationManager)context.getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
        boolean ok = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
        if(ok){
            //如果sdk版本大于23也就是android6.0版本以上就要手动添加权限
            if(Build.VERSION.SDK_INT>=23){
                if(ContextCompat.checkSelfPermission(context,perms[0])!=PERMISSION_GRANTED){
                    ActivityCompat.requestPermissions(MainActivity.this,perms,BAIDU_READ_PHONE_STATE);
                }else{
                    return true;
                }
            //其他版本的android 就不需要添加权限直接返回true;
            }else{
                return true;
            }
        }else{
            Toast.makeText(this, "系统检测到未开启GPS定位服务,请开启", Toast.LENGTH_SHORT).show();
            Intent intent = new Intent();
            intent.setAction(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivityForResult(intent, PRIVATE_CODE);
            return false;
        }
        return true;
    }

——————————————结束语————————————————
有问题欢迎大家在留言区留言

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
Android获取大致定位可以使用网络定位或基站定位。 网络定位是通过手机连接的Wi-Fi网络或移动数据网络来确手机的位置。Android系统提供了一个名为LocationManager的类,可以通过它来获取网络定位信息。 基站定位是通过手机连接的基站信号来确手机的位置,这种定位方式比较粗略,但是耗电少。Android系统也提供了获取基站定位信息的API。 以下是获取网络定位的示例代码: ``` LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_COARSE); // 设置精度要求为粗略 String provider = locationManager.getBestProvider(criteria, true); // 获取最佳的位置提供器 Location location = locationManager.getLastKnownLocation(provider); // 获取最后一次定位信息 ``` 获取基站定位的示例代码: ``` TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); GsmCellLocation cellLocation = (GsmCellLocation) telephonyManager.getCellLocation(); int cellId = cellLocation.getCid(); // 获取基站ID int lac = cellLocation.getLac(); // 获取位置区域码 ``` 需要注意的是,获取位置信息需要在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_NETWORK_STATE"/> ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zygswo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值