Android 位置权限错误与 null

Posted

技术标签:

【中文标题】Android 位置权限错误与 null【英文标题】:Android location permission error with null 【发布时间】:2019-08-10 23:45:59 【问题描述】:

我是一名学生,目前正在学习并尝试使用 google map api。现在,我面临着获取位置的问题。昨天还能用,今天突然不能用了。代码有点长,因为我想表明该应用程序在使用应用程序之前要求允许打开该位置,但我认为我没有正确理解它。我认为应用程序的启动方式与我希望的方式不同。

这个过程应该是,从之前的activity intent到这个MapsActivity会提示请求打开位置的权限,一旦位置开启,google map marker会更新到当前位置。

现在,应用不断崩溃。

public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback 

    private GoogleMap mMap;
    FusedLocationProviderClient mFusedLocationClient;
    LocationRequest mLocationRequest;
    LocationCallback mLocationCallback;
    double mLocationLat, mLocationLong;

    LocationSettingsRequest.Builder mLocationSettingsBuilder;
    SettingsClient client;
    Task<LocationSettingsResponse> task;
    private static final int REQUEST_CHECK_SETTINGS = 0x1;


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

        // 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);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);

        setSupportActionBar(toolbar);
        //toolbar.setTitle("AskForMech : Maps");
        //toolbar.setLogo(R.drawable.ic_launcher);

        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(MapsActivity.this);

        mLocationCallback = new LocationCallback()
            @Override
            public void onLocationResult(LocationResult locationResult) 
                if(locationResult==null)
                    return;
                 else 
                    mLocationLat = locationResult.getLastLocation().getLatitude();
                    mLocationLong = locationResult.getLastLocation().getLongitude();
                
            
        ;

        setLocationRequestSettings();

    

    public void getLocation() //error is here
        LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
        Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        mLocationLat = location.getLatitude();
        mLocationLong = location.getLongitude();
    

    @Override
    public void onMapReady(GoogleMap googleMap) 
        mMap = googleMap;
        mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);

        getLocation(); //error is here
        LatLng pos = new LatLng(mLocationLat, mLocationLong);
        mMap.addMarker(new MarkerOptions().position(pos).title("You!"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(pos));
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(pos, 18.00f));
    

    @Override
    protected void onResume() 
        super.onResume();
        //startLocationUpdate();
         requestLocationUpdate();
    

    @Override
    protected void onPause() 
        super.onPause();

        if(mFusedLocationClient != null)

            mFusedLocationClient.removeLocationUpdates(mLocationCallback);
            Toast.makeText(MapsActivity.this, "Listener is removed.", Toast.LENGTH_SHORT).show();
        
    

    private void requestLocationUpdate()
        mLocationSettingsBuilder = new LocationSettingsRequest.Builder().addLocationRequest(mLocationRequest);
        client = LocationServices.getSettingsClient(MapsActivity.this);

        task = client.checkLocationSettings(mLocationSettingsBuilder.build());

        task.addOnSuccessListener(MapsActivity.this, new OnSuccessListener<LocationSettingsResponse>() 
            @Override
            public void onSuccess(LocationSettingsResponse locationSettingsResponse) 

                startLocationUpdate();
            
        );

        task.addOnFailureListener(MapsActivity.this, new OnFailureListener() 
            @Override
            public void onFailure(@NonNull Exception e) 

                if(e instanceof ResolvableApiException)
                    try

                        ResolvableApiException resolvable = (ResolvableApiException) e;
                        resolvable.startResolutionForResult(MapsActivity.this, REQUEST_CHECK_SETTINGS);

                    catch(IntentSender.SendIntentException sendEx) 

                    
                
            
        );
    

    private void setLocationRequestSettings()

        mLocationRequest = LocationRequest.create();
        mLocationRequest.setInterval(3000);
        mLocationRequest.setFastestInterval(1000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    

    private void startLocationUpdate()
            // Here, thisActivity is the current activity
            if (ContextCompat.checkSelfPermission(MapsActivity.this,
                    Manifest.permission.ACCESS_FINE_LOCATION)
                    != PackageManager.PERMISSION_GRANTED) 

                if (ActivityCompat.shouldShowRequestPermissionRationale(MapsActivity.this,
                        Manifest.permission.ACCESS_FINE_LOCATION)) 

                    showExplanation();

                 else 
                    ActivityCompat.requestPermissions(MapsActivity.this,
                            new String[]Manifest.permission.ACCESS_FINE_LOCATION,
                            0);

                
             else 

                mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, null);
                Toast.makeText(MapsActivity.this, "Location permission was granted!", Toast.LENGTH_SHORT).show();
            
        

    private void showExplanation()
        AlertDialog.Builder builder = new AlertDialog.Builder(MapsActivity.this);

        builder.setTitle("Requires Location Permission.");
        builder.setMessage("This app needs location permission to get the location information.");
        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() 
            @Override
            public void onClick(DialogInterface dialogInterface, int i) 
                ActivityCompat.requestPermissions(MapsActivity.this,
                        new String[]Manifest.permission.ACCESS_FINE_LOCATION,
                        0);
            
        );

        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() 
            @Override
            public void onClick(DialogInterface dialogInterface, int i) 
                Toast.makeText(MapsActivity.this, "Sorry, this function cannot be used until permission is granted.",Toast.LENGTH_SHORT).show();
            
        );
        builder.show();
    

【问题讨论】:

日志上的错误是什么? What is a NullPointerException, and how do I fix it?的可能重复 这个问题被反复询问getLastKnownLocation 可能返回null!你必须忍受它!(通过做一些空检查) @Maxouille 非常感谢您的回复,我认为您的回答让我对正在发生的事情有所了解。 @Selvin 谢谢你,Selvin 先生。 【参考方案1】:

您应该使用回调方法onLocationChanged() 而不是getLastKnownLocation ()。确实,getLastKnownLocation() 可以返回null(见here)

我更喜欢使用onLocationChanged(),一旦检测到位置更改就会调用它。事实证明它对我很有用。

如果您在实现 LocationListener 时遇到任何问题,请查看此帖子:https://***.com/a/42218626/3780625

最好的

【讨论】:

以上是关于Android 位置权限错误与 null的主要内容,如果未能解决你的问题,请参考以下文章

Android检查位置权限错误

Android:位置服务权限

权限被拒绝无法获取位置 Android

融合位置 API 运行时权限错误

检查用户位置的权限

询问位置权限时,React Native Expo 应用程序在 android apk 文件上崩溃