Kim Gysen Kim Gysen -4 years ago 82
Java Question

Hidden fragment to isolate code

My question is how custom it is to isolate certain functionality required by an activity into a hidden fragment, in this case Location Services.

My initial thought was to pass the boilerplate callbacks that are related to Location Services into a separate plain Java utility class, and only keep the listener for

onLocationChanged
in the Activity. This would be much cleaner.

The problem is that this results in circular dependencies, because the pojo would require a reference to the activity context for certain calls, and the Activity would have a reference to the utility class resulting in a circular dependency, which results in tight coupling.

Therefore my thought was to make a hidden fragment and store the code there; this would keep the code in the main activity clean.

What is the usual way to do this?

The current code that I use:

public class HomeActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener{
private static final String TAG = "HOME_ACTIVITY"; // Logging

private GoogleApiClient mGoogleApiClient;
private Location mLocation;
private LocationManager mLocationManager;
private LocationRequest mLocationRequest;
private com.google.android.gms.location.LocationListener listener;

private double mLatCurLoc;
private double mLngCurLoc;

private float MIN_DISTANCE = 200.0f;
private long UPDATE_INTERVAL = 2 * 1000; /* 10 secs */
private long FASTEST_INTERVAL = 2000; /* 2 sec */

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);

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

mLocationManager = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);

}

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

@Override
public void onBackPressed() {
moveTaskToBack(true);
}

@Override
public void onConnected(Bundle bundle) {
// Android Studio complains that we should check the permissions before getting last location
// However, we have already checked permissions in the previous activity
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}

startLocationUpdates();
mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);

if(mLocation == null){
startLocationUpdates();
}
if (mLocation != null) {

} else {
Toast.makeText(this, "Location not Detected", Toast.LENGTH_SHORT).show();
}
}

@Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Connection Suspended");
mGoogleApiClient.connect();
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i(TAG, "Connection failed. Error: " + connectionResult.getErrorCode());
}

@Override
protected void onStart() {
super.onStart();
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
}

@Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}

protected void startLocationUpdates() {
// Create the location request
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(UPDATE_INTERVAL)
.setSmallestDisplacement(MIN_DISTANCE)
.setFastestInterval(FASTEST_INTERVAL);
// Request location updates
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
mLocationRequest, this);
}

@Override
public void onLocationChanged(Location location) {
mLatCurLoc = location.getLatitude();
mLngCurLoc = location.getLongitude();
String msg = "Updated Location: " +
Double.toString(location.getLatitude()) + "," +
Double.toString(location.getLongitude());
Log.i("LOCATION_CHANGED", msg);
}


}

Answer Source

I think that's the beauty of inheritance in OOP. You'd just have an activity which will deal with location services, and make your other activities who want to deal with locations extend e.g. LocationAwareActivity. The moment one of those activities is not interested in locations you'd just change the parent class, and vice versa, the moment one of your activities would like to be aware of locations - it will extend LocationAwareActivity.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download