Сбой приложения в API 23 при использовании FusedLocationApi

На самом деле я создал приложение для отображения ближайшей заправочной станции, поэтому я использую для этого FusedLocationApi, и в коде сначала я проверяю, включено ли использование местоположения. Если нет, то я создаю GoogleClient и вызываю функцию setingsrequest(), и если местоположение включено. чем приложение работает отлично, но когда местоположение выключено, чем приложение, происходит сбой .. пожалуйста, проверьте журналы

журналы:

Обновленный код:

вы пытаетесь получить доступ к местоположению до того, как mGoogleApiClient будет подключен, вызовите метод settingsrequest() из метода onConnected, который выполняется на mGoogleApiClient.

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);



        Log.d(TAG, "onCreate ...............................");
        //show error dialog if GoolglePlayServices not available
        if (!isGooglePlayServicesAvailable()) {
            finish();
        }
        setContentView(R.layout.activity_fuel_stations);

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

        LocationManager mlocManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
        final boolean enabled = mlocManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        if(!enabled) {

            mGoogleApiClient.connect();
            setingsrequest();
        }
        else
        {

            init();


        }



    }


    private boolean isGooglePlayServicesAvailable() {
        int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (ConnectionResult.SUCCESS == status) {
            return true;
        } else {
            GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
            return false;
        }
    }

    public void setingsrequest()
    {

        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(30 * 1000);
        locationRequest.setFastestInterval(5 * 1000);
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest);
        builder.setAlwaysShow(true); //this is the key ingredient

        PendingResult<LocationSettingsResult> result =
                LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
        result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
            @Override
            public void onResult(LocationSettingsResult result) {
                final Status status = result.getStatus();
                final LocationSettingsStates state = result.getLocationSettingsStates();
                switch (status.getStatusCode()) {
                    case LocationSettingsStatusCodes.SUCCESS:
                        // All location settings are satisfied. The client can initialize location
                        // requests here.

                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        // Location settings are not satisfied. But could be fixed by showing the user
                        // a dialog.
                        try {
                            // Show the dialog by calling startResolutionForResult(),
                            // and check the result in onActivityResult().
                            status.startResolutionForResult(FuelStations.this, REQUEST_CHECK_SETTINGS);
                        } catch (IntentSender.SendIntentException e) {
                            // Ignore the error.
                        }
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        // Location settings are not satisfied. However, we have no way to fix the
                        // settings so we won't show the dialog.
                        break;
                }
            }
        });
    }

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

        switch (requestCode) {
// Check for the integer request code originally supplied to startResolutionForResult().
            case REQUEST_CHECK_SETTINGS:
                switch (resultCode) {
                    case Activity.RESULT_OK:


                        Toast.makeText(getApplicationContext(),"Location is on",Toast.LENGTH_SHORT).show();
                        init();
                        break;
                    case Activity.RESULT_CANCELED:
                       //keep asking if imp or do whatever
                        finish();
                        break;
                }
                break;
        }
    }

    private void init(){

        mapFrag = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mapFrag.getMapAsync(this);
    }


    @Override
    public void onMapReady(GoogleMap googleMap) {
        mGoogleMap = googleMap;
        tempGoogleMap = mGoogleMap;
        //MAP_FLAG=1;
        mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);

        //Initialize Google Play Services
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_FINE_LOCATION)
                    == PackageManager.PERMISSION_GRANTED) {
                buildGoogleApiClient();

            } else {
                checkLocationPermission();
            }
        } else {

            mGoogleApiClient.connect();
            mGoogleMap.setMyLocationEnabled(true);
            mGoogleMap.getUiSettings().setMapToolbarEnabled(true);
            //the below listener is depreceated so i have  to find a different way
            // mGoogleMap.setOnMyLocationButtonClickListener(myLocationChangeListener);
            mGoogleMap.setOnMyLocationButtonClickListener(new GoogleMap.OnMyLocationButtonClickListener() {
                @Override
                public boolean onMyLocationButtonClick() {

                    Location loc = mGoogleMap.getMyLocation();
                    LatLng currentLoc = new LatLng(loc.getLatitude(), loc.getLongitude());
                    mGoogleMap.clear();
                    markerOptions.position(currentLoc);
                    markerOptions.title("Current Position");
                    markerOptions.icon(BitmapDescriptorFactory
                            .defaultMarker(BitmapDescriptorFactory.HUE_RED));

                    mCurrLocationMarker = mGoogleMap.addMarker(markerOptions);
                    mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLoc,15.0f));
                    nearestFuelStation();
                    return true;
                }
            });

        }

    }

    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        mGoogleApiClient.connect();
    }

    private void checkLocationPermission() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {

            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_FINE_LOCATION)) {

                // Show an explanation to the user *asynchronously* -- don't block
                // this thread waiting for the user's response! After the user
                // sees the explanation, try again to request the permission.
                new AlertDialog.Builder(this)
                        .setTitle("Location Permission Needed")
                        .setMessage("This app needs the Location permission, please accept to use location functionality")
                        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                //Prompt the user once explanation has been shown
                                ActivityCompat.requestPermissions(FuelStations.this,
                                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                        MY_PERMISSIONS_REQUEST_LOCATION );
                            }
                        })
                        .create()
                        .show();


            } else {
                // No explanation needed, we can request the permission.
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        MY_PERMISSIONS_REQUEST_LOCATION );
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {


        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST_LOCATION: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    // permission was granted, yay! Do the
                    // location-related task you need to do.
                    if (ContextCompat.checkSelfPermission(this,
                            Manifest.permission.ACCESS_FINE_LOCATION)
                            == PackageManager.PERMISSION_GRANTED) {

                        if (mGoogleApiClient == null) {
                            buildGoogleApiClient();
                        }
                        mGoogleMap.setMyLocationEnabled(true);
                    }

                } else {

                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                    Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
                }
                return;
            }

            // other 'case' lines to check for other
            // permissions this app might request
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu, menu);
        return true;
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            Intent intent= new Intent(getApplicationContext(),MainMenu.class);
            startActivity(intent);
            finish();
            return true;
        }

        return super.onOptionsItemSelected(item);

    }


    @Override
    public void onConnected(Bundle bundle) {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        } startLocationUpdates();
        mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if(mLocation == null){
            startLocationUpdates();
        }
        if (mLocation != null) {
            double latitude = mLocation.getLatitude();
            double longitude = mLocation.getLongitude();
        } else {
            // Toast.makeText(this, "Location not Detected", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
        if (i == CAUSE_SERVICE_DISCONNECTED) {
            Toast.makeText(this, "Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
        } else if (i == CAUSE_NETWORK_LOST) {
            Toast.makeText(this, "Network lost. Please re-connect.", Toast.LENGTH_SHORT).show();
        }

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

        Toast.makeText(getApplicationContext(),"Connection Failed",Toast.LENGTH_SHORT).show();

    }

    @Override
    public void onLocationChanged(Location location) {
        mLastLocation = location;
        if (mCurrLocationMarker != null) {
            mCurrLocationMarker.remove();
        }
        if (mGoogleMap!=null)
        mGoogleMap.clear();
        //Place current location marker
        latitude = location.getLatitude();
        longitude = location.getLongitude();
        LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
        markerOptions.position(latLng);
        markerOptions.title("Current Position");
        markerOptions.icon(BitmapDescriptorFactory
                .defaultMarker(BitmapDescriptorFactory.HUE_RED));

        mCurrLocationMarker = mGoogleMap.addMarker(markerOptions);
        mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng,15.0f));

        if (mGoogleApiClient != null) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        }
        nearestFuelStation();

    }

    private void nearestFuelStation() {
        String FuelStation = "gas_station";

    }

    private String getUrl(double latitude, double longitude, String nearbyPlace) {

                }

    @Override
    protected void onStart() {

        if(mGoogleApiClient != null){
        mGoogleApiClient.connect();
     }
        super.onStart();
        Log.d("client value", String.valueOf(mGoogleApiClient.isConnected()));
    }

    @Override
    protected void onResume() {
        super.onResume();



    }


    @Override
    protected void onStop() {
        // Disconnecting the client invalidates it.
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);

        if(mGoogleApiClient!=null){

            {
                mGoogleApiClient.disconnect();}
            }

        super.onStop();
    }



    // Trigger new location updates at interval
    protected void startLocationUpdates() {
        // Create the location request
        mLocationRequest = LocationRequest.create()
                .setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY)
                .setInterval(UPDATE_INTERVAL)
                .setFastestInterval(FASTEST_INTERVAL);
        // Request location updates
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
                    mLocationRequest, this);
        }
    }


}

