package com.ese2013.mensaunibe.map;
import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.content.IntentSender;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import com.ese2013.mensaunibe.App;
import com.ese2013.mensaunibe.R;
import com.ese2013.mensaunibe.mensa.MensaActivity;
import com.ese2013.mensaunibe.mensa.MensaListAdapter;
import com.ese2013.mensaunibe.model.utils.AppUtils;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
/**
* @author group7
* @author Sandor Torok
*/
public class MyLocation implements
LocationListener,
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener {
private static final String TAG = "MyLocation";
// A request to connect to Location Services
private static LocationRequest mLocationRequest;
// Stores the current instantiation of the location client in this object
private static LocationClient mLocationClient;
private static ActionBarActivity mFragActivity;
boolean mUpdatesRequested = false;
private MensaListAdapter mMensaListAdapter;
private static MyLocation mySingelton = null;
private MyLocation(){
// Create a new global location parameters object
mLocationRequest = LocationRequest.create();
/*
* Set the update interval
*/
mLocationRequest.setInterval(AppUtils.UPDATE_INTERVAL_IN_MILLISECONDS);
// Use high accuracy
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// Set the interval ceiling to one minute
mLocationRequest.setFastestInterval(AppUtils.FAST_INTERVAL_CEILING_IN_MILLISECONDS);
// Turn on location updates
mUpdatesRequested = true;
/*
* Create a new location client, using the enclosing class to
* handle callbacks.
*/
mLocationClient = new LocationClient(App.getAppContext(), this, this);
}
public static MyLocation getInstance(){
if (mySingelton == null)
mySingelton = new MyLocation();
return mySingelton;
}
/*
* Called when the Activity is no longer visible at all.
* Stop updates and disconnect.
*/
public void callOnStop() {
// If the client is connected
if (mLocationClient.isConnected()) {
stopPeriodicUpdates();
}
// After disconnect() is called, the client is considered "dead".
mLocationClient.disconnect();
}
/*
* Called when the Activity is going into the background.
* Parts of the UI may be visible, but the Activity is inactive.
*/
public void callOnPause() {
if (mMensaListAdapter != null) mMensaListAdapter.locationReady(false);
if(mFragActivity instanceof BaseMapActivity)((BaseMapActivity) mFragActivity).locationReady(false);
}
/*
* Called when the Activity is restarted, even before it becomes visible.
*/
public void callOnStart() {
/*
* Connect the client. Don't re-start any requests here;
* instead, wait for onResume()
*/
mLocationClient.connect();
}
/*
* Called when the system detects that this Activity is now visible.
*/
public void callOnResume() {
mUpdatesRequested = true;
}
/*
* Handle results returned to this Activity by other Activities started with
* startActivityForResult(). In particular, the method onConnectionFailed() in
* LocationUpdateRemover and LocationUpdateRequester may call startResolutionForResult() to
* start an Activity that handles Google Play services problems. The result of this
* call returns here, to onActivityResult.
*/
public void callOnActivityResult(int requestCode, int resultCode, Intent intent) {
// Choose what to do based on the request code
switch (requestCode) {
// If the request code matches the code sent in onConnectionFailed
case AppUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST :
switch (resultCode) {
// If Google Play services resolved the problem
case Activity.RESULT_OK:
// Log the result
Log.d(TAG, App.getAppContext().getString(R.string.resolved));
break;
// If any other result was returned by Google Play services
default:
// Log the result
Log.d(TAG, App.getAppContext().getString(R.string.no_resolution));
break;
}
// If any other request code was received
default:
// Report that this Activity received an unknown requestCode
Log.d(TAG,
App.getAppContext().getString(R.string.unknown_activity_request_code, requestCode));
break;
}
}
/**
* Verify that Google Play services is available before making a request.
*
* @return true if Google Play services is available, otherwise false
*/
private boolean servicesConnected() {
// Check that Google Play services is available
int resultCode =
GooglePlayServicesUtil.isGooglePlayServicesAvailable(App.getAppContext());
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
// In debug mode, log the status
Log.d(TAG, App.getAppContext().getString(R.string.play_services_available));
// Continue
return true;
// Google Play services was not available for some reason
} else {
// Display an error dialog
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(resultCode, mFragActivity, 0);
if (dialog != null) {
ErrorDialogFragment errorFragment = new ErrorDialogFragment();
errorFragment.setDialog(dialog);
errorFragment.show(mFragActivity.getSupportFragmentManager(), AppUtils.APPTAG);
}
return false;
}
}
public Location getLocation() {
// If Google Play Services is available
if (servicesConnected()) {
// Get the current location
Location currentLocation = mLocationClient.getLastLocation();
return currentLocation;
}
return null;
}
/*
* 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, App.getAppContext().getString(R.string.connected));
if (mUpdatesRequested) {
startPeriodicUpdates();
}
if (mMensaListAdapter != null){
mMensaListAdapter.locationReady(true);
mMensaListAdapter.notifyDataSetChanged();
mMensaListAdapter.locationReady(false);
}
/*if(mFragActivity instanceof MapActivity){
((MapActivity) mFragActivity).locationReady(true);
((MapActivity) mFragActivity).notifyDataSetChanged();
((MapActivity) mFragActivity).locationReady(false);
}*/
}
/*
* Called by Location Services if the connection to the
* location client drops because of an error.
*/
@Override
public void onDisconnected() {
Log.d(TAG, App.getAppContext().getString(R.string.disconnected));
if (mMensaListAdapter != null) {mMensaListAdapter.locationReady(false);}
if(mFragActivity instanceof BaseMapActivity){((BaseMapActivity) mFragActivity).locationReady(false);}
}
/*
* Called by Location Services if the attempt to
* Location Services fails.
*/
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
/*
* Google Play services can resolve some errors it detects.
* If the error has a resolution, try sending an Intent to
* start a Google Play services activity that can resolve
* error.
*/
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(
mFragActivity,
AppUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST);
/*
* Thrown if Google Play services canceled the original
* PendingIntent
*/
} catch (IntentSender.SendIntentException e) {
// Log the error
e.printStackTrace();
}
} else {
// If no resolution is available, display a dialog to the user with the error.
showErrorDialog(connectionResult.getErrorCode());
}
}
/**
* Report location updates to the UI.
*
* @param location The updated location.
*/
@Override
public void onLocationChanged(Location location) {
Log.d(TAG, App.getAppContext().getString(R.string.location_updated));
if (mMensaListAdapter != null){
mMensaListAdapter.locationReady(true);
mMensaListAdapter.notifyDataSetChanged();
}
}
/**
* In response to a request to start updates, send a request
* to Location Services
*/
private void startPeriodicUpdates() {
mLocationClient.requestLocationUpdates(mLocationRequest, this);
}
/**
* In response to a request to stop updates, send a request to
* Location Services
*/
private void stopPeriodicUpdates() {
mLocationClient.removeLocationUpdates(this);
}
/**
* Show a dialog returned by Google Play services for the
* connection error code
*
* @param errorCode An error code returned from onConnectionFailed
*/
private void showErrorDialog(int errorCode) {
// Get the error dialog from Google Play services
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
errorCode,
mFragActivity,
AppUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST);
// If Google Play services can provide an error dialog
if (errorDialog != null) {
// Create a new DialogFragment in which to show the error dialog
ErrorDialogFragment errorFragment = new ErrorDialogFragment();
// Set the dialog in the DialogFragment
errorFragment.setDialog(errorDialog);
// Show the error dialog in the DialogFragment
errorFragment.show(mFragActivity.getSupportFragmentManager(), AppUtils.APPTAG);
}
}
/**
* Define a DialogFragment to display the error dialog generated in
* showErrorDialog.
*/
public static class ErrorDialogFragment extends DialogFragment {
// Global field to contain the error dialog
private Dialog mDialog;
/**
* Default constructor. Sets the dialog field to null
*/
public ErrorDialogFragment() {
super();
mDialog = null;
}
/**
* Set the dialog to display
*
* @param dialog An error dialog
*/
public void setDialog(Dialog dialog) {
mDialog = dialog;
}
/*
* This method must return a Dialog to the DialogFragment.
*/
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return mDialog;
}
}
public void setAdapter(MensaListAdapter mensaListAdapter) {
mMensaListAdapter = mensaListAdapter;
}
public void setActivity(MensaActivity mensaActivity) {
mFragActivity = mensaActivity;
}
public void setActivity(BaseMapActivity mapActivity){
mFragActivity = mapActivity;
}
}