简体   繁体   English

手机重启后Android获取位置为空

[英]Android get location is null after phone reboot

In my app im getting the phone's location via this function, but when I restart the phone and start the app I get null from this method.在我的应用程序中,我通过此功能获取手机的位置,但是当我重新启动手机并启动应用程序时,我从该方法中获得了空值。 Is there something that im missing or doing wrong?有什么我遗漏或做错的吗? What should I do to fix this issue?我应该怎么做才能解决这个问题?

Here is the function im using:这是我使用的函数:

public void getAddress() {
        Log.v("--", "get address 1");
        boolean isGPSProviderEnabled = locationManager
                .isProviderEnabled(LocationManager.GPS_PROVIDER);
        boolean network_enabled = locationManager
                .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        Log.v("--", "get address 31 " + isGPSProviderEnabled + " gps  -  "
                + isConnectedToNetwork());

        if (isGPSProviderEnabled || network_enabled) {
            Log.v("--", "get address 2");
            Criteria c = new Criteria();
            Log.v("--", "provider " + locationManager.getBestProvider(c, true));
            locationManager.requestSingleUpdate(
                    locationManager.getBestProvider(c, true),
                    mLocationListener, Looper.myLooper());
            location = locationManager.getLastKnownLocation(locationManager
                    .getBestProvider(c, true));
            if (location == null) {
                Log.v("--", "get address 6");
                // TODO check if this is working
                locationManager.requestSingleUpdate(
                        locationManager.getBestProvider(c, true),
                        mLocationListener, Looper.myLooper());
                locationManager.requestLocationUpdates(
                        locationManager.getBestProvider(c, true), 0, 0,
                        mLocationListener);
                Location oldLocation = new Location("");
                oldLocation.setLatitude(new Double(prefs.getString(
                        Constants.LATITUDE, "48.51")));
                oldLocation.setLongitude(new Double(prefs.getString(
                        Constants.LONGITUDE, "2.20")));
                populateList(oldLocation);
                // locationManager.requestLocationUpdates(
                // locationManager.getBestProvider(c, true), 1000, 100,
                // mLocationListener);
            } else {
                Log.v("--", "get address 3");
                if (isConnectedToNetwork()) {
                    new AsyncTask<Void, Void, Void>() {
                        protected Void doInBackground(Void... params) {
                            try {
                                com.quanticapps.athan.utils.Geocoder geocoder = new com.quanticapps.athan.utils.Geocoder(
                                        Main.this);
                                GeocoderModel geocoderModel = geocoder
                                        .getFromLocation(
                                                location.getLatitude(),
                                                location.getLongitude(), 5);
                                city = geocoderModel.getCity();
                                country = geocoderModel.getCountry();
                                prefs.edit().putString(Constants.CITY, city)
                                        .apply();
                                Log.v("--", "get address 4");
                            } catch (IOException e) {
                                Log.v("--", "get address 11");
                                e.printStackTrace();
                            } catch (LimitExceededException e) {
                                Log.v("--", "get address 12");
                                e.printStackTrace();
                            }
                            return null;
                        };

                        protected void onPostExecute(Void result) {
                            prefs.edit().putString(Constants.COUNTRY, country)
                                    .apply();
                            prefs.edit().putString(Constants.CITY, city)
                                    .apply();
                            populateList(location);
                        };
                    }.execute();
                } else {
                    city = null;
                    Log.v("--", "get address 33 " + location.getLatitude());
                    populateList(location);
                }
            }
        } else {
            Log.v("--", "get address 5");
            startGpsEnableDialog();
        }

    }

and my location listener:和我的位置监听器:

