尽管onconnect()被调用,GoogleApiClient仍未连接?

时间:2016-01-24 15:06:41

标签: android

当用户点击广告地理位置按钮时,我想在用户的当前位置添加地理围栏。但是,在使用融合的api客户端之后,它表明它还没有连接。我的代码就在这里 -

import android.Manifest;
import android.app.Service;
import android.content.Context;
import android.content.pm.PackageManager;
import android.database.sqlite.SQLiteDatabase;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

import java.util.ArrayList;

public class MapsActivity extends FragmentActivity implements com.google.android.gms.location.LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    private GoogleMap googleMap; // Might be null if Google Play services APK is not available.
    public SQLiteDatabase db;
    ArrayList<Geofence> mGeofences;
    public double latitude = 77.80;
    public double longitude = 55.76;
    Double valueindex = 0.0;
    private int request = 0;
    private LocationRequest mLocationRequest;
    private GoogleApiClient mGoogleApiClient;
    /**
     * Geofence Coordinates
     */
    ArrayList<LatLng> mGeofenceCoordinates;
    /**
     * Geofence Store
     */
    private GeofenceStore mGeofenceStore;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mGeofences = new ArrayList<Geofence>();
        mGeofenceCoordinates = new ArrayList<LatLng>();
        db = openOrCreateDatabase("CoordsDB", Context.MODE_PRIVATE, null);
//        db.execSQL("CREATE TABLE IF NOT EXISTS Coordinates(number DOUBLE,latitude DOUBLE,longitude DOUBLE);");
//        db.execSQL("INSERT INTO Coordinates VALUES('Fixed', 28.61,77.20)");
        setContentView(R.layout.activity_maps);
        SupportMapFragment supportMapFragment =
                (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.googleMap);
        /**
         * SupportMapFragment belongs to the v4 support library, contrary to the default MagFragment that is a native component in Android.
         SupportMapFragment will support more Android versions, but it is also an additional library you have to add in your project,
         so I think it really depends on the Android versions you are targeting:
         •  On recent versions, the default components should be enough
         •  On older versions you will need to install the v4 support library and maybe others
         *
         */
        googleMap = supportMapFragment.getMap();
        Log.i("My activity", "maps=" + googleMap);
        googleMap.setMyLocationEnabled(true);
        /**
         * setMyLocationEnabled(true/false) shows the true location when the GPS is switched on from the device. It is an inbuilt feature of the googlemaps .
         */

        LocationManager locationManager = (LocationManager) getSystemService(Service.LOCATION_SERVICE);
        // getting GPS status
        boolean isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        Log.i("My activity", "gps is" + isGPSEnabled);

        // getting network status
        boolean isNetworkEnabled = locationManager
                .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        Log.i("My activity", "network is" + isNetworkEnabled);

        Criteria crta = new Criteria();
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD) {
            crta.setAccuracy(Criteria.ACCURACY_FINE);
        } else {
            crta.setAccuracy(Criteria.ACCURACY_MEDIUM);
        }
        /**
         * we have used .setAccuracy as fine for higher SDks than gingerbread .Gingerbread is used as a reference because in apks lower
         * than gingerbread there is very poor geofencing, with gingerbread google made it a lot easier for locationservices to be used for devleopers.
         * it had improved set of tools for Location Services, which included geofencing and substantially improved location discovery.
         */
        crta.setPowerRequirement(Criteria.POWER_LOW);
        String provider = locationManager.getBestProvider(crta, true);

        /**
         * It request Location updates after every 5 sec or if the user traveled 10m
         */
        Log.i("My activity", "manager is " + locationManager);
        Log.i("My activity", "provider is " + provider);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

                MapsActivity.this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 100);
                // 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 Activity#requestPermissions for more details.
                return;
            }
        }
        if (mGoogleApiClient == null) {
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addConnectionCallbacks((GoogleApiClient.ConnectionCallbacks) this)
                    .addOnConnectionFailedListener((GoogleApiClient.OnConnectionFailedListener) this)
                    .addApi(LocationServices.API)
                    .build();
            mGoogleApiClient.connect();
            Log.i("Api is",""+mGoogleApiClient);
        }
        mLocationRequest = new LocationRequest();
        // We want a location update every 10 seconds.
        mLocationRequest.setInterval(10000);
        // We want the location to be as accurate as possible.
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

