LocationServices.FusedLocationApi ... ERROR

0

AS shows me an error in the next line, the problem is that it causes my app to stop, and when I go to the activity in java it appears underlined in red, I do not know why because

LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);

activity2 java, this is the complete code of the activity

    package com.websmithing.gpstracker;

    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.content.SharedPreferences;
    import android.location.Location;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.util.Log;

    import com.google.android.gms.common.ConnectionResult;
    import com.google.android.gms.common.GooglePlayServicesUtil;
    import com.google.android.gms.common.api.GoogleApiClient;
    import com.google.android.gms.location.LocationListener;
    import com.google.android.gms.location.LocationRequest;
    import com.google.android.gms.location.LocationServices;
    import com.loopj.android.http.AsyncHttpResponseHandler;
    import com.loopj.android.http.RequestParams;

    import java.io.UnsupportedEncodingException;
    import java.net.URLEncoder;
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.TimeZone;

    //import com.google.android.gms.common.GooglePlayServicesUtil;

    public class LocationService extends Service implements
            GoogleApiClient.ConnectionCallbacks,
            GoogleApiClient.OnConnectionFailedListener,
            LocationListener {

        private static final String TAG = "LocationService";

        // use the websmithing defaultUploadWebsite for testing and then check your
        // location with your browser here: https://www.websmithing.com/gpstracker/displaymap.php
        private String defaultUploadWebsite;

        private boolean currentlyProcessingLocation = false;
        private LocationRequest locationRequest;
        private GoogleApiClient googleApiClient;

        @Override
        public void onCreate() {
            super.onCreate();

            defaultUploadWebsite = getString(R.string.default_upload_website);
        }

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            // if we are currently trying to get a location and the alarm manager has called this again,
            // no need to start processing a new location.
            if (!currentlyProcessingLocation) {
                currentlyProcessingLocation = true;
                startTracking();
            }

            return START_NOT_STICKY;
        }

        private void startTracking() {
            Log.d(TAG, "startTracking");

            if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {

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

                if (!googleApiClient.isConnected() || !googleApiClient.isConnecting()) {
                    googleApiClient.connect();
                }
            } else {
                Log.e(TAG, "unable to connect to google play services.");
            }
        }

        protected void sendLocationDataToWebsite(Location location) {
            // formatted for mysql datetime format
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            dateFormat.setTimeZone(TimeZone.getDefault());
            Date date = new Date(location.getTime());

            SharedPreferences sharedPreferences = this.getSharedPreferences("com.websmithing.gpstracker.prefs", Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = sharedPreferences.edit();

            float totalDistanceInMeters = sharedPreferences.getFloat("totalDistanceInMeters", 0f);

            boolean firstTimeGettingPosition = sharedPreferences.getBoolean("firstTimeGettingPosition", true);

            if (firstTimeGettingPosition) {
                editor.putBoolean("firstTimeGettingPosition", false);
            } else {
                Location previousLocation = new Location("");
                previousLocation.setLatitude(sharedPreferences.getFloat("previousLatitude", 0f));
                previousLocation.setLongitude(sharedPreferences.getFloat("previousLongitude", 0f));

                float distance = location.distanceTo(previousLocation);
                totalDistanceInMeters += distance;
                editor.putFloat("totalDistanceInMeters", totalDistanceInMeters);
            }

            editor.putFloat("previousLatitude", (float)location.getLatitude());
            editor.putFloat("previousLongitude", (float)location.getLongitude());
            editor.apply();

            final RequestParams requestParams = new RequestParams();
            requestParams.put("latitude", Double.toString(location.getLatitude()));
            requestParams.put("longitude", Double.toString(location.getLongitude()));

            Double speedInMilesPerHour = location.getSpeed()* 2.2369;
            requestParams.put("speed",  Integer.toString(speedInMilesPerHour.intValue()));

            try {
                requestParams.put("date", URLEncoder.encode(dateFormat.format(date), "UTF-8"));
            } catch (UnsupportedEncodingException e) {}

            requestParams.put("locationmethod", location.getProvider());

            if (totalDistanceInMeters > 0) {
                requestParams.put("distance", String.format("%.1f", totalDistanceInMeters / 1609)); // in miles,
            } else {
                requestParams.put("distance", "0.0"); // in miles
            }

            requestParams.put("username", sharedPreferences.getString("userName", ""));
            requestParams.put("phonenumber", sharedPreferences.getString("appID", "")); // uuid
            requestParams.put("sessionid", sharedPreferences.getString("sessionID", "")); // uuid

            Double accuracyInFeet = location.getAccuracy()* 3.28;
            requestParams.put("accuracy",  Integer.toString(accuracyInFeet.intValue()));

            Double altitudeInFeet = location.getAltitude() * 3.28;
            requestParams.put("extrainfo",  Integer.toString(altitudeInFeet.intValue()));

            requestParams.put("eventtype", "android");

            Float direction = location.getBearing();
            requestParams.put("direction",  Integer.toString(direction.intValue()));

            final String uploadWebsite = sharedPreferences.getString("defaultUploadWebsite", defaultUploadWebsite);

            LoopjHttpClient.get(uploadWebsite, requestParams, new AsyncHttpResponseHandler() {
                @Override
                public void onSuccess(int statusCode, cz.msebera.android.httpclient.Header[] headers, byte[] responseBody) {
                    LoopjHttpClient.debugLoopJ(TAG, "sendLocationDataToWebsite - success", uploadWebsite, requestParams, responseBody, headers, statusCode, null);
                    stopSelf();
                }
                @Override
                public void onFailure(int statusCode, cz.msebera.android.httpclient.Header[] headers, byte[] errorResponse, Throwable e) {
                    LoopjHttpClient.debugLoopJ(TAG, "sendLocationDataToWebsite - failure", uploadWebsite, requestParams, errorResponse, headers, statusCode, e);
                    stopSelf();
                }
            });
        }

        @Override
        public void onDestroy() {
            super.onDestroy();
        }

        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }

        @Override
        public void onLocationChanged(Location location) {
            if (location != null) {
                Log.e(TAG, "position: " + location.getLatitude() + ", " + location.getLongitude() + " accuracy: " + location.getAccuracy());

                // we have our desired accuracy of 500 meters so lets quit this service,
                // onDestroy will be called and stop our location uodates
                if (location.getAccuracy() < 500.0f) {
                    stopLocationUpdates();
                    sendLocationDataToWebsite(location);
                }
            }
        }

        private void stopLocationUpdates() {
            if (googleApiClient != null && googleApiClient.isConnected()) {
                googleApiClient.disconnect();
            }
        }

        /**
         * Called by Location Services when the request to connect the
         * client finishes successfully. At this point, you can
         * request the current location or start periodic updates
         */
        @Override
        public void onConnected(Bundle bundle) {
            Log.d(TAG, "onConnected");

            locationRequest = LocationRequest.create();
            locationRequest.setInterval(1000); // milliseconds
            locationRequest.setFastestInterval(1000); // the fastest rate in milliseconds at which your app can handle location updates
            locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

// this line of error            LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);

        }

        @Override
        public void onConnectionFailed(ConnectionResult connectionResult) {
            Log.e(TAG, "onConnectionFailed");

            stopLocationUpdates();
            stopSelf();
        }

        @Override
        public void onConnectionSuspended(int i) {
            Log.e(TAG, "GoogleApiClient connection has been suspend");
        }
    }

    
