package com.integreight.onesheeld.shields.controller;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v4.app.DialogFragment;
import android.text.TextUtils;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.integreight.onesheeld.sdk.ShieldFrame;
import com.integreight.onesheeld.MainActivity;
import com.integreight.onesheeld.R;
import com.integreight.onesheeld.enums.UIShield;
import com.integreight.onesheeld.shields.ControllerParent;
import com.integreight.onesheeld.shields.controller.utils.SendFrameHandler;
import com.integreight.onesheeld.utils.CrashlyticsUtils;
import com.integreight.onesheeld.utils.Log;
public class GpsShield extends ControllerParent<GpsShield> implements
LocationListener, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, SendFrameHandler {
public static final byte GPS_VALUE = 0x01;
private GpsEventHandler eventHandler;
private LocationRequest mLocationRequest;
private GoogleApiClient mLocationClient;
private boolean mUpdatesRequested;
private ShieldFrame frame;
private LocationManager manager;
private static final int SERVICE_VERSION_UPDATE_REQUIRED = 2,
SERVICE_MISSING = 1, SERVICE_DISABLED = 3, CANCELED = 13,
SUCCESS = 0;
private Location lastKnownLocation;
int PERIOD = 5000;
public GpsShield() {
}
public GpsShield(Activity activity, String tag) {
super(activity, tag);
}
@Override
public ControllerParent<GpsShield> init(String tag) {
mLocationClient = new GoogleApiClient.Builder(getApplication())
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mUpdatesRequested = false;
manager = (LocationManager) getApplication().getSystemService(
Context.LOCATION_SERVICE);
// check if Google play services available, no dialog displayed
if (isGoogleplayServicesAvailableNoDialogs()) {
if (manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
startGps();
}
return super.init(tag);
}
@Override
public ControllerParent<GpsShield> invalidate(SelectionAction selectionAction, boolean isToastable) {
this.selectionAction =selectionAction;
addRequiredPremission(Manifest.permission.ACCESS_FINE_LOCATION);
if (checkForPermissions()) {
if(!isLocationServicesEnabled()){
buildAlertMessageNoGps();
if (this.selectionAction != null) {
this.selectionAction.onFailure();
}
}
else {
if (selectionAction != null)
selectionAction.onSuccess();
}
}else {
if (selectionAction != null)
selectionAction.onFailure();
}
return super.invalidate(selectionAction, isToastable);
}
public void setGpsEventHandler(GpsEventHandler eventHandler) {
this.eventHandler = eventHandler;
}
@Override
public void onNewShieldFrameReceived(ShieldFrame frame) {
// TODO Auto-generated method stub
}
public static class ErrorDialogFragment extends DialogFragment {
private Dialog mDialog;
public ErrorDialogFragment() {
super();
mDialog = null;
}
public void setDialog(Dialog dialog) {
mDialog = dialog;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return mDialog;
}
}
public void startGps() {
mUpdatesRequested = true;
mLocationRequest = LocationRequest.create();
mLocationRequest.setInterval(PERIOD);
mLocationRequest.setFastestInterval(PERIOD);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// check Internet connection
mLocationClient = new GoogleApiClient.Builder(getApplication())
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
if (mLocationClient != null)
mLocationClient.connect();
}
public void isGooglePlayServicesAvailableWithDialog() {
// checking if Google play services exist or not.
if (mLocationClient != null) {
if (isGooglePlayServicesAvailable()) {
if (!isLocationServicesEnabled()) {
buildAlertMessageNoGps();
}
} else
Log.d("Gps",
"Google Play services was not available for some reasons");
}
}
private boolean isLocationServicesEnabled(){
int locationMode = 0;
String locationProviders;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
try {
locationMode = Settings.Secure.getInt(getActivity().getContentResolver(), Settings.Secure.LOCATION_MODE);
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
}
return locationMode != Settings.Secure.LOCATION_MODE_OFF;
}else{
locationProviders = Settings.Secure.getString(getActivity().getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
return !TextUtils.isEmpty(locationProviders);
}
}
private void buildAlertMessageNoGps() {
final AlertDialog.Builder builder = new AlertDialog.Builder(
getActivity());
builder.setMessage(
R.string.gps_we_need_you_to_enable_the_location_services_for_this_shield_to_work_correctly)
.setCancelable(false)
.setPositiveButton(R.string.gps_validation_dialog_ok_button,
new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog,
final int id) {
getActivity()
.startActivity(
new Intent(
Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
})
.setNegativeButton(R.string.gps_validation_dialog_later_button, new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog,
final int id) {
dialog.cancel();
activity.showToast(R.string.gps_please_enable_location_services_to_be_able_to_use_this_shield);
}
});
final AlertDialog alert = builder.create();
alert.show();
}
public void stopGps() {
mUpdatesRequested = false;
if (mLocationClient!=null && mLocationClient.isConnected()) {
mLocationClient.disconnect();
mLocationClient.unregisterConnectionCallbacks(this);
}
}
private void showErrorDialog(int errorCode) {
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(errorCode,
getActivity(), 0);
if (errorDialog != null) {
ErrorDialogFragment errorFragment = new ErrorDialogFragment();
errorFragment.setDialog(errorDialog);
errorFragment.show(
((MainActivity) getActivity()).getSupportFragmentManager(),
activity.getString(R.string.gps_shield_name)+" Shield");
}
}
private boolean isGooglePlayServicesAvailable() {
// Check that Google Play services is available
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(getActivity()
.getApplicationContext());
switch (resultCode) {
case SUCCESS:
return true;
case SERVICE_DISABLED:
showErrorDialog(SERVICE_DISABLED);
return false;
case SERVICE_MISSING:
showErrorDialog(SERVICE_MISSING);
return false;
case SERVICE_VERSION_UPDATE_REQUIRED:
showErrorDialog(SERVICE_VERSION_UPDATE_REQUIRED);
return false;
case CANCELED:
showErrorDialog(CANCELED);
return false;
}
return false;
}
private boolean isGoogleplayServicesAvailableNoDialogs() {
// Check that Google Play services is available
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(getActivity()
.getApplicationContext());
switch (resultCode) {
case SUCCESS:
return true;
case SERVICE_DISABLED:
return false;
case SERVICE_MISSING:
return false;
case SERVICE_VERSION_UPDATE_REQUIRED:
return false;
case CANCELED:
return false;
}
return false;
}
public interface GpsEventHandler {
void onLangChanged(String lang);
void onLatChanged(String lat);
}
@Override
public void reset() {
// TODO Auto-generated method stub
stopGps();
}
@Override
public void onLocationChanged(Location arg0) {
// TODO Auto-generated method stub
if (eventHandler != null && mLocationClient.isConnected()) {
lastKnownLocation = arg0;
eventHandler.onLangChanged(arg0.getLongitude() + "");
eventHandler.onLatChanged(arg0.getLatitude() + "");
}
// lastLocation = arg0;
sendFrame(arg0);
}
@Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
Log.d("GPS Location Failed", arg0.toString());
}
public Location getLastKnownLocation() {
return lastKnownLocation;
}
@Override
public void onConnected(Bundle arg0) {
// TODO Auto-generated method stub
try {
if (mUpdatesRequested && mLocationRequest != null
&& mLocationClient != null) {
LocationServices.FusedLocationApi.requestLocationUpdates(
mLocationClient, mLocationRequest, this);
}
}catch (SecurityException | IllegalStateException ignored){
CrashlyticsUtils.logException(ignored);
}
}
private void sendFrame(Location myLocation) {
// TODO Auto-generated method stub
frame = new ShieldFrame(UIShield.GPS_SHIELD.getId(), GPS_VALUE);
float lat = (float) myLocation.getLatitude();
float lang = (float) myLocation.getLongitude();
frame.addArgument(lat);
frame.addArgument(lang);
sendShieldFrame(frame);
}
@Override
public void sendFrameHandler(Location location) {
if (location != null) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
if (eventHandler != null) {
eventHandler.onLangChanged(latitude + "");
eventHandler.onLatChanged(longitude + "");
}
sendFrame(location);
}
}
@Override
public void onConnectionSuspended(int arg0) {
// TODO Auto-generated method stub
}
}