person techDigi    schedule 20.06.2017    source источник
comment
но я отключаюсь только в методе onPause()   -  person Rameshbabu    schedule 20.06.2017
comment
Вы должны создать экземпляр клиентского объекта в методе onCreate(Bundle) вашей Activity, а затем вызвать connect() в onStart() и отключить() в onStop(), независимо от состояния.   -  person techDigi    schedule 20.06.2017
comment
После отключения зачем запрашиватьLocationUpdates. Поэтому лучше проверьте подключение следующим образом: if(this.googleApiClient != null){ this.googleApiClient.connect(); }   -  person AskNilesh    schedule 20.06.2017
comment
поэтому вам нужно дождаться обратного вызова onConnected(), прежде чем mGoogleApiClient.isConnected() вернет true, и вы сможете использовать GoogleApiClient для запроса обновлений местоположения.   -  person Rameshbabu    schedule 20.06.2017
comment
хорошо, сэр, позвольте мне попробовать   -  person Rameshbabu    schedule 20.06.2017
comment
в onConnected, когда я проверяю статус клиента, он возвращает true, поэтому мне нужно запросить обновления местоположения (requestLocationUpdates)   -  person techDigi    schedule 20.06.2017
comment
проверьте обновленный код ... и теперь, когда местоположение находится в приложении, происходит сбой, но когда отображается диалоговое окно местоположения, приложение работает нормально ... и эта проблема возникает только в API 23   -  person techDigi    schedule 20.06.2017


