移动代码后,getLastLocation()返回null

时间:2018-08-08 09:07:04

标签: java android

问题

我不明白为什么现在getLastLocation()返回null。我刚刚移动了代码段以获取检查许可权代码段下的最后一个已知位置,现在每次我运行应用程序“位置”为空(在工作之前)。 您能帮我找到问题吗?谢谢

MapsActivity.java

    ...
 @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_maps);

            // Get fused location client
            mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
            // Create a Toolbar
            Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);


            // Set the toolbar
            myToolbar.setTitle("RSSI Map");
            myToolbar.setSubtitle("A Connectivity Map Builder");
            setSupportActionBar(myToolbar);

            // Obtain the SupportMapFragment and get notified when the map is ready to be used.
            SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.map);
            mapFragment.getMapAsync(this);


        }

        @Override
                public void onMapReady(GoogleMap googleMap) {

                    mMap = googleMap;


                    // Check if localization permission is granted
                    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                        mMap.setMyLocationEnabled(true);
                    } else {
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                            requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSION_FINE_LOCATION);
                        }
                    }

                    // Get last location
                    mFusedLocationClient.getLastLocation()
                            .addOnSuccessListener(this, new OnSuccessListener<Location>() {
                                @Override
                                public void onSuccess(Location location) {
                                    // Got last known location. In some rare situations this can be null.
                                    if (location != null) {
                                        longitude = location.getLongitude();
                                        latitude = location.getLatitude();

                                    }
                                }
                            });
    ...

解决方案

这有效,但实际上我不知道为什么。 我从OnMapReady回调中删除了通过保险丝提供程序客户端获取最后已知位置的代码,并将其移至checkLocationSettings方法内。 我还需要获取位置更新,因此我遵循了本教程https://developer.android.com/training/location/receive-location-updates。 我使用createLocationRequest方法创建请求,并使用checkLocationSettings来查看设置是否合适。如果合适,我在getLastKnownLocation内调用OnMapReady(我从checkLocationSettings删除的代码段)。

 @Override
        protected void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_maps);


            mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
            Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);

            // Create location request and location callback
            createLocationRequest();
            createLocationCallback();

            // Set the toolbar
            myToolbar.setTitle("RSSI Map");
            myToolbar.setSubtitle("A Connectivity Map Builder");
            setSupportActionBar(myToolbar);



            // If location permission is granted initialize Map and check location settings
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {

                mapSync();

                // Check if location settings are appropriate for location request and if is the case invoke getLastLocation()
                checkLocationSettings();

            } else {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSION_FINE_LOCATION);
                }
            }
        }

 @Override
        public void onMapReady(GoogleMap googleMap) {

            mMap = googleMap;

            // Check if localization permission is granted
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                mMap.setMyLocationEnabled(true);
            } else {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSION_FINE_LOCATION);
                }
            }




 public void checkLocationSettings() {
            // Get and check location services settings
            LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                    .addLocationRequest(mLocationRequest);

            SettingsClient client = LocationServices.getSettingsClient(MapsActivity.this);
            Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());

            task.addOnSuccessListener(MapsActivity.this, new OnSuccessListener<LocationSettingsResponse>() {
                @Override
                public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
                    // All location settings are satisfied. The client can initialize
                    // location requests here
                    getLastKnownLocation();

                }
            });
...
}

3 个答案:

答案 0 :(得分:1)

流应为:

  1. 在AndroidManifest.xml中添加位置权限
  2. 检查用户是否已授予该权限,如果是,请检查位置设置;然后不要先寻求许可
  3. 如果已授予许可并且位置设置为“开”,则您应该执行所需的操作。

在您的情况下,从显示的代码中,您没有检查位置设置,而是在请求权限后尝试在权限为getLastLocation()时应放在if语句中已授予以及何时在onRequestPermissionsResult()

中授予许可

编辑: 添加/更改以下代码:

1。

protected void createLocationRequest() {
        if (mLocationRequest == null) {
            mLocationRequest = new LocationRequest();
            mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            mLocationRequest.setInterval(10000);
            mLocationRequest.setFastestInterval(5000);
        }
    }

2。

