融合位置提供者:getLastKnowLocation 返回 null 并且 onLocationChange 没有被调用?

Posted

技术标签:

【中文标题】融合位置提供者:getLastKnowLocation 返回 null 并且 onLocationChange 没有被调用?【英文标题】:Fused Location Provider : getLastKnowLocation is returning null and onLocationChange is not getting called? 【发布时间】:2018-04-24 18:35:21 【问题描述】:

有很多类似的问题和博客,但没有一个可以帮助我解决我的问题。我已经编写了下面的代码,但是getLastKnowLocation 返回的位置为空,有时getLastKnowLocation 可以在某些条件下返回空。在我的代码中,如果 getLastKnowLocation 方法返回 null 但未调用 onLocationChanged 方法,我请求新的更新位置。 这是代码。

@Override
    protected void onCreate(Bundle savedInstanceState) 

        super.onCreate(savedInstanceState);
        setContentView(R.layout.location_provider_layout);
        Intent intent = getIntent();              
        checkPlayServices();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
        mGoogleApiClient.connect();

        mLocationRequest= LocationRequest.create()
                                         .setInterval(10000)
                                         .setFastestInterval(5000)
                                         .setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);


    



    private boolean checkPlayServices() 
        GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
        int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.SUCCESS) 
            if (apiAvailability.isUserResolvableError(resultCode)) 
                apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST)
                        .show();
             else
                finish();

            return false;
        
        return true;
    


    @Override
    public void onConnected(@Nullable Bundle bundle) 
        if (mGoogleApiClient.isConnected())
            Log.d(LOCATION_TAG, "Google api is connected");


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

        PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
        result.setResultCallback(new ResultCallback<LocationSettingsResult>() 
            @Override
            public void onResult(@NonNull LocationSettingsResult locationSettingsResult) 
                final Status status = locationSettingsResult.getStatus();
                switch (status.getStatusCode()) 

                    case LocationSettingsStatusCodes.SUCCESS:;
                        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) 
                            boolean isLocationOn = ActivityCompat.checkSelfPermission(LocationProviderClass.this, Manifest.permission_group.LOCATION) != PackageManager.PERMISSION_GRANTED;

                            if (!(isLocationOn)) 
                                String [] runTimePermission=new String[]Manifest.permission_group.SMS;
                                requestPermissions(runTimePermission, LOCATION_REQUESTCODE);
                            
                            else
                                computeLocation();
                         else
                            computeLocation();
                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        try 
                            status.startResolutionForResult(LocationProviderClass.this, STATUS_INT);
                         catch (IntentSender.SendIntentException e) 
                            Log.d(LOCATION_TAG, "error in startResolutionForResult");
                        
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        Log.d(LOCATION_TAG, "Location setting is canceled");
                        break;
                    default:
                        Log.d(LOCATION_TAG,"Location setting enters into default");

                
            
        );


        computeLocation();
    

    @Override
    public void onConnectionSuspended(int i) 
        Log.d("PERMISSION_TAG","connection suspended");

    

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) 

        if (!mGoogleApiClient.isConnected())
            Log.d(PERMISSION_TAG, "ON connection failed error");
        if (connectionResult.hasResolution()) 
            try 
                // Start an Activity that tries to resolve the error
                connectionResult.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST);
             catch (IntentSender.SendIntentException e) 
                e.printStackTrace();
            
         else 
            Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
        

    


    private void computeLocation() 

        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M) 
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) 
                Toast.makeText(getApplicationContext(), "Fine access location is not granted", Toast.LENGTH_LONG).show();
            
        

        location=LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if(location==null) 
            Toast.makeText(getApplicationContext(), "getLastLocation return null", Toast.LENGTH_LONG).show();
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        
        else 
            Toast.makeText(getApplicationContext(), "getLastLocation return"+location.getLatitude()+" "+location.getLongitude(), Toast.LENGTH_LONG).show();
           //do what ever you want here
        


    


    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) 
        switch (requestCode) 
            case  LOCATION_REQUESTCODE: 

                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) 

                    computeLocation();

                
                else 

                    Log.d(RUNTIME_PERMISSION_ERROR,"Error in runtime error");
                    Toast.makeText(getApplication(),"The app need location permission", Toast.LENGTH_LONG).show();

                
                break;
            



        
    



    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 

        if (requestCode == STATUS_INT) 
            switch (resultCode) 
                case Activity.RESULT_OK: 
                    Toast.makeText(getApplicationContext(), "User enabled location permission", Toast.LENGTH_LONG).show();
                    computeLocation();
                    break;
                
                case Activity.RESULT_CANCELED: 
                    Toast.makeText(getApplication(), "You canceled the permission the app is not going to work", Toast.LENGTH_LONG).show();
                    break;
                
                default:
                    Toast.makeText(getApplication(), "Permission error", Toast.LENGTH_LONG).show();
            

        
    


    @Override
    public void onLocationChanged(Location location) 
        Log.d(LOCATION_TAG, "onLocationChanged method called");
        Toast.makeText(getApplicationContext(), "onLocationChanged method called"+location.getLongitude()+" "+location.getLatitude(), Toast.LENGTH_LONG).show();

    


    @Override
    public void onStart() 
        super.onStart();

    
    @Override
     protected void onResume()
    
       super.onResume();
        this.mGoogleApiClient.connect();
    
    @Override
    public void onPause() 
        super.onPause();
        if (this.mGoogleApiClient.isConnected())
         LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,this);
            this.mGoogleApiClient.disconnect();

    


【问题讨论】:

【参考方案1】:

您必须添加侦听器,以便在您获得更改位置时告诉设备您有一个动作。 做这样的事

LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
LocationListener listener = new LocationListener() 
   ...

locationManager.requestLocationUpdates(GPS_PROVIDER, intervall, distance, listener);

【讨论】:

我要的是 Google Play 服务(融合位置提供商)而不是 LocationManager。

以上是关于融合位置提供者:getLastKnowLocation 返回 null 并且 onLocationChange 没有被调用?的主要内容,如果未能解决你的问题,请参考以下文章

重新启动活动时,Android Wear 上的融合位置提供程序会导致崩溃

Android 融合位置提供程序设置

融合位置提供程序 - 通过位移更新位置不起作用

是否可以使用 Google 的新融合位置提供程序模拟位置?

Android 中的融合位置提供程序

融合位置提供程序和“Wi-Fi 和移动网络位置”设置