asked by Andres Arango 30.12.2017 в 14:46
source

1 answer

0

As of Android 6.0 (Marshmallow) Android changed the way you ask for permissions. It no longer asks for them when installing the app, but it asks for them at runtime (which it considers risky) or automatically grants them (to those that it does not consider risky, to see a list of the groups of permits and which it considers risky. enter here: List of normal permits- dangerous ).
The warning indicated by Android Studio is just that you need to request the permissions at run time, or that you handle a SecurityException (with try ... catch).

To request the permissions in execution time you can do the following:

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
  // Check Permissions Now
  ActivityCompat.requestPermissions(this,
        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
        REQUEST_LOCATION);
} else {
  // permission has been granted, continue as usual
  Location myLocation =
LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
}

You need to also check the permission ACCESS_COARSE_LOCATION ( INTERNET and ACCESS_NETWORK_STATE do not need to be checked because it is not considered "risky" and Android grants it automatically).
And in onRequestPermissionsResult you check if the user granted you the permission or not:

public void onRequestPermissionsResult(int requestCode,
                                       String[] permissions,
                                       int[] grantResults) {
    if (requestCode == REQUEST_LOCATION) {
        if(grantResults.length == 1
           && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // We can now safely use the API we requested access to
            Location myLocation =
                LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        } else {
            // Permission was denied or request was cancelled
        }
    }
}

Also remember to add the dependency on gradle:

dependencies {
    compile 'com.google.android.gms:play-services-location:11.8.0'
}
    
answered by 30.12.2017 / 16:06
source