GoogleApiClient挂app的使用

Use of GoogleApiClient hanging app

在我的应用程序中,我有 4 到 5 个片段,所有片段都需要 GoogleApiCLient 对象来获取当前位置并执行其他相关操作。

所以,我只是使用 GoogleApiClient,如下所示:

首先我实现为 :

implements GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener

声明

private GoogleApiClient mGoogleApiClient;

在 Fragment 的 onCreate() 端:

 if (!Constant.checkPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION)) {
                Constant.requestPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION, 101);
            } else {
                if (Constant.isOnline(mContext)) {
                    buildGoogleApiClient();
                    locationUpdate();
                } else {
                    Constant.displayToast(mContext, getResources().getString(R.string.msg_internet));
                }
            }

建筑如下 :

private synchronized void buildGoogleApiClient() {
    if (mGoogleApiClient == null || !mGoogleApiClient.isConnected()) {
        mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
                .addApi(LocationServices.API)
                .addApi(Places.GEO_DATA_API)
                .addApi(Places.PLACE_DETECTION_API)
                .enableAutoManage(getActivity(), MapFragment.this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
    }
}

onConnected 方法:

@Override
public void onConnected(@Nullable Bundle bundle) {
    try {
        if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

getLocation()方法:

  private void getLocation() {
    try {
        if (ActivityCompat.checkSelfPermission((Activity) mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission((Activity) mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        } else {
            mLocationManager = (LocationManager) mContext
                    .getSystemService(LOCATION_SERVICE);
            // getting GPS status
            boolean isGPSEnabled = mLocationManager
                    .isProviderEnabled(LocationManager.GPS_PROVIDER);
            // getting network status
            boolean isNetworkEnabled = mLocationManager
                    .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
            if (!isGPSEnabled && !isNetworkEnabled) {
                // no network provider is enabled
            } else {
                if (Prefrences.checkPref(mContext, ZIPCODE)) {
                    getLatLongFromZipCode();
                } else {
                    if (isNetworkEnabled) {
                        if (!Prefrences.checkPref(mContext, NEAR_ME_SEARCH)) {
                            mLocationManager.requestLocationUpdates(
                                    LocationManager.NETWORK_PROVIDER,
                                    0,
                                    0, this);
                            if (mLocationManager != null) {
                                mLocation = mLocationManager
                                        .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                                if (mLocation != null) {
                                    mCurrentLatitude = mLocation.getLatitude();
                                    mCurrentLongitude = mLocation.getLongitude();
                                } else if (mLastLocation != null) {
                                    mCurrentLatitude = mLastLocation.getLatitude();
                                    mCurrentLongitude = mLastLocation.getLongitude();
                                } else {
                                    Constant.displayToast(mContext, "Location not fetched. Try again.");
                                }
                            }
                        }
                    } else if (isGPSEnabled) {
                        if (!Prefrences.checkPref(mContext, NEAR_ME_SEARCH)) {
                            if (mLocation == null) {
                                mLocationManager.requestLocationUpdates(
                                        LocationManager.GPS_PROVIDER,
                                        0,
                                        0, this);
                                if (mLocationManager != null) {
                                    mLocation = mLocationManager
                                            .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                                    if (mLocation != null) {
                                        mCurrentLatitude = mLocation.getLatitude();
                                        mCurrentLongitude = mLocation.getLongitude();
                                    } else if (mLastLocation != null) {
                                        mCurrentLatitude = mLastLocation.getLatitude();
                                        mCurrentLongitude = mLastLocation.getLongitude();
                                    } else {
                                        Constant.displayToast(mContext, "Location not fetched. Try again.");
                                    }
                                }
                            }
                        }
                    }
                    loadServiceData();
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

}

locationUpdate()方法,其中调用了getLocation()方法:

private void locationUpdate() {
    try {
        mLocationRequest = LocationRequest.create();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setInterval(5 * 1000);
        mLocationRequest.setFastestInterval(1 * 1000);
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(mLocationRequest);
        // **************************
        builder.setAlwaysShow(true); // this is the key ingredient
        // **************************
        if (mGoogleApiClient != null) {
            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.
                            try {
                                if (Constant.isOnline(mContext)) {
                                    getLocation();
                                } else
                                    Constant.displayToast(mContext, mContext.getResources().getString(R.string.msg_internet));
                            } catch (Exception e) {
                                e.printStackTrace();
                            }

                            break;
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            // Location settings are not satisfied. But could be
                            // fixed by showing the user
                            // a dialog.
                            try {
                                status.startResolutionForResult((Activity) mContext, LOCATION_GET_CODE);
                            } catch (IntentSender.SendIntentException e) {
                                e.printStackTrace();
                            }

                            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.
                            Constant.displayToast(mContext, "Location change issue.");
                            break;
                    }
                }
            });
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

onActivityResult() 也如下:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == LOCATION_GET_CODE) {
        switch (resultCode) {
            case Activity.RESULT_OK:
                try {
                    getLocation();
                } catch (Exception e) {
                    e.printStackTrace();
                }

                break;

            case Activity.RESULT_CANCELED:
                // The user was asked to change settings, but chose not to
                Toast.makeText(mContext, "Please, turn on GPS and try again", Toast.LENGTH_LONG).show();
                break;

            default:
                break;

        }
    }
    Runtime.getRuntime().gc();
}

onStop() 方法:

@Override
public void onStop() {
    try {
        if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
            mGoogleApiClient.stopAutoManage(getActivity());
            mGoogleApiClient.disconnect();
        }
        super.onStop();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

onStart() 方法:

 @Override
public void onStart() {
    try {
        super.onStart();
        if (mGoogleApiClient != null) {
            mGoogleApiClient.connect();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

onDestroy() 方法:

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

        if (mGoogleApiClient != null) {
            mGoogleApiClient.stopAutoManage(getActivity());
            mGoogleApiClient.disconnect();
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

现在,问题是当我从一个片段导航到另一个片段时,我的应用程序卡住或挂起 2 到 3 秒。

可能是什么问题? 谢谢。

这种情况正在发生,因为在每个片段中,您都在一次又一次地做同样的事情。您在 onStart() 中连接并在 onStop() 中断开连接。第二个片段的 onStart() 在第一个片段的 onStop() 之前调用。

不要在每个片段中使用 GoogleApiClient,而是将其移动到单个 class 并连接并断开与您的 Activity.

我已经为自己的目的实现了 LocationUpdater。看代码,觉得不错可以用

LocationFinder.class

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResult;
import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.google.android.gms.maps.model.LatLng;

/**
 * Created by Bhuvanesh on 8/21/2017.
 */

@SuppressWarnings("MissingPermission")
public class LocationFinder implements LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
    public static final String TAG = "LocationFinder";
    private static final String BROADCAST_GPS_REQ = "LocationFinder.GPS_REQ";
    private static final String KEY_GPS_REQ = "key.gps.req";
    private static final int GPS_REQUEST = 2301;
    private FragmentActivity activity;
    private FinderType finderType;
    private GoogleApiClient googleApiClient;
    private LocationRequest locationRequest;
    private long updateInterval;
    private long fastestInterval;
    private GpsRequestListener gpsRequestListener;
    private LocationUpdateListener locationUpdateListener;

public LocationFinder(FragmentActivity activity, FinderType finderType) {
    this.activity = activity;
    this.finderType = finderType;
}

private void connectGoogleApiClient() {
    googleApiClient = new GoogleApiClient.Builder(activity)
            .addApi(LocationServices.API).addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this).build();
    googleApiClient.connect();
}

private void createLocationRequest() {
    locationRequest = LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(updateInterval);
    locationRequest.setFastestInterval(fastestInterval);
}

private BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        int intExtra = intent.getIntExtra(KEY_GPS_REQ, 0);
        switch (intExtra) {
            case Activity.RESULT_OK:
                LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, LocationFinder.this);
                gpsRequestListener.gpsTurnedOn();
                break;
            case Activity.RESULT_CANCELED:
                gpsRequestListener.gpsNotTurnedOn();
        }
    }
};

public void gpsRequestCallback(GpsRequestListener gpsRequestListener) {
    this.gpsRequestListener = gpsRequestListener;
    LocalBroadcastManager.getInstance(activity).registerReceiver(receiver, new IntentFilter(BROADCAST_GPS_REQ));
}

public void find(LocationUpdateListener listener) {
    this.locationUpdateListener = listener;
    createLocationRequest();
    connectGoogleApiClient();
}

private void find() {
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
            .addLocationRequest(locationRequest);
    builder.setAlwaysShow(true);

    PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
    result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
        @Override
        public void onResult(@NonNull LocationSettingsResult locationSettingsResult) {
            Status status = locationSettingsResult.getStatus();
            switch (status.getStatusCode()) {
                case LocationSettingsStatusCodes.SUCCESS:
                    LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, LocationFinder.this);
                    break;
                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                    try {
                        status.startResolutionForResult(activity, GPS_REQUEST);
                    } catch (IntentSender.SendIntentException e) {
                        e.printStackTrace();
                    }
                    break;
                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                    Log.d(TAG, "No GPS Hardware");
                    break;
            }
        }
    });
}

public void stopFinder() {
    LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
    activity.unregisterReceiver(receiver);
    googleApiClient.disconnect();
}

@Override
public void onConnected(@Nullable Bundle bundle) {
    Log.d(TAG, "GoogleApiClient: Connected");
    find();
}

@Override
public void onConnectionSuspended(int i) {
    Log.d(TAG, "GoogleApiClient: onConnectionSuspended")
}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    Log.d(TAG, "GoogleApiClient: onConnectionFailed")
}

@Override
public void onLocationChanged(Location location) {
    if (finderType != FinderType.TRACK)
        stopFinder();
    locationUpdateListener.onLocationUpdate(new LatLng(location.getLatitude(), location.getLongitude()));
}

public void setGpsRequestListener(GpsRequestListener gpsRequestListener) {
    this.gpsRequestListener = gpsRequestListener;
}

public static void onRequestResult(Activity activity, int requestCode, int resultCode) {
    if (requestCode == GPS_REQUEST) {
        Intent intent = new Intent(BROADCAST_GPS_REQ);
        intent.putExtra(KEY_GPS_REQ, resultCode);
        LocalBroadcastManager.getInstance(activity).sendBroadcast(intent);
    }
}

public enum FinderType {
    // It will update the current GPS location once.
    GPS,
    //It will update the user location continuously.
    TRACK
}

interface LocationUpdateListener {
    void onLocationUpdate(LatLng latLng);
}

interface GpsRequestListener {
    void gpsTurnedOn();

    void gpsNotTurnedOn();
}
}

在你的Activity中:

LocationFinder finder = new LocationFinder((FragmentActivity) getActivity(), LocationFinder.FinderType.TRACK);
finder.config(5000, 5000);
finder.find(this);

您应该在片段中实施 LocationFinder.LocationUpdateListener。您将在回调方法中获取位置更新。

void onLocationUpdate(LatLng latLng);

如果你想打开 Gps 并在你必须这样做之后得到回调。

finder.gpsRequestCallback(new GpsRequestListener() {
            @Override
            public void gpsTurnedOn() {

            }

            @Override
            public void gpsNotTurnedOn() {

            }
        });

在你的activityonActivityResult()中应该是这样的。

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        LocationFinder.onRequestResult(this, requestCode, resultCode);
    }

注意:您必须获得位置权限才能使用它。