package com.twormobile.itrackmygps;
import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.*;
import android.location.*;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.Settings;
import com.twormobile.itrackmygps.android.Log;
import android.view.*;
import android.widget.*;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
public class MainActivity extends Activity{
private static final String TAG = "MainActivity";
private TextView tvUsername;
private ImageButton btnTracker;
private ImageView ivGpsFixStatus;
private TextView tvGpsFixStatus;
private LinearLayout layoutGPSStatus;
private LinearLayout layoutGPSDetails;
private TextView tvGPSCounter;
private TextView tvGPSLatitude;
private TextView tvGPSLongitude;
private TextView tvGPSAltitude;
private TextView tvGPSBearing;
private TextView tvGPSSpeed;
private TextView tvGPSDateTime;
private TextView tvGPSAccuracy;
private TextView tvGPSProvider;
private TextView tvGPSTotalSatellites;
private TextView tvTimeInterval;
private TextView tvTimeIntervalTitle;
private GoogleMap gmap;
private boolean firstFix = true;
private Marker marker;
private int mapLayer;
private float currentZoom; //tracks the current zoom of the map
private boolean isZoomBasedOnSpeed;
private GpsLoggerApplication gpsApp;
private GpsManager gpsManager;
private GpsConnectionStatusReceiver mGpsNetworkStatusReceiver;
private WifiStatusReceiver mWifiStatusReceiver;
private TimeIntervalChangeReceiver mTimeIntervalReceiver;
/**
* When WIFI is disconnected, starts the location service.
* When WIFI is connected and the service is set to ON, poll every 5 minutes
*/
public class WifiStatusReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
if(ApplicationConstants.DEBUG) {
if(gpsApp.isWiFiConnected())
gpsApp.showToast("WIFI in range");
else
gpsApp.showToast("WIFI not in range");
}
if(gpsApp.isON()) {
gpsManager.stopLocationProviders();
gpsManager.startLocationProviders();
}
}
}
public class TimeIntervalChangeReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Log.d("Time Interval Changed", "onReceived");
String strInterval = intent.getStringExtra("TIME_INTERVAL");
tvTimeInterval.setText(strInterval);
}
}
public class GpsConnectionStatusReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Log.d("GpsConnectionStatusReceiver", "onReceived");
updateGpsFixConnectionStatus();
}
}
private BroadcastReceiver mLocationReceiver = new LocationReceiver() {
@Override
protected void onLocationReceived(Context context, Location loc, int ctr) {
displayGPSDetails(loc, ctr);
if(gmap != null){
LatLng pos = new LatLng(loc.getLatitude(), loc.getLongitude());
float maxZoom = gmap.getMaxZoomLevel();
if(marker == null){
MarkerOptions markerOptions = new MarkerOptions().position(pos);
marker = gmap.addMarker(markerOptions);
}
marker.setPosition(pos);
// If this is the first fix, zoom to the new position
if(firstFix){
firstFix = false;
currentZoom = maxZoom/2.0f;
gmap.moveCamera(CameraUpdateFactory.newLatLngZoom(pos, currentZoom));
}
else {
// Dynamic zoom based on speed
if(isZoomBasedOnSpeed){
int speed = (int) (loc.getSpeed()*GpsManager.KPH);
boolean isMoving = speed > 1;
boolean isSpeedSlow = isBetween(speed, 10, 40);
boolean isSpeedModerate = isBetween(speed, 41, 60);
boolean isSpeedQuiteFast = isBetween(speed, 61, 80);
boolean isSpeedFast = speed > 81;
if(isSpeedSlow){
currentZoom = maxZoom - 3.0f; //zoom = 18
}
else if(isSpeedModerate){
currentZoom = maxZoom - 4.0f; //zoom = 17
}
else if(isSpeedQuiteFast){
currentZoom = maxZoom - 5.0f; //zoom = 16
}
else if(isSpeedFast){
currentZoom = maxZoom - 6.0f; //zoom = 15
}
else{ //crawling
currentZoom = maxZoom - 2.0f; //zoom = 19
}
if(isMoving){
gmap.moveCamera(CameraUpdateFactory.newLatLngZoom(pos, currentZoom));
}
else{
if(MapUtils.isLatLngNotVisible(pos, gmap)){
gmap.moveCamera(CameraUpdateFactory.newLatLng(pos));
return;
}
}
}
if(MapUtils.isLatLngNotVisible(pos, gmap)){
gmap.moveCamera(CameraUpdateFactory.newLatLng(pos));
return;
}
}
}
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.gpsApp = (GpsLoggerApplication)getApplication();
this.gpsManager = gpsApp.getGpsManager();
if(!gpsManager.isLocationAccessEnabled()){
displayLocationAccessDialog();
}
tvUsername = (TextView)findViewById(R.id.tv_username);
tvTimeInterval = (TextView)findViewById(R.id.tv_time_interval);
tvTimeIntervalTitle = (TextView)findViewById(R.id.tv_time_interval_title);
btnTracker = (ImageButton)findViewById(R.id.btn_tracker);
ivGpsFixStatus = (ImageView)findViewById(R.id.iv_gps_status);
tvGpsFixStatus = (TextView)findViewById(R.id.tv_gps_fix_status);
//find the view layouts
layoutGPSStatus = (LinearLayout)findViewById(R.id.layout_gps_status);
layoutGPSDetails = (LinearLayout)findViewById(R.id.layout_gps_details);
//find the textviews
tvGPSCounter = (TextView)findViewById(R.id.tv_gps_counter);
tvGPSLatitude = (TextView)findViewById(R.id.tv_gps_latitude);
tvGPSLongitude = (TextView)findViewById(R.id.tv_gps_longitude);
tvGPSAltitude = (TextView)findViewById(R.id.tv_gps_altitude);
tvGPSBearing = (TextView)findViewById(R.id.tv_gps_bearing);
tvGPSSpeed = (TextView)findViewById(R.id.tv_gps_speed);
tvGPSDateTime = (TextView)findViewById(R.id.tv_gps_timestamp);
tvGPSAccuracy = (TextView)findViewById(R.id.tv_gps_accuracy);
tvGPSProvider = (TextView)findViewById(R.id.tv_gps_provider);
tvGPSTotalSatellites = (TextView)findViewById(R.id.tv_gps_fix_total_satellites);
ActionBar actionBar = getActionBar();
actionBar.show();
gmap = ((MapFragment) getFragmentManager().findFragmentById(R.id.mapview)).getMap();
mGpsNetworkStatusReceiver = new GpsConnectionStatusReceiver();
showGPSStatus(false);
checkUserInPreferences();
updateButtonTrackerStatus();
this.mWifiStatusReceiver = new WifiStatusReceiver();
final IntentFilter wifiFilters = new IntentFilter();
wifiFilters.addAction("android.net.wifi.STATE_CHANGE");
this.registerReceiver(mWifiStatusReceiver, wifiFilters);
mTimeIntervalReceiver = new TimeIntervalChangeReceiver();
displayTimeInterval(false);
Context context = getApplicationContext();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
getDefaultMapSettings(prefs);
}
private void checkUserInPreferences() {
if(gpsApp.isLoggedIn()){
tvUsername.setText(gpsApp.getUsername());
btnTracker.setEnabled(true);
}
else {
tvUsername.setText("User not logged in.");
btnTracker.setEnabled(false);
}
}
private void getDefaultMapSettings(SharedPreferences prefs){
// we add 1 since GoogleMap.MAP_TYPE_NORMAL starts at 1
mapLayer = prefs.getInt(SettingsActivity.PREF_MAP_LAYER_INDEX, 0) + 1;
isZoomBasedOnSpeed = prefs.getBoolean(SettingsActivity.PREF_ZOOM_BASED_ON_SPEED, true);
if(gmap != null){
gmap.setMapType(mapLayer);
}
}
private void updateFromSettingsPreferences() {
Context context = getApplicationContext();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
getDefaultMapSettings(prefs);
int minTimeInSeconds = prefs.getInt(SettingsActivity.PREF_TIME_INTERVAL_IN_SECONDS,
SettingsActivity.DEFAULT_TIME_INTERVAL_IN_SECONDS);
gpsManager.updateFromSettings(minTimeInSeconds);
}
public void updateButtonTrackerStatus(){
if(gpsApp.isON())
btnTracker.setImageResource(R.drawable.track_on);
else
btnTracker.setImageResource(R.drawable.track_off);
}
public void buttonTrackClicked(View view){
if (gpsApp.isON()) {
Log.i(TAG, "buttonStopPressed");
showGPSStatus(false);
displayTimeInterval(false);
gpsApp.showToast("Tracker Turned OFF");
btnTracker.setImageResource(R.drawable.track_off);
stopService(new Intent(this, GpsLoggerService.class));
}
else {
Log.i(TAG, "buttonStartPressed");
showGPSStatus(true);
displayTimeInterval(true);
gpsApp.showToast("Tracker Turned ON");
btnTracker.setImageResource(R.drawable.track_on);
startService(new Intent(this, GpsLoggerService.class));
}
}
private void displayTimeInterval(boolean f){
if(f) {
tvTimeIntervalTitle.setVisibility(View.VISIBLE);
tvTimeInterval.setVisibility(View.VISIBLE);
}
else {
tvTimeIntervalTitle.setVisibility(View.INVISIBLE);
tvTimeInterval.setVisibility(View.INVISIBLE);
}
}
private void showGPSStatus(boolean f){
if(f) {
layoutGPSDetails.setVisibility(View.VISIBLE);
ivGpsFixStatus.setVisibility(View.VISIBLE);
layoutGPSStatus.setVisibility(View.VISIBLE);
}
else {
layoutGPSDetails.setVisibility(View.INVISIBLE);
ivGpsFixStatus.setVisibility(View.INVISIBLE);
layoutGPSStatus.setVisibility(View.INVISIBLE);
}
}
private void updateGpsFixConnectionStatus() {
GpsFix status = gpsManager.connectionStatus();
ivGpsFixStatus.setImageResource(status.icon());
tvGpsFixStatus.setText(status.toString());
}
@Override
public void onStart() {
super.onStart();
this.registerReceiver(mLocationReceiver, new IntentFilter(IntentCodes.ACTION_LOCATION));
this.registerReceiver(mGpsNetworkStatusReceiver, new IntentFilter(IntentCodes.ACTION_GPS_NETWORK_STATUS));
this.registerReceiver(mTimeIntervalReceiver, new IntentFilter(IntentCodes.ACTION_TIME_INTERVAL_CHANGE));
}
@Override
public void onStop() {
this.unregisterReceiver(mLocationReceiver);
this.unregisterReceiver(mGpsNetworkStatusReceiver);
this.unregisterReceiver(mTimeIntervalReceiver);
super.onStop();
}
private void displayGPSDetails(Location location, int ctr) {
if(location != null){
tvGPSCounter.setText(Integer.toString(ctr));
tvGPSLatitude.setText(Double.toString(location.getLatitude()));
tvGPSLongitude.setText(Double.toString(location.getLongitude()));
tvGPSAltitude.setText(Double.toString(location.getAltitude()));
tvGPSBearing.setText(Float.toString(location.getBearing()));
tvGPSSpeed.setText(Float.toString(location.getSpeed()*GpsManager.KPH));
tvGPSAccuracy.setText(Float.toString(location.getAccuracy()));
tvGPSProvider.setText(location.getProvider());
String gpsDateTime = CustomDateUtils.formatDateTimestamp(location.getTime());
tvGPSDateTime.setText(gpsDateTime);
// location.getExtras() is provider specific
Bundle locBundle = location.getExtras();
int satellitesWithFix = 0;
if(locBundle != null && locBundle.containsKey("satellites")){
satellitesWithFix = location.getExtras().getInt("satellites");
}
int satellitesTotal = gpsManager.getTotalSatellites();
String s = Integer.toString(satellitesWithFix) + "/" + satellitesTotal;
tvGPSTotalSatellites.setText(s);
}
}
public void onPause() {
super.onPause(); // Always call the superclass method first
Log.d(TAG, "paused");
}
public void onResume() {
super.onResume(); // Always call the superclass method first
Log.d(TAG, "resume");
updateButtonTrackerStatus();
// Update the counter and location details from last currentLocation when
// the app resumes from background
if(gpsApp.isON()) {
showGPSStatus(true);
displayGPSDetails(gpsManager.getCurrentLocation(), gpsManager.getCounter());
displayTimeInterval(true);
gpsManager.displayCurrentTimeInterval();
}
else {
displayTimeInterval(false);
}
}
public void onDestroy() {
try {
if(mWifiStatusReceiver != null) {
this.unregisterReceiver(mWifiStatusReceiver);
}
}
catch(IllegalStateException ex) {
Log.d(TAG, ex.toString());
}
super.onDestroy();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_activity_actions, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_share:
buttonSharePressed();
return true;
case R.id.action_configure:
buttonSettingsPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void displayLocationAccessDialog(){
AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
dialog.setMessage(R.string.gps_network_not_enabled);
dialog.setPositiveButton(R.string.enable, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
});
dialog.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
}
});
dialog.show();
}
private boolean isBetween(int x, int lower, int upper) {
return lower <= x && x <= upper;
}
@Override
public void onBackPressed() {
//Ensures that we don't go back to previous activity
}
private void buttonSettingsPressed(){
Log.d(TAG, "buttonSettingsPressed");
Intent intent = new Intent(this, SettingsActivity.class);
startActivityForResult(intent, IntentCodes.SETTINGS);
}
private void buttonSharePressed(){
Log.d(TAG, "buttonSharePressed");
Intent intent = new Intent(this, ShareActivity.class);
startActivity(intent);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == IntentCodes.SETTINGS && resultCode == Activity.RESULT_OK){
updateFromSettingsPreferences();
}
}
}