//        Location location = locationManager.getLastKnownLocation(provider);
        Location location = LocationServices.FusedLocationApi.getLastLocation(
                mGoogleApiClient);
        startLocationUpdates();
        Log.i("Location is", location + "");



        if (location != null) {

            onLocationChanged(location);
        }


        /**
         * the Permission is requested after every  sec or at a distance of 0 metres by the user.
         */


    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case 100: {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this, "Thanks for the permission", Toast.LENGTH_LONG).show();
                    // permission was granted, yay! do the
                    // calendar task you need to do.
                } else {
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                    Toast.makeText(this, "You did not allow to access your current location", Toast.LENGTH_LONG).show();
                }
            }
            // other 'switch' lines to check for other
            // permissions this app might request
        }
    }


    @Override
    public void onLocationChanged(Location location) {
        CameraPosition INIT =
                new CameraPosition.Builder()
                        .target(new LatLng(location.getLatitude(), location.getLongitude()))
                        .zoom(17.5F)
                        .bearing(300F) // orientation
                        .tilt(50F) // viewing angle
                        .build();
        // use GooggleMap mMap to move camera into position
        googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(INIT));
    }

    @Override
    protected void onStart() {

        super.onStart();
        mGoogleApiClient.connect();
    }

    @Override
    protected void onStop() {

        super.onStop();
        mGoogleApiClient.disconnect();

    }


    public void Add(View view) {
        if (request <= 3) {
            mGeofenceCoordinates.add(new LatLng(latitude, longitude));
            Log.i("The id is", "" + valueindex);
            mGeofences.add(new Geofence.Builder()
                    // The coordinates of the center of the geofence and the radius in meters.
                    .setRequestId("" + valueindex)
                    .setCircularRegion(latitude, longitude, 30)
                    .setExpirationDuration(Geofence.NEVER_EXPIRE)
                            // Required when we use the transition type of GEOFENCE_TRANSITION_DWELL
                    .setLoiteringDelay(50000)
                    .setTransitionTypes(
                            Geofence.GEOFENCE_TRANSITION_ENTER
                                    | Geofence.GEOFENCE_TRANSITION_DWELL
                                    | Geofence.GEOFENCE_TRANSITION_EXIT).build());
            mGeofenceStore = new GeofenceStore(this, mGeofences);
            valueindex++;
            request++;

//            Cursor c = db.rawQuery("SELECT * FROM Coordinates WHERE Id='"+valueindex+"'", null);


            googleMap.addMarker(new MarkerOptions().snippet("Radius:30m").draggable(false).title(valueindex + "").position(new LatLng(latitude, longitude)));
        } else {
            Toast.makeText(this, "Maximum limit exceeded", Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void onConnected(Bundle bundle) {
        Location mlastlocation;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

                MapsActivity.this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 100);
                //    public void requestPermissions(@NonNull String[] permissions, int requestCode)
                // 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 Activity#requestPermissions for more details.
                return;
            }
        }
            mlastlocation = LocationServices.FusedLocationApi.getLastLocation(
                    mGoogleApiClient);
           startLocationUpdates();
            if (mlastlocation != null) {
                Log.i("the last location:", "" + mlastlocation);
                Toast.makeText(this, "Get last location first asshole!", Toast.LENGTH_LONG).show();
            }


        }


    protected void startLocationUpdates() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                MapsActivity.this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 100);
                //    public void requestPermissions(@NonNull String[] permissions, int requestCode)
                // 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 Activity#requestPermissions for more details.
                return;
            }
            LocationRequest mLocationRequest = new LocationRequest();

            LocationServices.FusedLocationApi.requestLocationUpdates(
                    mGoogleApiClient, mLocationRequest, this);
        }
    }

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

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
    Log.i("Connection","Failed");
    }
}

这是我的错误 -

java.lang.RuntimeException: Unable to start activity ComponentInfo{saksham.geofencing/saksham.geofencing.MapsActivity}: java.lang.IllegalStateException: GoogleApiClient is not connected yet.
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2426)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)
            at android.app.ActivityThread.-wrap11(ActivityThread.java)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5443)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
     Caused by: java.lang.IllegalStateException: GoogleApiClient is not connected yet.
            at com.google.android.gms.common.api.internal.zzh.zzb(Unknown Source)
            at com.google.android.gms.common.api.internal.zzl.zzb(Unknown Source)
            at com.google.android.gms.common.api.internal.zzj.zzb(Unknown Source)
            at com.google.android.gms.location.internal.zzd.requestLocationUpdates(Unknown Source)
            at saksham.geofencing.MapsActivity.startLocationUpdates(MapsActivity.java:276)
            at saksham.geofencing.MapsActivity.onCreate(MapsActivity.java:139)
            at android.app.Activity.performCreate(Activity.java:6245)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1130)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)
            at android.app.ActivityThread.-wrap11(ActivityThread.java)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5443)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)

和我的清单文件 -

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="saksham.geofencing" >

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
    <!--
 The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
         Google Maps Android API v2, but are recommended.
    -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="@string/google_maps_key" />

        <activity
            android:name=".MapsActivity"
            android:label="@string/title_activity_maps" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
    <receiver android:name="com.aol.android.geofence.GeofenceReceiver"
        android:exported="false">
        <intent-filter >
            <action android:name="com.aol.android.geofence.ACTION_RECEIVE_GEOFENCE"/>
        </intent-filter>
    </receiver>

</manifest>

请帮助,我是android的新手,即使在搜索了无数的博客之后,我已经被困住了很多天

1 个答案:

答案 0 :(得分:1)

在您的onCreate方法中,您正确配置了Google API客户端并致电onConnect

if (mGoogleApiClient == null) {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks((GoogleApiClient.ConnectionCallbacks) this)
            .addOnConnectionFailedListener((GoogleApiClient.OnConnectionFailedListener) this)
            .addApi(LocationServices.API)
            .build();
    mGoogleApiClient.connect();
    Log.i("Api is",""+mGoogleApiClient);
}

但是,在此之下的几行(仍然在onCreate生命周期方法中),您有以下代码:

Location location = LocationServices.FusedLocationApi.getLastLocation(
            mGoogleApiClient);
startLocationUpdates();
Log.i("Location is", location + "");

if (location != null) {
    onLocationChanged(location);
}

我的猜测是,此部分的第一行导致了错误 - 您正在尝试检索某个位置,但此时Google API客户端仍未连接。由于您的onConnected回调中已有类似的代码,因此您应该可以从onCreate方法中删除我在上面引用的第二个代码块来解决问题。