package com.alimuzaffar.sunalarm.activity;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import org.json.JSONArray;
import org.json.JSONObject;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.location.Location;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.DialogFragment;
import android.support.v4.widget.SimpleCursorAdapter;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.Window;
import com.actionbarsherlock.widget.SearchView;
import com.actionbarsherlock.widget.SearchView.OnQueryTextListener;
import com.actionbarsherlock.widget.SearchView.OnSuggestionListener;
import com.alimuzaffar.sunalarm.BuildConfig;
import com.alimuzaffar.sunalarm.R;
import com.alimuzaffar.sunalarm.receiver.AlarmReceiver;
import com.alimuzaffar.sunalarm.util.AppRater;
import com.alimuzaffar.sunalarm.util.AppSettings;
import com.alimuzaffar.sunalarm.util.AppSettings.Key;
import com.alimuzaffar.sunalarm.util.ChangeLog;
import com.alimuzaffar.sunalarm.util.JsonHttpHelper;
import com.alimuzaffar.sunalarm.util.Utils;
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.LocationRequest;
import com.luckycatlabs.sunrisesunset.SunriseSunsetCalculator;
public class ShowStatusActivity extends SherlockFragmentActivity implements
OnCheckedChangeListener, OnQueryTextListener, OnSuggestionListener,
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener {
private static final String TAG = "ShowStatusActivity";
private static int SETTINGS = 808;
//Constants that define the activity detection interval
// Milliseconds per second
private static final int MILLISECONDS_PER_SECOND = 1000;
// Update frequency in seconds
public static final int UPDATE_INTERVAL_IN_SECONDS = 5;
// Update frequency in milliseconds
private static final long UPDATE_INTERVAL =
MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN_SECONDS;
// The fastest update frequency, in seconds
private static final int FASTEST_INTERVAL_IN_SECONDS = 1;
// A fast frequency ceiling in milliseconds
private static final long FASTEST_INTERVAL =
MILLISECONDS_PER_SECOND * FASTEST_INTERVAL_IN_SECONDS;
public static SimpleDateFormat TIME_24HRS = new SimpleDateFormat("HH:mm", Locale.getDefault());
public static SimpleDateFormat TIME_12HRS = new SimpleDateFormat("hh:mm a", Locale.getDefault());
private TextView duskTime, dawnTime, duskTitle, dawnTitle;
private View duskTimeProgress, dawnTimeProgress;
private CompoundButton duskAlarmSet, dawnAlarmSet;
private EditText delayDawnAlarm, delayDuskAlarm;
private Calendar todaySunriseCal;
private Calendar todaySunsetCal;
private Calendar tomorrowSunriseCal;
private Calendar tomorrowSunsetCal;
private Calendar nextSunriseCal;
private Calendar nextSunsetCal;
SunriseSunsetCalculator calculator = null;
//Global variable to hold the current location
private Location mCurrentLocation;
// A request to connect to Location Services
private LocationRequest mLocationRequest;
private LocationClient mLocationClient;
SearchView mSearchView;
SimpleCursorAdapter simpleCursorAdapter;
MenuItem mChangeLocation;
// Global constants
/*
* Define a request code to send to Google Play services This code is
* returned in Activity.onActivityResult
*/
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
// Define a DialogFragment that displays the error dialog
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
public void setDialog(Dialog dialog) {
mDialog = dialog;
}
// Return a Dialog to the DialogFragment.
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return mDialog;
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// requestWindowFeature(Window.FEATURE_PROGRESS);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_show_status);
setVolumeControlStream(AudioManager.STREAM_ALARM);
// initialize preferences
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
dawnTime = (TextView) findViewById(R.id.dawnTime);
duskTime = (TextView) findViewById(R.id.duskTime);
dawnTimeProgress = findViewById(R.id.dawnTimeProgress);
duskTimeProgress = findViewById(R.id.duskTimeProgress);
dawnTitle = (TextView) findViewById(R.id.dawn);
duskTitle = (TextView) findViewById(R.id.dusk);
duskAlarmSet = (CompoundButton) findViewById(R.id.duskAlarmSet);
dawnAlarmSet = (CompoundButton) findViewById(R.id.dawnAlarmSet);
delayDawnAlarm = (EditText) findViewById(R.id.delayDawnAlarm);
delayDuskAlarm = (EditText) findViewById(R.id.delayDuskAlarm);
bindToggleButtons();
ChangeLog cl = new ChangeLog(this);
if (cl.firstRun()) cl.getLogDialog().show();
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
mLocationClient = new LocationClient(this, this, this);
// Create a new global location parameters object
mLocationRequest = LocationRequest.create();
// Use high accuracy
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// Set the update interval to 5 seconds
mLocationRequest.setInterval(UPDATE_INTERVAL);
// Set the fastest update interval to 1 second
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
AppRater.app_launched(this);
// needed for 2.3 < devices.
setSupportProgressBarIndeterminateVisibility(false);
}
@Override
protected void onStart() {
super.onStart();
// Connect the client.
mLocationClient.connect();
}
@Override
protected void onResume() {
super.onResume();
final AppSettings settings = AppSettings.getInstance(getApplicationContext());
if (!settings.getBoolean(Key.MANUAL_LOCATION, false)) {
//mLocationClient.requestLocationUpdates(mLocationRequest, this);
getSupportActionBar().setSubtitle("Automatically detect location.");
} else {
String location = settings.getString(Key.MANUAL_LOCATION_NAME);
getSupportActionBar().setSubtitle(location);
}
// enable everything
duskAlarmSet.setEnabled(true);
dawnAlarmSet.setEnabled(true);
delayDawnAlarm.setEnabled(true);
delayDuskAlarm.setEnabled(true);
LinearLayout myLayout = (LinearLayout) findViewById(R.id.focussucker);
myLayout.requestFocus();
String[] from = { "text" };
int[] to = { android.R.id.text1 };
if (simpleCursorAdapter == null)
simpleCursorAdapter =
new SimpleCursorAdapter(ShowStatusActivity.this, android.R.layout.simple_list_item_1,
new MatrixCursor(new String[] { "_id", "text" }), from, to, 0);
}
@Override
protected void onStop() {
// If the client is connected
if (mLocationClient.isConnected()) {
/*
* Remove location updates for a listener.
* The current Activity is the listener, so
* the argument is "this".
*/
mLocationClient.removeLocationUpdates(this);
}
/*
* After disconnect() is called, the client is
* considered "dead".
*/
mLocationClient.disconnect();
super.onStop();
}
private void calculate(String timeZoneId) {
if (calculator != null) {
TimeZone tz = TimeZone.getTimeZone(timeZoneId);
Calendar cal = Calendar.getInstance(tz);
todaySunriseCal = Utils.getSunrise(this, calculator, cal);
todaySunsetCal = Utils.getSunset(this, calculator, cal);
cal.add(Calendar.DATE, 1);
tomorrowSunriseCal = Utils.getSunrise(this, calculator, cal);
tomorrowSunsetCal = Utils.getSunset(this, calculator, cal);
if (todaySunriseCal == null || todaySunsetCal == null || tomorrowSunriseCal == null
|| tomorrowSunsetCal == null) {
Toast.makeText(this, "Something went wrong. Cannot calculate timing.", Toast.LENGTH_LONG)
.show();
return;
}
String dawnText = null;
boolean dawnToday, duskToday = false;
if (todaySunriseCal.before(Calendar.getInstance(tz))) {
nextSunriseCal = tomorrowSunriseCal;
TIME_12HRS.setTimeZone(nextSunriseCal.getTimeZone());
dawnText = TIME_12HRS.format(nextSunriseCal.getTime());
dawnToday = false;
} else {
nextSunriseCal = todaySunriseCal;
TIME_12HRS.setTimeZone(nextSunriseCal.getTimeZone());
dawnText = TIME_12HRS.format(nextSunriseCal.getTime());
dawnToday = true;
}
String duskText = null;
if (todaySunsetCal.before(Calendar.getInstance(tz))) {
nextSunsetCal = tomorrowSunsetCal;
TIME_12HRS.setTimeZone(nextSunsetCal.getTimeZone());
duskText = TIME_12HRS.format(nextSunsetCal.getTime());
duskToday = false;
} else {
nextSunsetCal = todaySunsetCal;
TIME_12HRS.setTimeZone(nextSunsetCal.getTimeZone());
duskText = TIME_12HRS.format(nextSunsetCal.getTime());
duskToday = true;
}
if (dawnToday) {
dawnTitle.setText(getString(R.string.s_dawn, getString(R.string.today)));
} else {
dawnTitle.setText(getString(R.string.s_dawn, getString(R.string.tomorrow)));
}
if (duskToday) {
duskTitle.setText(getString(R.string.s_dusk, getString(R.string.today)));
} else {
duskTitle.setText(getString(R.string.s_dusk, getString(R.string.tomorrow)));
}
dawnTime.setText(dawnText);
duskTime.setText(duskText);
dawnTimeProgress.setVisibility(View.INVISIBLE);
duskTimeProgress.setVisibility(View.INVISIBLE);
dawnTime.setVisibility(View.VISIBLE);
duskTime.setVisibility(View.VISIBLE);
AppSettings settings = AppSettings.getInstance(this);
if (settings.getBoolean(Key.DAWN_ALARM)) {
updateAlarms(true, false);
}
if (settings.getBoolean(Key.DUSK_ALARM)) {
updateAlarms(false, true);
}
}
}
private void bindToggleButtons() {
AppSettings settings = AppSettings.getInstance(ShowStatusActivity.this.getApplicationContext());
dawnAlarmSet.setChecked(settings.getBoolean(Key.DAWN_ALARM));
duskAlarmSet.setChecked(settings.getBoolean(Key.DUSK_ALARM));
delayDawnAlarm.setText(String.valueOf(settings.getInt(Key.DAWN_DELAY)));
delayDuskAlarm.setText(String.valueOf(settings.getInt(Key.DUSK_DELAY)));
duskAlarmSet.setOnCheckedChangeListener(this);
dawnAlarmSet.setOnCheckedChangeListener(this);
delayDawnAlarm.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
AppSettings settings = AppSettings.getInstance(getApplicationContext());
int num = 0;
try {
num = Integer.parseInt(s.toString());
} catch (NumberFormatException nfe) {
num = 0;
}
settings.set(Key.DAWN_DELAY, num);
if (settings.getBoolean(Key.DAWN_ALARM)) {
updateAlarms(true, false);
}
}
});
delayDuskAlarm.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
AppSettings settings = AppSettings.getInstance(getApplicationContext());
int num = 0;
try {
num = Integer.parseInt(s.toString());
} catch (NumberFormatException nfe) {
num = 0;
}
settings.set(Key.DUSK_DELAY, num);
if (settings.getBoolean(Key.DUSK_ALARM)) {
updateAlarms(false, true);
}
}
});
if (AppSettings.DEBUG) {
bindTestButtons();
} else {
removeTestButtons();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.show_status, menu);
mChangeLocation = menu.findItem(R.id.menu_changeloc);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.menu_settings) {
Intent intent = new Intent(this, SettingsActivity.class);
startActivityForResult(intent, SETTINGS);
}
else if (item.getItemId() == R.id.menu_changeloc) {
if (mSearchView == null) {
mSearchView = (SearchView) item.getActionView();
mSearchView.setQueryHint("City Name");
mSearchView.setOnQueryTextListener(this);
mSearchView.setOnSuggestionListener(this);
mSearchView.setSuggestionsAdapter(simpleCursorAdapter);
}
if (!isOnline()) {
Toast.makeText(this, "No internet connection detected.", Toast.LENGTH_SHORT).show();
item.collapseActionView();
}
} else if (item.getItemId() == R.id.menu_clear_location) {
clearSetLocation();
} else if (item.getItemId() == R.id.menu_help) {
Intent intent = new Intent(this, HelpActivity.class);
startActivity(intent);
}
return false;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == SETTINGS) {
AppSettings settings = AppSettings.getInstance(getApplicationContext());
String timeZoneId = settings.getString(Key.TIMEZONE_ID, TimeZone.getDefault().getID());
calculate(timeZoneId);
updateAlarms(true, true);
} else if (requestCode == CONNECTION_FAILURE_RESOLUTION_REQUEST) {
// Decide what to do based on the original request code
/*
* If the result code is Activity.RESULT_OK, try to connect again
*/
if (resultCode == Activity.RESULT_OK) {
/*
* Try the request again
*/
}
}
}
private void updateAlarms(boolean dawn, boolean dusk) {
AppSettings settings = AppSettings.getInstance(getApplicationContext());
if (dawn && settings.getBoolean(Key.DAWN_ALARM) && nextSunriseCal != null) {
Utils.stopAlarm(getApplicationContext(), Key.DAWN_ALARM.toString());
Utils.setAlarm(getApplicationContext(), nextSunriseCal, Key.DAWN_ALARM.toString());
}
if (dusk && settings.getBoolean(Key.DUSK_ALARM) && nextSunsetCal != null) {
Utils.stopAlarm(getApplicationContext(), Key.DUSK_ALARM.toString());
Utils.setAlarm(getApplicationContext(), nextSunsetCal, Key.DUSK_ALARM.toString());
}
if (nextSunriseCal == null || nextSunsetCal == null) {
Toast
.makeText(
this,
"ERROR: Alarm has not have been set.\nUnable to determine alarm times.\nEnable GPS and try again.",
Toast.LENGTH_LONG).show();
}
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
AppSettings settings = AppSettings.getInstance(ShowStatusActivity.this.getApplicationContext());
if (buttonView.getId() == R.id.dawnAlarmSet && nextSunriseCal != null) {
settings.set(Key.DAWN_ALARM, isChecked);
if (isChecked)
Utils.setAlarm(getApplicationContext(), nextSunriseCal, Key.DAWN_ALARM.toString());
else Utils.stopAlarm(getApplicationContext(), Key.DAWN_ALARM.toString());
} else if (buttonView.getId() == R.id.duskAlarmSet && nextSunsetCal != null) {
settings.set(Key.DUSK_ALARM, isChecked);
if (isChecked)
Utils.setAlarm(getApplicationContext(), nextSunsetCal, Key.DUSK_ALARM.toString());
else Utils.stopAlarm(getApplicationContext(), Key.DUSK_ALARM.toString());
}
if (nextSunriseCal == null || nextSunsetCal == null) {
Toast
.makeText(
this,
"ERROR: Alarm has not have been set.\nUnable to determine alarm times.\nEnable GPS and try again.",
Toast.LENGTH_LONG).show();
}
}
private void bindTestButtons() {
Button testDawn = ((Button) findViewById(R.id.testDawn));
testDawn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(ShowStatusActivity.this, AlarmReceiver.class);
intent.putExtra("alarm_type", Key.DAWN_ALARM.toString());//
sendBroadcast(intent);
}
});
Button testDusk = ((Button) findViewById(R.id.testDusk));
testDusk.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(ShowStatusActivity.this, AlarmReceiver.class);
intent.putExtra("alarm_type", Key.DUSK_ALARM.toString());
sendBroadcast(intent);
}
});
}
private void removeTestButtons() {
TableRow tableRow7 = ((TableRow) findViewById(R.id.tableRow7));
tableRow7.setVisibility(View.GONE);
}
private void clearSetLocation() {
final AppSettings settings = AppSettings.getInstance(getApplicationContext());
settings.set(Key.MANUAL_LOCATION, false);
settings.set(Key.MANUAL_LOCATION_NAME, "Automatically detect location.");
getSupportActionBar().setSubtitle("Automatically detect location.");
getAutoLocation();
}
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if (newText.length() > 1) {
simpleCursorAdapter.changeCursor(new MatrixCursor(new String[] { "_id", "text" }));
setSupportProgressBarIndeterminateVisibility(true);
(new FetchLocationsAsyncTask() {
protected void onPostExecute(MatrixCursor cursor) {
// dismiss UI progress indicator
// process the result
// ...
setSupportProgressBarIndeterminateVisibility(false);
String[] from = { "text" };
int[] to = { android.R.id.text1 };
if (simpleCursorAdapter == null)
simpleCursorAdapter =
new SimpleCursorAdapter(ShowStatusActivity.this,
android.R.layout.simple_list_item_1, cursor, from, to, 0);
else simpleCursorAdapter.changeCursor(cursor);
mSearchView.setSuggestionsAdapter(simpleCursorAdapter);
}
}).execute(newText, getResources().getString(R.string.places_api_key)); // start
// the
// background
// processing
}
return false;
}
@Override
public boolean onSuggestionSelect(int position) {
return false;
}
@Override
public boolean onSuggestionClick(int position) {
final AppSettings settings = AppSettings.getInstance(getApplicationContext());
Cursor c = mSearchView.getSuggestionsAdapter().getCursor();
c.moveToPosition(position);
String suggestion = c.getString(1);
mChangeLocation.collapseActionView();
// Log.d(TAG, "NEW LOCATION >>>> " + suggestion);
Toast.makeText(this, "Setting your location to \"" + suggestion + "\"", Toast.LENGTH_SHORT)
.show();
settings.set(Key.MANUAL_LOCATION, true);
settings.set(Key.MANUAL_LOCATION_NAME, suggestion);
getSupportActionBar().setSubtitle(suggestion);
(new FetchGeoLocationAsyncTask() {
protected void onPostExecute(JSONObject result) {
// set lat lng & timezone
try {
double lat = Double.parseDouble(result.getString("lat"));
double lng = Double.parseDouble(result.getString("lng"));
settings.set(Key.LAST_LATITUDE, lat);
settings.set(Key.LAST_LONGITUDE, lng);
String timeZoneId = result.getString("timeZoneId");
settings.set(Key.TIMEZONE_ID, timeZoneId);
Log.d(getClass().getSimpleName(), result.toString());
calculator =
new SunriseSunsetCalculator(
new com.luckycatlabs.sunrisesunset.dto.Location(lat, lng), timeZoneId);
calculate(timeZoneId);
if (settings.getBoolean(Key.DAWN_ALARM)) {
updateAlarms(true, false);
}
if (settings.getBoolean(Key.DUSK_ALARM)) {
updateAlarms(false, true);
}
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
Toast.makeText(ShowStatusActivity.this, "Something went wrong. Could not set location.",
Toast.LENGTH_LONG).show();
}
}
}).execute(suggestion);
return false;
}
public boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected()) {
return true;
}
return false;
}
private boolean servicesConnected() {
// Check that Google Play services is available
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
// In debug mode, log the status
Log.d("Location Updates", "Google Play services is available.");
// Continue
return true;
// Google Play services was not available for some reason
} else {
// Get the error code
// Get the error dialog from Google Play services
Dialog errorDialog =
GooglePlayServicesUtil.getErrorDialog(resultCode, this,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
// If Google Play services can provide an error dialog
if (errorDialog != null) {
// Create a new DialogFragment for 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(getSupportFragmentManager(), "Location Updates");
}
return false;
}
}
/*
* 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 dataBundle) {
AppSettings settings = AppSettings.getInstance(this);
if (settings.getBoolean(Key.MANUAL_LOCATION, false)) {
double lat = settings.getDouble(Key.LAST_LATITUDE);
double lng = settings.getDouble(Key.LAST_LONGITUDE);
String timeZoneId = settings.getString(Key.TIMEZONE_ID);
calculator =
new SunriseSunsetCalculator(
new com.luckycatlabs.sunrisesunset.dto.Location(lat, lng), timeZoneId);
calculate(timeZoneId);
} else {
getAutoLocation();
}
}
private void getAutoLocation() {
mCurrentLocation = mLocationClient.getLastLocation();
if (mCurrentLocation == null) {
mLocationClient.requestLocationUpdates(mLocationRequest, this);
} else {
Toast.makeText(this, "getAutoLocation: Location: " + mCurrentLocation.getLatitude() + ", " + mCurrentLocation.getLongitude(), Toast.LENGTH_SHORT).show();
calculate(mCurrentLocation);
}
}
private void enableOrDisable() {
AppSettings settings = AppSettings.getInstance(this);
if (settings.getDouble(Key.LAST_LATITUDE) != 0
&& settings.getDouble(Key.LAST_LONGITUDE) != 0) {
// use saved location.
String timeZoneId =
settings.getString(Key.TIMEZONE_ID, TimeZone.getDefault().getID());
calculator =
new SunriseSunsetCalculator(new com.luckycatlabs.sunrisesunset.dto.Location(
settings.getDouble(Key.LAST_LATITUDE), settings
.getDouble(Key.LAST_LONGITUDE)), timeZoneId);
calculate(timeZoneId);
dawnTimeProgress.setVisibility(View.INVISIBLE);
duskTimeProgress.setVisibility(View.INVISIBLE);
dawnTime.setVisibility(View.VISIBLE);
duskTime.setVisibility(View.VISIBLE);
} else {
// disable everything, no saved
// location, no way to get it.
dawnTime.setVisibility(View.INVISIBLE);
duskTime.setVisibility(View.INVISIBLE);
dawnTimeProgress.setVisibility(View.INVISIBLE);
duskTimeProgress.setVisibility(View.INVISIBLE);
duskAlarmSet.setEnabled(false);
dawnAlarmSet.setEnabled(false);
delayDawnAlarm.setEnabled(false);
delayDuskAlarm.setEnabled(false);
}
}
private void calculate(Location location) {
AppSettings settings = AppSettings.getInstance(this);
calculator =
new SunriseSunsetCalculator(new com.luckycatlabs.sunrisesunset.dto.Location(location
.getLatitude(), location.getLongitude()), TimeZone.getDefault().getID());
settings.set(Key.LAST_LATITUDE, location.getLatitude());
settings.set(Key.LAST_LONGITUDE, location.getLongitude());
settings.set(Key.TIMEZONE_ID, TimeZone.getDefault().getID());
calculate(TimeZone.getDefault().getID());
}
/*
* Called by Location Services if the connection to the
* location client drops because of an error.
*/
@Override
public void onDisconnected() {
// Display the connection status
Toast.makeText(this, "Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
}
/*
* 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(this, 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());
}
}
private boolean showErrorDialog(int errorCode) {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
// In debug mode, log the status
// Continue
return true;
// Google Play services was not available for some reason
} else {
Dialog errorDialog =
GooglePlayServicesUtil.getErrorDialog(errorCode, this,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
// If Google Play services can provide an error dialog
if (errorDialog != null) {
// Create a new DialogFragment for 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(getSupportFragmentManager(), "Location Updates");
}
return false;
}
}
@Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
mLocationClient.removeLocationUpdates(this);
String msg =
"onLocationChanged: Updated Location: " + Double.toString(location.getLatitude()) + ","
+ Double.toString(location.getLongitude());
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
calculate(location);
}
}
class FetchLocationsAsyncTask extends AsyncTask<String, Integer, MatrixCursor> {
// web key used.
private static String PLACES_URL =
"https://maps.googleapis.com/maps/api/place/autocomplete/json?input=%s&types=(cities)&sensor=true&key=%s";
@Override
protected MatrixCursor doInBackground(String... params) {
String[] columnNames = { "_id", "text" };
MatrixCursor cursor = new MatrixCursor(columnNames);
try {
String url = String.format(PLACES_URL, URLEncoder.encode(params[0], "UTF-8"), params[1]);
if (BuildConfig.DEBUG) Log.d("FetchLocationsAsyncTask", "Places API = " + url);
JSONObject jsonObject = JsonHttpHelper.getJson(url);
JSONArray predictions = jsonObject.optJSONArray("predictions");
if (predictions != null) {
List<String> results = new ArrayList<String>();
for (int i = 0; i < predictions.length(); i++) {
JSONObject item = predictions.getJSONObject(i);
String description = item.getString("description");
results.add(description);
}
String[] temp = new String[2];
int id = 0;
for (String item : results) {
temp[0] = Integer.toString(id++);
temp[1] = item;
cursor.addRow(temp);
}
}
} catch (Exception e) {
Log.e("FetchLocationsAsyncTask", e.getMessage(), e);
}
return cursor;
}
}
class FetchGeoLocationAsyncTask extends AsyncTask<String, Integer, JSONObject> {
private static final String GEO_URL =
"http://maps.google.com/maps/api/geocode/json?address=%s&sensor=true";
private static final String TZ_URL =
"https://maps.googleapis.com/maps/api/timezone/json?location=%s×tamp="
+ System.currentTimeMillis() / 1000 + "&sensor=true";
@Override
protected JSONObject doInBackground(String... params) {
try {
String url = String.format(GEO_URL, URLEncoder.encode(params[0], "UTF-8"));
JSONObject jsonObject = JsonHttpHelper.getJson(url);
if (BuildConfig.DEBUG) Log.d("FetchLocationsAsyncTask", "GEO API = " + url);
if (BuildConfig.DEBUG) Log.d("FetchGeoLocationAsyncTask", jsonObject.toString());
JSONArray results = jsonObject.getJSONArray("results");
JSONObject item = results.getJSONObject(0);
JSONObject geo = item.getJSONObject("geometry").getJSONObject("location");
JSONObject result = new JSONObject();
result.put("name", item.getString("formatted_address"));
String lat = geo.getString("lat");
result.put("lat", lat);
String lng = geo.getString("lng");
result.put("lng", lng);
String tzUrl = String.format(TZ_URL, URLEncoder.encode(lat + "," + lng, "UTF-8"));
if (BuildConfig.DEBUG) Log.d("FetchLocationsAsyncTask", "TIMEZONE API = " + tzUrl);
JSONObject tzObj = JsonHttpHelper.getJson(tzUrl);
if (tzObj != null) {
String tzId = tzObj.getString("timeZoneId");
result.put("timeZoneId", tzId);
}
return result;
} catch (Exception e) {
Log.e("FetchGeoLocationAsyncTask", e.getMessage(), e);
}
return null;
}
}