private void checkLocationSettings() {

        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(mLocationRequest);

        final Task<LocationSettingsResponse> result =
                LocationServices.getSettingsClient(MapsActivity.this).checkLocationSettings(builder.build());

        result.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>() {
            @Override
            public void onComplete(@NonNull Task<LocationSettingsResponse> task) {

                Log.e(TAG, "onComplete() called with: task = [" + task.isComplete() + "]");
                // All location settings are satisfied. The client can initialize
                // location requests here.
                // ...
                getLastKnownLocation(mFusedLocationClient);
            }
        });


        result.addOnFailureListener(this, new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.e(TAG, "onFailure() called with: e = [" + e + "]");
                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(MapsActivity.this,
                                REQUEST_CHECK_SETTINGS);
                    } catch (IntentSender.SendIntentException sendEx) {
                        // Ignore the error.
                    }
                }
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.e("MapsActivity", "onActivityResult() called with: requestCode = [" + requestCode + "], resultCode = [" + resultCode + "], data = [" + data + "]");
        getLastKnownLocation(mFusedLocationClient);
    }


    public void getLastKnownLocation(FusedLocationProviderClient cl) {
        // Get last location
        mFusedLocationClient.getLastLocation()
                .addOnSuccessListener(this, new OnSuccessListener<Location>() {
                    @Override
                    public void onSuccess(Location location) {
                        Log.e(TAG, "onSuccess() called with: location = [" + location + "]");
                        // Got last known location. In some rare situations this can be null.
                        if (location != null) {
                            longitude = location.getLongitude();
                            latitude = location.getLatitude();
                            Log.e("MapsActivity", "onSuccess() called with: location = [" + location + "]");
                            LatLng mCurrentLocation = new LatLng(latitude, longitude);
                            mMap.addMarker(new MarkerOptions().position(mCurrentLocation).title("Current position"));
                            mMap.moveCamera(CameraUpdateFactory.newLatLng(mCurrentLocation));

                            // Set zoom level
                            mMap.animateCamera(CameraUpdateFactory.zoomTo(19.0f));
                            Toast.makeText(getApplicationContext(), "value is " + latitude + "poi" + longitude, Toast.LENGTH_LONG).show();
                        }
                    }
                });
    }



    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case MY_PERMISSION_FINE_LOCATION:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    mMap.setMyLocationEnabled(true);
                    createLocationRequest();
                    checkLocationSettings();
                } else {
                    Toast.makeText(getApplicationContext(), "This app requires location permission to be granted", Toast.LENGTH_LONG).show();
                    finish();
                }
                break;


        }
  1. 仅此代码与onMapReady()中的位置有关:

    // Check if localization permission is granted
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
            == PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED) {
        mMap.setMyLocationEnabled(true);
        createLocationRequest();
        checkLocationSettings();
    
    
    } else {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            ActivityCompat.requestPermissions(this
                    , new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}
                    , MY_PERMISSION_FINE_LOCATION);
        }
    }
    

确保清单中同时具有以下权限:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

答案 1 :(得分:0)

请尝试以下操作:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);

    // Get fused location client
    mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
    // Create a Toolbar
    Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);


    // Set the toolbar
    myToolbar.setTitle("RSSI Map");
    myToolbar.setSubtitle("A Connectivity Map Builder");
    setSupportActionBar(myToolbar);


    /**
    * Request permission here
    */
    reqPerms();
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == MY_PERMISSION_FINE_LOCATION) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            /**
            * Load the map after all perms are granted
            */
            loadMapAsync();
        } else {
            /**
            * Notify user that the app needs some permissions to do some tasks!
            */
        }
    }
}

@Override
public void onMapReady(GoogleMap googleMap) {

    mMap = googleMap;
    mMap.setMyLocationEnabled(true);

    // Get last location
    mFusedLocationClient.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<Location>() {
        @Override
        public void onSuccess(Location location) {
            // Got last known location. In some rare situations this can be null.
            if (location != null) {
                longitude = location.getLongitude();
                latitude = location.getLatitude();
            }
        }
    );
}

private void reqPerms() {
    // Check if localization permission is granted
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        /**
        * Load the map after all perms are granted
        */
        loadMapAsync();
    } else {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSION_FINE_LOCATION);
        }    
    }
}

private void loadMapAsync() {
    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
}

编辑: 请在清单中尝试也添加MY_PERMISSION_FINE_LOCATION,并在“活动”中请求对此权限。

答案 2 :(得分:0)

1)

requestPermissions()

此方法异步运行- docs 。您需要致电:

mFusedLocationClient.getLastLocation()
                            .addOnSuccessListener()

获得许可后。

2)检查locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)

3)添加到mFusedLocationClient.getLastLocation()

.addOnCompleteListener(new OnCompleteListener<Location>() {
                @Override
                public void onComplete(@NonNull Task<Location> task) {
                    if (task.getResult() == null) {
                        mFusedLocationClient.requestLocationUpdates(getLocationRequest(), mLocationCallback, null);
                    }
                }
            })

.addOnCanceledListener(new OnCanceledListener() {
                    @Override
                    public void onCanceled() {
                        Log.d(TAG, "onCanceled: mFusedLocationClient addOnCanceledListener");
                    }
                });

PS,如果您在Samsung s8或s9上检查它,那将是问题,我不知道为什么...