private final LocationListener mLocationListener = new LocationListener() {
        @Override
        public void onLocationChanged(final Location location) {
            // TODO
            Log.v("--", "get address 121");
            if (location != null) {
                Main.this.location = location;
                getAddress();
            }
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onProviderEnabled(String provider) {
            // TODO Auto-generated method stub
            Log.v("--", "provider enabled");
        }

        @Override
        public void onProviderDisabled(String provider) {
            // TODO Auto-generated method stub
            Log.v("--", "provider disabled");
        }
    };

When the phone is rebooted the cached last location is lost so if you didnt open up an app that uses GPS like google maps or something then there will be no last location.当手机重新启动时,缓存的最后一个位置会丢失,所以如果你没有打开一个使用 GPS 的应用程序,比如谷歌地图或其他东西,那么将没有最后一个位置。

There never has to be a location returned to you, you should always assume it could be null永远不必返回给您的位置,您应该始终假设它可能为空

in case that fusedLocationClient returned null location then you should get the location by yourself using requestLocationUpdates如果fusedLocationClient返回空位置,那么您应该使用requestLocationUpdates自己获取位置

    fusedLocationClient.lastLocation
        .addOnSuccessListener { location: Location? ->
            if (location == null) {
                checkLocationSettingsAndStartLocationUpdates(
                    resolutionForResult
                )
            } else {
                showUserCurrentLocation(location)
            }
        }

first let's define resolutionForResult首先让我们定义resolutionForResult

private val resolutionForResult =
    registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { activityResult ->
        if (activityResult.resultCode == RESULT_OK)
            locationManger.startLocationUpdates(requestPermissionLauncher)
        else {
            showMessage("we can't determine your location")
        }
    }

then this method那么这个方法

private fun checkLocationSettingsAndStartLocationUpdates(
    resolutionForResult: ActivityResultLauncher<IntentSenderRequest>
) {
    val builder = LocationSettingsRequest.Builder()
        .addLocationRequest(locationRequest)
    val client: SettingsClient = LocationServices.getSettingsClient(requireContext)
    val task: Task<LocationSettingsResponse> = client.checkLocationSettings(builder.build())

    task.addOnSuccessListener { _ ->
        startLocationUpdates()
    }

    task.addOnFailureListener { exception ->
        if (exception is ResolvableApiException) {
            // Location settings are not satisfied, but this can be fixed
            // by showing the user a dialog.
            try {
                val intentSenderRequest =
                    IntentSenderRequest.Builder(exception.resolution).build()
                resolutionForResult.launch(intentSenderRequest)
            } catch (sendEx: IntentSender.SendIntentException) {
            }
        }
    }
}

then startLocationUpdates where the actual location updates happens然后startLocationUpdates实际位置更新发生的地方

fun startLocationUpdates(
    ) {
        if (ActivityCompat.checkSelfPermission(
                requireContext,
                Manifest.permission.ACCESS_FINE_LOCATION
            ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
                requireContext,
                Manifest.permission.ACCESS_COARSE_LOCATION
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            requestPermissionLauncher.launch(
                Manifest.permission.ACCESS_FINE_LOCATION
            )
            return
        }
        fusedLocationClient.requestLocationUpdates(
            locationRequest,
            locationCallback,
            Looper.getMainLooper()
        )
    }

here is also the declaration of locationRequest and locationCallback这里也是locationRequestlocationCallback的声明

private val locationRequest: LocationRequest by lazy {
    LocationRequest.create().apply {
        interval = 10000
        fastestInterval = 5000
        priority = LocationRequest.PRIORITY_HIGH_ACCURACY
    }
}

and

private var locationCallback: LocationCallback = object : LocationCallback() {
    override fun onLocationResult(locationResult: LocationResult?) {
        locationResult ?: return
        for (location in locationResult.locations) {
            if (location != null) {
                //showUserCurrentLocation(location)
                stopLocationUpdates(this)//if you only need the location once then stop the updates
                break
            }
        }
    }
}

here is stopLocationUpdates method这是stopLocationUpdates方法

fun stopLocationUpdates(locationCallback: LocationCallback) {
    fusedLocationClient.removeLocationUpdates(locationCallback)
}

also the fusedLocationClient is defined once the user gives the permission or after the check for the permission,一旦用户授予权限或检查权限后, fusedLocationClient也被定义,

Here is how to check if permission guaranted这是检查权限是否得到保证的方法

fun locationPermissionGranted(): Boolean {
    return when (PackageManager.PERMISSION_GRANTED) {
        ContextCompat.checkSelfPermission(
            requireContext,
            Manifest.permission.ACCESS_FINE_LOCATION
        ) -> {
            fusedLocationClient =
                LocationServices.getFusedLocationProviderClient(requireContext)
            true
        }
        else -> {
            false
        }
    }
}

in case of false then you would need to ask for the permissionfun如果是假的,那么你需要请求permissionfun

 requestPermission(requestPermissionLauncher: ActivityResultLauncher<String>) {
        requestPermissionLauncher.launch(
            Manifest.permission.ACCESS_FINE_LOCATION
        )
    }

here is the definition for requestPermissionLauncher这是requestPermissionLauncher的定义

private val requestPermissionLauncher = registerForActivityResult(
    ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
    if (isGranted) {
        fusedLocationClient =
                LocationServices.getFusedLocationProviderClient(requireContext())
    } else {
        showMessage(
            "the application can't show your " +
                    "current location on the map, because you denied the location permission"
        )
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 手机重启后Android无法获取位置 - Android failing to get location after a phone reboot Android:如何单一更新位置并在重启后无法获取位置 - Android: how to singleUpdate location & can't get location after reboot Android 在手机启动后获取 GPS 位置,我正在尝试将其用于服务,但位置返回为 null - Android get GPS Location after phone boots, I am trying to get it in a service but location returned as null 手机重启(重启)后,哪个接收者首先在android中被调用 - After Reboot (Restart) of phone , Which receiver get called first in android Facebook-手机重启后,会话为空 - Facebook - Session is null after the phone reboot Android-重新启动电话后启动器应用程序中断 - Android - Launcher Application breaks after reboot phone Android:重启手机后恢复应用程序变量 - Android: Resume app variables after a phone reboot 手机重启后,Android AlarmManager被禁用 - Android AlarmManager disabled after phone reboot Android:手机重启后设置闹钟/提醒 - Android: set alarm/reminder after phone reboot Android使用共享的首选项和Dispatcher活动,以返回到上一个活动(重启手机后) - Android using shared preference and Dispatcher activity, to get back to the last activity (after reboot the phone)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM