1

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

所以,我只是用GoogleApiClient如下:

首先我实现如:片段的

private GoogleApiClient mGoogleApiClient; 

在侧的onCreate():

implements GoogleApiClient.ConnectionCallbacks, 
    GoogleApiClient.OnConnectionFailedListener 

宣言

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(); 
    } 
} 

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

可能是什么问题? 谢谢。

回答

0

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

而是在每个片段中使用GoogleApiClient的,它从你活动移动到一个类和连接和断开。

我为自己的目的实施了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(); 
} 
} 

在你活动

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() { 

      } 
     }); 

在你的活动onActivityResult()应该是这样的。

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

注意:您有使用此之前得到位置的权限