java - 移动代码后 getLastLocation() 返回 null

标签 java android

问题

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

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 回调中删除了通过 fuse 提供程序客户端获取最后已知位置的代码,并将其移至 checkLocationSettings 方法中。 我还需要获取位置更新,因此我遵循了本教程 https://developer.android.com/training/location/receive-location-updates 。 我使用 createLocationRequest 方法创建请求,并使用 checkLocationSettings 来查看设置是否合适。如果它们被占用,我会在 checkLocationSettings 内调用 getLastKnownLocation(我从 OnMapReady 中删除的代码 fragment )。

 @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();

                }
            });
...
}

最佳答案

流程应该是:

  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;


        }
  • 只有这段代码与 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);
        }
    }
    
  • 确保您在 list 中拥有以下权限:

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

    关于java - 移动代码后 getLastLocation() 返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51742727/

    相关文章:

    java - 垃圾收集和线程

    java - 从输入流在 JavaFx 中播放 mp3 文件

    android - 在android中通过ant脚本更改应用程序名称

    android - 如何知道android手机是否在某个建筑物名称内?

    android - 媒体播放器 : prepareAsync called in state 8, mPlayer(0x9a318160)

    Android Studio 仅构建 1 个模块

    android - 与 webgl 相比,android 上的着色器精度不准确

    Java 8 : Class. getName() 减慢字符串连接链速度

    java - 我将如何使用系统剪贴板从 java 中粘贴?

    java - 如何在一个列表中包含基类和子类的实例?