Ответы (1)


заменять

с

 @Override
    protected void onResume() {
        super.onResume();

        mGoogleApiClient.connect();

    }

Лучше проверьте соединение, прежде чем идти на запрос. Это из-за того, что GoogleApiClient отключился. После запроса на отключение вызова выдается эта ошибка java.lang.IllegalStateException: GoogleApiClient еще не подключен.

 @Override
    public void onConnected(Bundle bundle) {
     LocationManager mlocManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
        final boolean enabled = mlocManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        if (!enabled) {
            setingsrequest();
        } else {
            init();

        }
    }
person Om Infowave Developers    schedule 20.06.2017
comment
E/UncaughtException: java.lang.IllegalStateException: GoogleApiClient еще не подключен. на com.google.android.gms.internal.zzbcc.zze (неизвестный источник) на com.google.android.gms.internal.zzbcw.zze (неизвестный источник) на com.google.android.gms.internal.zzbco.zze (Неизвестный источник) на com.google.android.gms.internal.zzcca.requestLocationUpdates(Неизвестный источник) на activity.FuelStations.onConnected(FuelStations.java:356) на com.google.android.gms.common.internal.zzac. zzn (неизвестный источник) на com.google.android.gms.internal.zzbco.zzm (неизвестный источник) на com.google.android.gms.internal.zzbcc.zzpY(неизвестный источник) на com.google.android.gms.internal.zzbcc.onConnected(неизвестный источник) на com.google.android.gms.internal.zzbcw.onConnected (Неизвестный источник) на com.google.android.gms.internal.zzbbh.onConnected(Неизвестный источник) на com.google.android.gms.common.internal.zzaa.onConnected(Неизвестный источник) на com.google.android.gms .common.internal.zzn.zzrj(неизвестный источник) на com.google.android.gms.common.internal.zze.zzs(неизвестный источник) на com.google.android.gms.common.internal.zzi.zzrk (неизвестный источник) на com.google.android.gms.common.internal.zzh.handleMessage (неизвестный источник) на android.os. Handler.dispatchMessage(Handler.java:102) в android.os.Looper.loop(Looper.java:148) в android.app.ActivityThread.main(ActivityThread.java:5417) в java.lang.reflect.Method.invoke (Собственный метод) на com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) на com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) - person techDigi; 20.06.2017