Android Open Source - airprobe Map






From Project

Back to project page airprobe.

License

The source code is released under:

GNU General Public License

If you think the Android project airprobe listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 * AirProbe/*w w  w . j ava 2  s  .com*/
 * Air quality application for Android, developed as part of 
 * EveryAware project (<http://www.everyaware.eu>).
 *
 * Copyright (C) 2014 CSP Innovazione nelle ICT. All rights reserved.
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * For any inquiry please write to <devel@csp.it>
 * 
 * CONTRIBUTORS
 * 
 * This program was made with the contribution of:
 *   Fabio Saracino <fabio.saracino@csp.it>
 *   Patrick Facco <patrick.facco@csp.it>
 * 
 * 
 * SOURCE CODE
 * 
 *  The source code of this program is available at
 *  <https://github.com/CSPICT/airprobe>
 */

package org.csp.everyaware.offline;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Formatter;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.HttpHostConnectException;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.csp.everyaware.ColorHelper;
import org.csp.everyaware.Constants;
import org.csp.everyaware.ExtendedLatLng;
import org.csp.everyaware.KmlParser;
import org.csp.everyaware.R;
import org.csp.everyaware.Start;
import org.csp.everyaware.Utils;
import org.csp.everyaware.bluetooth.BluetoothBroadcastReceiver;
import org.csp.everyaware.bluetooth.BluetoothManager;
import org.csp.everyaware.db.AnnotatedRecord;
import org.csp.everyaware.db.DbManager;
import org.csp.everyaware.db.MapCluster;
import org.csp.everyaware.db.MarkerRecord;
import org.csp.everyaware.db.Record;
import org.csp.everyaware.db.Track;
import org.csp.everyaware.internet.FacebookManager;
import org.csp.everyaware.internet.StoreAndForwardService;
import org.csp.everyaware.internet.TwitterManager;
import org.csp.everyaware.tabactivities.Graph;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.LocationSource;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.LocationSource.OnLocationChangedListener;
import com.google.android.gms.maps.model.BitmapDescriptor;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polygon;
import com.google.android.gms.maps.model.PolygonOptions;
import com.google.android.gms.maps.model.PolylineOptions;
import com.google.android.gms.maps.model.VisibleRegion;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.app.AlertDialog.Builder;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnShowListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.provider.Settings;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.CompoundButton.OnCheckedChangeListener;

public class Map extends Activity
{
  private MapView mMapView;
  private GoogleMap mGoogleMap;
  private MyLocationSource mLocationSource;
  
  private Handler mHandler;
  private DbManager mDbManager;
  
  private List<Record>mRecords = new ArrayList<Record>();

  //opened track
  private Track mTrack;
  
  //track length button
  private Button mTrackLengthBtn;
  
  //zoom control custom buttons
  private Button mZoomInBtn, mZoomOutBtn;
  private float mZoom = 15f;
  
  //insert ann button
  private Button mInsertAnnBtn;

  //share button (log on facebook/twitter)
  private Button mShareBtn;
  
  //zoom controls (they can show/hide on map)
  private LinearLayout mZoomControls;
  private long mOnMapClickTs;
  
  //status icons
  private ImageView mGpsStatus;
  private ImageView mInterUplStatus;
  
  //camera tracking button and boolean flag
  private Button mFollowCamBtn;
  private boolean mCameraTrackOn = true;

  //get bc levels around user from server
  private Button mGetBcLevelsBtn;
  //black carbon legend
  private LinearLayout mSpectrum;
  
  //array of points of path showed on map
  private List<ExtendedLatLng>mLatLngPoints;
  
  private ProgressDialog mCancelDialog;
  private ProgressDialog mProgressDialog;
  private ProgressDialog mProgressDialog2;
  
  private boolean mInitializedView = false;
  private boolean mConnectivityOn;

  //private GetDataThread mGetDataThread;
  
  private double avg_poll_min = 0;
  private int poll_mult = 35;
  private int poll_base = 25;
  
  //share section
  private boolean mValidFbSession;
  private boolean mValidTwSession;  
  private FacebookManager mFacebookManager;
  private TwitterManager mTwitterManager;
  private Button[] mButtons  = new Button[2]; //login buttons (facebook and twitter)
  
  private Toast mExitToast; //toast showed when user press back button
  
  private PowerManager mPowerMan; 
  private PowerManager.WakeLock mWakeLock;
  
  private final int BC_MULTIPLIER = 10;
  
  private KmlParser mKmlParser; //parse server response and returns a list of MapCluster(s)
  private List<MapCluster>mMapClusters; //black carbons level contained in the screen
  private List<Polygon>mMapPolygons;
  
  private Button mToBeHideBtn;
  
  @Override
  public void onCreate(Bundle savedInstanceState) 
  {
    super.onCreate(savedInstanceState);
    Log.d("Map", "******************************onCreate()******************************");
    requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.map_container);    
    
        mToBeHideBtn = (Button)findViewById(R.id.startStopBtn);
        mToBeHideBtn.setVisibility(View.GONE);
        
        mPowerMan = (PowerManager) getSystemService(Context.POWER_SERVICE);
        mWakeLock = mPowerMan.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "CPUalwaysOn");
    
    Utils.setStep(Constants.TRACK_MAP, getApplicationContext());
    
    mDbManager = DbManager.getInstance(getApplicationContext());
    mDbManager.openDb();
  
    //it will contain  displayed latlng points
    mLatLngPoints = new ArrayList<ExtendedLatLng>();

    //istantiate custom implementation of LocationSource interface
    mLocationSource = new MyLocationSource();
    
        //google map initialization
        setUpMapIfNeeded(savedInstanceState);
    
    //obtaining references to buttons and defining listeners
    getButtonRefs();
    
    mHandler = new Handler();
    
    mKmlParser = new KmlParser();
    
    //starting store'n'forward service and saving reference to it
    Intent serviceIntent = new Intent(getApplicationContext(), StoreAndForwardService.class);
    Utils.storeForwServIntent = serviceIntent;
    startService(serviceIntent);
    
    //set appropriate colors in all seven black carbon levels under black carbon text box
    setBcLevelColors();
  }
  
  @Override
  protected void onStart() 
  {
      super.onStart();

      // This verification should be done during onStart() because the system calls
      // this method when the user returns to the activity, which ensures the desired
      // location provider is enabled each time the activity resumes from the stopped state.
      LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
      final boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

      if (!gpsEnabled) 
      {
          // Build an alert dialog here that requests that the user enable
          // the location services, then when the user clicks the "OK" button,
          // call enableLocationSettings()
      }
  }

  private void enableLocationSettings() 
  {
      Intent settingsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
      startActivity(settingsIntent);
  }
  
  @Override
  protected void onStop() 
  {
    super.onStop();  
    Log.d("Map", "******************************onStop()******************************");
  }      
    
    @Override
    public void onDestroy()
    {
      Utils.paused = false;
      
      mMapView.onDestroy();
      super.onDestroy(); 
      Log.d("Map", "******************************onDestroy()***************************");
      
      //release partial wake lock
      if(mWakeLock != null)
        mWakeLock.release();
    }      
    
    @Override
    public void onPause()
    {
      Utils.paused = true;
      
      mLocationSource.removeLocUpdates();
      mMapView.onPause();
      
      Log.d("Map", "******************************onPause()*****************************");
      
      if(mServiceReceiver != null)
        //unregister receiver for messages from store'n'forward service
        unregisterReceiver(mServiceReceiver);
      
      if(mGpsServiceReceiver != null)
        //unregister receiver for messages from gps tracking service
        unregisterReceiver(mGpsServiceReceiver);
 
    //remove polygon heat map from map and clear array of polygons
    if(mMapPolygons != null)
    {
      for(int i = 0; i < mMapPolygons.size(); i++)
        mMapPolygons.get(i).remove();
      mMapPolygons.clear();
    }
    
      super.onPause();
    }
    
  @Override
  public void onResume()
  {
    Utils.paused = false;
    super.onResume();
      mMapView.onResume();
      
    //acquire partial wake lock
    if(!mWakeLock.isHeld())
      mWakeLock.acquire();  
    
      mLocationSource.registerLocUpdates();   
      
    if(Utils.uploadOn == Constants.INTERNET_ON_INT)
      mInterUplStatus.setBackgroundResource(R.drawable.internet_on);
    else if(Utils.uploadOn == Constants.INTERNET_OFF_INT)
      mInterUplStatus.setBackgroundResource(R.drawable.internet_off);
    else if(Utils.uploadOn == Constants.UPLOAD_ON_INT)
      mInterUplStatus.setBackgroundResource(R.drawable.upload);
    
      if(mCameraTrackOn)
        mFollowCamBtn.setBackgroundResource(R.drawable.follow_camera_pressed);
      else
        mFollowCamBtn.setBackgroundResource(R.drawable.follow_camera_not_pressed);
      
    //register receiver for messages from store'n'forward service
    IntentFilter internetOnFilter = new IntentFilter(Constants.INTERNET_ON);
    registerReceiver(mServiceReceiver, internetOnFilter);
    IntentFilter internetOffFilter = new IntentFilter(Constants.INTERNET_OFF);
    registerReceiver(mServiceReceiver, internetOffFilter);
    IntentFilter uploadOnFilter = new IntentFilter(Constants.UPLOAD_ON);
    registerReceiver(mServiceReceiver, uploadOnFilter);
    IntentFilter uploadOffFilter = new IntentFilter(Constants.UPLOAD_OFF);
    registerReceiver(mServiceReceiver, uploadOffFilter);
    
    //register receiver for messages from gps tracking service
    IntentFilter phoneGpsOnFilter = new IntentFilter(Constants.PHONE_GPS_ON);
    registerReceiver(mGpsServiceReceiver, phoneGpsOnFilter);
    IntentFilter networkGpsOnFilter = new IntentFilter(Constants.NETWORK_GPS_ON);
    registerReceiver(mGpsServiceReceiver, networkGpsOnFilter);
    IntentFilter phoneGpsOffFilter = new IntentFilter(Constants.PHONE_GPS_OFF);
    registerReceiver(mGpsServiceReceiver, phoneGpsOffFilter);
    
    //get selected track and draw it on map
    mTrack = Utils.track;
    
    if(mTrack != null)
    {
      Log.d("Map", "onCreate()--> shown session id: " +mTrack.mSessionId);
      
      if(mGoogleMap != null)
        mGoogleMap.clear();  
      
      int divider = 1;
      
      long trackLength = mTrack.mNumOfRecords;
      
      Log.d("Map", "onResume()--> track length: "+trackLength);
      
      if(trackLength > 1800)
        divider = 2;
      if(trackLength > 3600)
        divider = 4;
      if(trackLength > 7200)
        divider = 8;
      if(trackLength > 14400)
        divider = 16;
      
      mLatLngPoints = mDbManager.loadLatLngPointsBySessionId(mTrack.mSessionId, divider);
      if(mLatLngPoints != null)
      {
        int size = mLatLngPoints.size();
        
        if(size > 0)
        {
               calcMinAvgPollValue();
          drawPath();      
          mCameraTrackOn = false;
          if(mGoogleMap != null)
          try
          {
            mGoogleMap.animateCamera(CameraUpdateFactory.newLatLng(mLatLngPoints.get(size-1).mLatLng));
          }
          catch(NullPointerException e)
          {
            e.printStackTrace();
          }
        }
      }
    }
    
    if(mMapPolygons == null)
      mMapPolygons = new ArrayList<Polygon>();
  
    int color;
    
    //draw map cluster on the map
    if((mMapClusters != null)&&(mMapClusters.size() > 0))
    {
      for(int i = 0; i < mMapClusters.size(); i++)
      {
        MapCluster mapCluster = mMapClusters.get(i);
        
        if(mapCluster.mBcLevel != 0)
        {
          if((mapCluster.mBcLevel > 0)&&(mapCluster.mBcLevel <= 10))
            color = ColorHelper.numberToColor(mapCluster.mBcLevel * BC_MULTIPLIER);
          else
            color = ColorHelper.numberToColor(100);
          
          mMapPolygons.add(mGoogleMap.addPolygon(new PolygonOptions()
                  .add(new LatLng(mapCluster.mMinLat, mapCluster.mMinLon), new LatLng(mapCluster.mMinLat, mapCluster.mMaxLon),
                      new LatLng(mapCluster.mMaxLat, mapCluster.mMaxLon), new LatLng(mapCluster.mMaxLat, mapCluster.mMinLon))
                  .strokeColor(Color.TRANSPARENT)
                  .fillColor(Color.parseColor("#66" + String.format("%06X", 0xFFFFFF & color)))));
        }
      }
    }  
  }  
  
  @Override
  public void onBackPressed()
  {
    closeAppDialog();
    /*
    if(mExitToast != null)
    {    
      if(mExitToast.getView().isShown())
      {
        mExitToast.cancel();
        mExitToast = null;
        closeAppDialog();
      }
      else
      {
        //mExitToast = Toast.makeText(getApplicationContext(), R.string.press_again_to_exit_msg, Toast.LENGTH_SHORT);
        mExitToast.show();  
      }
    }
    else
    {
      mExitToast = Toast.makeText(getApplicationContext(), R.string.press_again_to_exit_msg, Toast.LENGTH_SHORT);
      mExitToast.show();    
    }*/
  }
  
    /***************************** INIT GOOGLE MAP **********************************************/
  
    private void setUpMap() 
    {
      mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
      mGoogleMap.getUiSettings().setCompassEnabled(false);
      mGoogleMap.getUiSettings().setZoomControlsEnabled(false);
        
      //assign istance of MyLocationSource to google maps and activate it
      //mGoogleMap.setLocationSource(mLocationSource); 
      //mGoogleMap.setMyLocationEnabled(true);
      
      //mGoogleMap.setInfoWindowAdapter(new CustomInfoWindowAdapter());
      
      //animate camera to an initial zoom level 
      try
      {
        mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(mZoom), 1500, null);
      }
      catch(NullPointerException e)
      {
        e.printStackTrace();
      }
      
      mGoogleMap.setOnMapClickListener(new OnMapClickListener()
      {
      @Override
      public void onMapClick(LatLng arg0) 
      {
        if(mZoomControls != null)
        {
          mOnMapClickTs = new Date().getTime();
          
          mZoomControls.setVisibility(View.VISIBLE);
          
          mHandler.postDelayed(new Runnable()
          {
            @Override
            public void run() 
            {
              if((new Date().getTime() - mOnMapClickTs) >= 2500)
                mZoomControls.setVisibility(View.GONE);
            }
            
          }, 3000);
        }
      }     
      });
      
      mGoogleMap.setOnMapLongClickListener(new OnMapLongClickListener()
      {
      @Override
      public void onMapLongClick(LatLng latLng) 
      {
        double minDistance = 0;
        int index = -1;
        
        Log.d("Map", "onMapLongClick()--> lat lng: " +latLng.latitude+", "+latLng.longitude);
        
        //calculate bounding box around tapped point (tapped point is the center of BB)
        LatLng topLeft = new LatLng(latLng.latitude + 0.01, latLng.longitude - 0.01);         
        LatLng bottomRight = new LatLng(latLng.latitude - 0.01, latLng.longitude + 0.01);
        
        //calculate intersection between BB and path and the point of path inside the intersection that
        //is nearer to tapped point
        //output of the cycle is the index of path point nearest to tapped point
        for(int i = 0; i < mLatLngPoints.size(); i++)
        {
          ExtendedLatLng extLatLng = mLatLngPoints.get(i);
          
          //if actual path point is inside BB, calculate distance between tapped point and path point and save it 
          if((extLatLng.mLatLng.latitude <= topLeft.latitude)&&(extLatLng.mLatLng.latitude >= bottomRight.latitude))
          {
            if((extLatLng.mLatLng.longitude >= topLeft.longitude)&&(extLatLng.mLatLng.longitude <= bottomRight.longitude))
            {
              double latDiff = Math.abs(extLatLng.mLatLng.latitude - latLng.latitude);              
              double lonDiff = Math.abs(extLatLng.mLatLng.longitude - latLng.longitude);
              double distance = Math.sqrt(latDiff*latDiff+lonDiff*lonDiff);
              
              if(i == 0)
              {
                minDistance = distance;
                index = 0;
              }
              else if(distance < minDistance)
              {
                minDistance = distance;
                index = i;
              }
            }
          }
        }
        
            //if an index is present, it is the index of the path point inside BB nearest to tapped point
            if(index > -1)
            {
              ExtendedLatLng nearestPathLatLng = mLatLngPoints.get(index);
                insertAnnDialog(nearestPathLatLng);
            }
            else
              Toast.makeText(getApplicationContext(), "Path not found", Toast.LENGTH_LONG).show();
      }     
      });
    }

    private void setUpMapIfNeeded(Bundle savedInstanceState) 
    {
        // Do a null check to confirm that we have not already instantiated the map.
        if(mMapView == null)  
        {
          mMapView = (MapView) findViewById(R.id.mapView);
          //MapView object has the same life cycle of activity
          mMapView.onCreate(savedInstanceState);
          
          //get reference to GoogleMap object from MapView
          mGoogleMap = mMapView.getMap();

            if(isGoogleMapsInstalled())
            {
                if (mGoogleMap != null) 
                {
                //CameraUpdateFactory e BitmapDescriptorFactory need initialization now
                try 
                {
                     MapsInitializer.initialize(this);
                } 
                catch (GooglePlayServicesNotAvailableException e) 
                {
                     e.printStackTrace();
                }

                    setUpMap();
                }
            }
            else
            {
                Builder builder = new AlertDialog.Builder(this);
                builder.setMessage(getString(R.string.install_google_maps_string));
                builder.setCancelable(false);
                builder.setPositiveButton(R.string.alert_dialog_ok, getGoogleMapsListener());
                AlertDialog dialog = builder.create();
                dialog.show();
            }
        }
    }  
  
    public boolean isGoogleMapsInstalled()
    {
        try
        {
            ApplicationInfo info = getPackageManager().getApplicationInfo("com.google.android.apps.maps", 0 );
            return true;
        } 
        catch(PackageManager.NameNotFoundException e)
        {
            return false;
        }
    }
    
    public DialogInterface.OnClickListener getGoogleMapsListener()
    {
        return new DialogInterface.OnClickListener() 
        {
            @Override
            public void onClick(DialogInterface dialog, int which) 
            {
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.apps.maps"));
                startActivity(intent);

                //Finish the activity so they can't circumvent the check
                finish();
            }
        };
    }
    
  public final void createLegalNoticesDialog(Activity activity)
  {
    AlertDialog ad = new AlertDialog.Builder(activity).create();  
    ad.setCancelable(false); // This blocks the 'BACK' button  
    ad.setMessage(GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(activity.getApplicationContext()));  
    ad.setButton("OK", new DialogInterface.OnClickListener() 
    {  
        @Override  
        public void onClick(DialogInterface dialog, int which) 
        {  
            dialog.dismiss();                      
        }  
    });  
    ad.show(); 
  }
  
    /********************************* PERSONALIZED LOCATION SOURCE ******************************************************/
    
    //to draw user current position on map
    private class MyLocationSource implements LocationListener
    {
      //private OnLocationChangedListener locChangeListener; //interface of LocationSource
      private LocationManager locManager;
      
      public MyLocationSource()
      {
        locManager = (LocationManager)getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
      }
      
      public void registerLocUpdates()
      {
      //register for location updates by gps and network providers
        locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
        
        try
        {
          locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
        }
        catch(IllegalArgumentException e)
        {
          e.printStackTrace();
        }
      }
      
      public void removeLocUpdates()
      {
        //remove location updates (all)
      locManager.removeUpdates(this);
      }
      
    @Override
    public void onProviderDisabled(String provider) 
    {
      
    }

    @Override
    public void onProviderEnabled(String provider) 
    {
      
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) 
    {
      
    }
    
    //method of LocationSource invoked on location update
    @Override
    public void onLocationChanged(Location location) 
    {
      try
      {
        //center camera on last location update
        if(mCameraTrackOn)
          mGoogleMap.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(location.getLatitude(), location.getLongitude())));
      }
      catch(NullPointerException e)
      {
        e.printStackTrace();
      }
    }
    }
  
  /****************** OTTIENE RIFERIMENTO AI BOTTONI *********************************/
  
  public void getButtonRefs()
  {    
    mZoomControls = (LinearLayout)findViewById(R.id.zoomLinearLayout);
    mZoomControls.setVisibility(View.GONE);
    
    mTrackLengthBtn = (Button)findViewById(R.id.trackLengthBtn);
    mFollowCamBtn = (Button)findViewById(R.id.followCameraBtn);
    mZoomOutBtn = (Button)findViewById(R.id.zoomOutBtn);
    mZoomInBtn = (Button)findViewById(R.id.zoomInBtn);
    mInsertAnnBtn = (Button)findViewById(R.id.insertAnnBtn);
    mShareBtn = (Button)findViewById(R.id.shareBtn);

    mTrackLengthBtn.setVisibility(View.GONE);
    mInsertAnnBtn.setVisibility(View.GONE);
    
    mZoomOutBtn.setOnClickListener(new OnClickListener()
    {
      @Override
      public void onClick(View arg0) 
      {
        // Zoom out
        try
        {
          mGoogleMap.moveCamera(CameraUpdateFactory.zoomBy(-1f)); 
        }
        catch(NullPointerException e)
        {
          e.printStackTrace();
        }
        //read and save actual zoom level
        mZoom = mGoogleMap.getCameraPosition().zoom;
      }      
    });
    
    mZoomInBtn.setOnClickListener(new OnClickListener()
    {
      @Override
      public void onClick(View arg0) 
      {
        // Zoom in
        try
        {
          mGoogleMap.moveCamera(CameraUpdateFactory.zoomBy(1f)); 
        }
        catch(NullPointerException e)
        {
          e.printStackTrace();
        }
        //read and save actual zoom level
        mZoom = mGoogleMap.getCameraPosition().zoom;
      }      
    });
    
    mShareBtn.setOnClickListener(new OnClickListener()
    {
      @Override
      public void onClick(View arg0) 
      {
        mFacebookManager = FacebookManager.getInstance(Map.this, mFacebookHandler);
        mTwitterManager = TwitterManager.getInstance(Map.this);
        
        final Dialog dialog = new Dialog(Map.this);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(R.layout.share_dialog);
        //dialog.setTitle("Activate login on...");

        getShareButtonsRef(dialog);
        
        dialog.show();
      }      
    });
    
    mFollowCamBtn.setOnClickListener(new OnClickListener()
    {
      @Override
      public void onClick(View arg0) 
      {
        //mCameraTrackOn = !mCameraTrackOn;
        setCameraTracking();
        
        if(mCameraTrackOn)
        {
          try
          {
            if(Utils.lastPhoneLocation != null)
              mGoogleMap.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(Utils.lastPhoneLocation.getLatitude(), Utils.lastPhoneLocation.getLongitude())));
            else if(Utils.lastNetworkLocation != null)
              mGoogleMap.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(Utils.lastNetworkLocation.getLatitude(), Utils.lastNetworkLocation.getLongitude())));
          }
          catch(NullPointerException e)
          {
            e.printStackTrace();
          }
        }
      }      
    });
    
    mShareBtn.setOnLongClickListener(new OnLongClickListener()
    {
      @Override
      public boolean onLongClick(View arg0) 
      {        
        Toast toast = Toast.makeText(getApplicationContext(), getResources().getString(R.string.share_btn_text), Toast.LENGTH_LONG);
        toast.setGravity(Gravity.TOP|Gravity.RIGHT, 0, 250); //250 from top on a 480x800 screen
        toast.show();
        return false;
      }      
    });
    
    //status icons references
    mGpsStatus = (ImageView)findViewById(R.id.gpsStatusIv);
    mInterUplStatus = (ImageView)findViewById(R.id.interUplStatusIv);

    //gps status icon initialization
    mGpsStatus.setBackgroundResource(R.drawable.gps_off);
    
    //read network type index on which upload data is allowed: 0 - only wifi; 1 - both wifi and mobile
    int networkTypeIndex = Utils.getUploadNetworkTypeIndex(getApplicationContext());
    
    //1 - is internet connection available? 
    boolean[] connectivity = Utils.haveNetworkConnection(getApplicationContext());
    
    //if user wants to upload only on wifi networks, connectivity[0] (network connectivity) must be true
    if(networkTypeIndex == 0)
    {
      if(connectivity[0])
        mConnectivityOn = true;
      else
        mConnectivityOn = false;
    }
    else //if user wants to upload both on wifi/mobile networks
      mConnectivityOn = connectivity[0] || connectivity[1];       
    
    //network status icon initialization
    if(mConnectivityOn)
    {
      mInterUplStatus.setBackgroundResource(R.drawable.internet_on);
      Utils.uploadOn = Constants.INTERNET_ON_INT;  
    }
    else
    {
      mInterUplStatus.setBackgroundResource(R.drawable.internet_off);           
      Utils.uploadOn = Constants.INTERNET_OFF_INT;
    }
    
    //button to get from server black carbon levels around user
    mGetBcLevelsBtn = (Button)findViewById(R.id.getBcLevelsBtn);
    mGetBcLevelsBtn.setVisibility(View.VISIBLE);
    mGetBcLevelsBtn.setOnClickListener(mGetBcLevelsOnClickListener);
    
    //bcLayout.addView(mGetBcLevelsBtn);
    mSpectrum = (LinearLayout)findViewById(R.id.spectrumLinearLayout);
    mSpectrum.setVisibility(View.VISIBLE);
  }
  
  private void setBcLevelColors()
  {
    TextView[] levelsTv = new TextView[7];
    levelsTv[0] = (TextView)findViewById(R.id.level1Tv);
    levelsTv[1] = (TextView)findViewById(R.id.level2Tv);
    levelsTv[2] = (TextView)findViewById(R.id.level3Tv);
    levelsTv[3] = (TextView)findViewById(R.id.level4Tv);
    levelsTv[4] = (TextView)findViewById(R.id.level5Tv);
    levelsTv[5] = (TextView)findViewById(R.id.level6Tv);
    levelsTv[6] = (TextView)findViewById(R.id.level7Tv);
    
    levelsTv[0].setBackgroundColor(ColorHelper.numberToColor(5));
    levelsTv[1].setBackgroundColor(ColorHelper.numberToColor(20));
    levelsTv[2].setBackgroundColor(ColorHelper.numberToColor(40));
    levelsTv[3].setBackgroundColor(ColorHelper.numberToColor(70));
    levelsTv[4].setBackgroundColor(ColorHelper.numberToColor(80));
    levelsTv[5].setBackgroundColor(ColorHelper.numberToColor(90));
    levelsTv[6].setBackgroundColor(ColorHelper.numberToColor(100));
  }
  
  /****************** DISEGNA PATH ****************************************************/
  
  //draw path from a list of points
  public void drawPath()
  {
    ExtendedLatLng newLatLng = null; 
    ExtendedLatLng precLatLng = null;
    int color = Color.DKGRAY;
    
    try
    {
      Log.d("Map", "polyline count: " +mLatLngPoints.size());
      
      for (int i = 0; i < mLatLngPoints.size(); i++) 
          {
        newLatLng = mLatLngPoints.get(i);
        color = Color.DKGRAY; //color for a segment without bc value
              
        //10 is upper limit in scale, so a black carbon of 10 (multiplied by 10) must be drawn in dark red
            if((newLatLng.mBc > 0)&&(newLatLng.mBc <= 10))
              color = ColorHelper.numberToColor(newLatLng.mBc * BC_MULTIPLIER);
            else
              color = ColorHelper.numberToColor(100);
            
            //draw segment with appropriate color (dark grey if no bc value is present) 
            if(precLatLng != null)
              mGoogleMap.addPolyline(new PolylineOptions().add(newLatLng.mLatLng).add(precLatLng.mLatLng).width(5).color(color));
            
              String annotation = newLatLng.mUserAnn;
              
              if(!annotation.equals(""))
              {
                BitmapDescriptor icon = BitmapDescriptorFactory.fromResource(R.drawable.annotation_marker);
                mGoogleMap.addMarker(new MarkerOptions()
                .position(newLatLng.mLatLng)
                .title("AQI: "+newLatLng.mBc)
                .snippet("Annotation: " +annotation)
                .icon(icon)
                .anchor(0.25f, 1f)); //Map Markers are 'anchored' by default to the middle of the bottom of layout (i.e., anchor(0.5,1)).
              }

              precLatLng = newLatLng;
          }      
      
      //center camera on last trackn position
      //if((mTrackMode)&&(mCameraTrackOn))
      try
      {
        mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(mLatLngPoints.get(mLatLngPoints.size()-1).mLatLng, mZoom));
      }
      catch(NullPointerException e)
      {
        e.printStackTrace();
      }
    }
    catch(Exception e)
    {
      
    }
  }
    
    /************************ ALERT DIALOG NO INTERNET AVAILABLE *************************************/
    
    public void noConnectivityDialog() 
    {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage(R.string.alert_dialog_no_internet)
          .setIcon(android.R.drawable.ic_dialog_info)
          .setTitle(R.string.app_name)
          .setCancelable( false )
          .setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() 
          {
            public void onClick(DialogInterface dialog, int id) 
            {
  
            }
          });
        
        AlertDialog alert = builder.create();
        alert.show(); 
    }
    
    /****************** GESTIONE CAMERA TRACKING SU ULTIMO PUNTO INSERITO ***********************/
    
    public void setCameraTracking()
    {
      mCameraTrackOn = !mCameraTrackOn;
      
      if(mCameraTrackOn)
        mFollowCamBtn.setBackgroundResource(R.drawable.follow_camera_pressed);
      else
        mFollowCamBtn.setBackgroundResource(R.drawable.follow_camera_not_pressed);
    }
  
    /****************** CALCULATE MINS VALUE FOR POLLUTANTS IN LOADED HISTORY *******************/
    
    public void calcMinAvgPollValue()
    {
      double actual_avg_poll = 0;
      
      //save first avg min
      avg_poll_min = mLatLngPoints.get(0).mAvgValue;
      
      for(int i = 1; i < mLatLngPoints.size(); i++)
      {
        actual_avg_poll = mLatLngPoints.get(i).mAvgValue;
        
        //if actual avg is less then avg min, save it
        if(actual_avg_poll < avg_poll_min)
          avg_poll_min = actual_avg_poll;  
      }
      //reduction
      avg_poll_min = avg_poll_min /2;
      
      //Log.d("Map", "calcMinAvgPollValue()--> " +avg_poll_min);
    }
  
  /***************** CALCOLA MEDIE VALORI RECORDS COMPRESI IN INTERVALLO **********************/
  
  public MarkerRecord calcAvgRecords(int begin, int end) throws IndexOutOfBoundsException
  {
    int totalRecords = 0;
    long startTs = 0, endTs = 0;
    
    double avg_poll = 0;
    
    totalRecords = end-begin;
    
    Log.d("calcAvgRecords()", "begin: "+begin+" end:" +end+ " totalRecords: " +totalRecords);
    
    for(int i = begin; i < end; i++)
    {
      if(i == begin)
        startTs = mRecords.get(i).mSysTimestamp;
      if(i == end-1)
        endTs = mRecords.get(i).mSysTimestamp;
      
      avg_poll += mRecords.get(i).calcAvgPoll();
      
    }    
    avg_poll = avg_poll / totalRecords;
    
    return new MarkerRecord(avg_poll, totalRecords, startTs, endTs);
  }
  
  public MarkerRecord calcAvgRecords(List<ExtendedLatLng>points) throws IndexOutOfBoundsException
  {
    int totalRecords = 0;
    long startTs = 0, endTs = 0;
    
    double avg_poll = 0;
    
    totalRecords = points.size();
    
    Log.d("calcAvgRecords()", " totalRecords: " +totalRecords);
    
    for(int i = 0; i < points.size(); i++)
    {
      if(i == 0)
        startTs = points.get(i).mSysTimestamp;
      if(i == totalRecords-1)
        endTs = points.get(i).mSysTimestamp;
      
      avg_poll += points.get(i).calcAvgPoll();
      
    }    
    avg_poll = avg_poll / totalRecords;
    
    return new MarkerRecord(avg_poll, totalRecords, startTs, endTs);
  }
  
    
    /******************************* DIALOGS ****************************************************/
    
    public void createProgressDialog(String msg, boolean cancelable)
    {
      mProgressDialog = ProgressDialog.show(Map.this, getResources().getString(R.string.app_name), msg, true, true);
    }
    
    public void createProgressDialog2(String msg, boolean cancelable)
    {
      mProgressDialog2 = new ProgressDialog(Map.this);
      mProgressDialog2.setTitle(getResources().getString(R.string.app_name));
      mProgressDialog2.setMessage(msg);
      mProgressDialog2.setIndeterminate(true);
      mProgressDialog2.setCancelable(true);
      //mProgressDialog2 = ProgressDialog.show(Map.this, getResources().getString(R.string.app_name), msg, true, true);
      mProgressDialog2.setOnShowListener(new OnShowListener()
      {
      @Override
      public void onShow(DialogInterface arg0) 
      {
        Log.d("OnShowListener", "onShow()");
        
        mHandler.postDelayed(new Runnable()
        {
          @Override
          public void run() 
          {
            //clear precedent heat map
            if(mMapPolygons != null)
            {
              for(int i = 0; i < mMapPolygons.size(); i++)
                mMapPolygons.get(i).remove();
              
              mMapPolygons.clear();
            }
            
            if(mMapClusters != null)
              mMapClusters.clear();
            
            //update information about map zoom level
            mZoom = mGoogleMap.getCameraPosition().zoom;

              //get viewport min/max coordinates
              VisibleRegion vr = mGoogleMap.getProjection().getVisibleRegion();
              double minLong = vr.latLngBounds.southwest.longitude;
              double maxLat = vr.latLngBounds.northeast.latitude;
              double maxLong = vr.latLngBounds.northeast.longitude;
              double minLat = vr.latLngBounds.southwest.latitude;
              
              String requestUrl = Constants.GET_BC_LEVELS_ADDR+(Math.round(mZoom)+1)+"&bbox="+minLong+","+minLat+","+maxLong+","+maxLat; //complete url string    
              Log.d("Map", "getData()--> request Url: " +requestUrl);
              
            new GetDataTask().execute(requestUrl);
            /*
            mGetDataThread = new GetDataThread();
            mGetDataThread.run();*/
          }          
        }, 500);

      }     
      });
      mProgressDialog2.show();
    }
    
    public void closeAppDialog() 
    {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage(R.string.alert_dialog_close_app)
          .setIcon(android.R.drawable.ic_dialog_info)
          .setTitle(R.string.app_name)
          .setCancelable( false )
          .setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() 
          {
            public void onClick(DialogInterface dialog, int id) 
            {
              closeApp();
            }
          })
        .setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() 
        {
          public void onClick(DialogInterface dialog, int id) 
          {
            dialog.dismiss();
          }
        });
        
        AlertDialog alert = builder.create();
        alert.show(); 
    }
   
    
    public HashMap<String,?> createItem(String title, String caption) 
    {  
        HashMap<String,String> item = new HashMap<String,String>();  
        item.put(Constants.ITEM_TITLE, title);  
        item.put(Constants.ITEM_CAPTION, caption);  
        return item;  
    }  
  
    /*************************** OPTION MENU ***************************************************/
    
  public boolean onCreateOptionsMenu(Menu menu)
  {    
    String[] menuItems = getResources().getStringArray(R.array.map_optionmenu);
    
    SubMenu mapSubMenu = menu.addSubMenu("Map Modes").setIcon(android.R.drawable.ic_menu_mapmode);
    
    mapSubMenu.add(1, Menu.FIRST, Menu.FIRST, "Hybrid").setCheckable(false);    
    mapSubMenu.add(1, Menu.FIRST+1, Menu.FIRST, "Normal").setCheckable(false);
    mapSubMenu.add(1, Menu.FIRST+2, Menu.FIRST+2, "Satellite").setCheckable(false);
    mapSubMenu.add(1, Menu.FIRST+3, Menu.FIRST+3, "Terrain").setCheckable(false);
    
    return super.onCreateOptionsMenu(menu);    
  }
  
    @Override  
    public boolean onOptionsItemSelected(MenuItem item) 
    {  
       int itemId = item.getItemId();
       
       switch(itemId)
       {
      case Menu.FIRST:
        mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        break;
      case Menu.FIRST + 1:
        mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
        break;
      case Menu.FIRST + 2:
        mGoogleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
        break;
      case Menu.FIRST + 3:
        mGoogleMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
        break;          
       }
       return true;
    }
    
    /********************** CLOSE APP *************************************************************************/
    
    public void closeApp()
    {          
      Utils.backToHome = true;
      
      //stop store'n'forward service
      if(Utils.storeForwServIntent != null)
        stopService(Utils.storeForwServIntent);
      
      //clear shared prefs
      Utils.deleteSharedPrefs(getApplicationContext());
      
      Utils.track = null;
      Utils.selectedTrackIndex = -1;
      
      Intent intent = new Intent(Map.this, Start.class);
      startActivity(intent);
      finish(); 
    }
    
    /******************* RECEIVE MESSAGES FROM GPS TRACKING SERVICE ***********************************/
    
    private BroadcastReceiver mGpsServiceReceiver = new BroadcastReceiver()
    {
        @Override
        public void onReceive(Context context, Intent intent) 
        {
          String action = intent.getAction();

            if (action.equals(Constants.PHONE_GPS_ON)) 
            {
              Log.d("GpsServiceReceiver", "onReceive()--> Phone Gps ON");
              mGpsStatus.setBackgroundResource(R.drawable.gps_on_phone);       
            }
            if (action.equals(Constants.NETWORK_GPS_ON)) 
            {
              Log.d("GpsServiceReceiver", "onReceive()--> Network Gps ON");
              mGpsStatus.setBackgroundResource(R.drawable.gps_on_network);

            }       
            if (action.equals(Constants.PHONE_GPS_OFF)) 
            {
              Log.d("GpsServiceReceiver", "onReceive()--> Phone Gps OFF");
              mGpsStatus.setBackgroundResource(R.drawable.gps_off);

            }    
        }
    };
    
    /********************* RECEIVES MESSAGES FROM STORE'N'FORWARD SERVICE *****************************/
    
    private BroadcastReceiver mServiceReceiver = new BroadcastReceiver() 
    {
        @Override
        public void onReceive(Context context, Intent intent) 
        {
          String action = intent.getAction();

            if (action.equals(Constants.INTERNET_ON)) 
            {
              Log.d("ServiceReceiver", "Internet is ON");
              mInterUplStatus.setBackgroundResource(R.drawable.internet_on);
            }
            if (action.equals(Constants.INTERNET_OFF)) 
            {
              Log.d("ServiceReceiver", "Internet is OFF");
              mInterUplStatus.setBackgroundResource(R.drawable.internet_off);
            }    
            if (action.equals(Constants.UPLOAD_ON)) 
            {
              Log.d("ServiceReceiver", "Upload is ON");
              mInterUplStatus.setBackgroundResource(R.drawable.upload);
            }   
            if (action.equals(Constants.UPLOAD_OFF)) 
            {
              Log.d("ServiceReceiver", "Upload is OFF");
              mInterUplStatus.setBackgroundResource(R.drawable.internet_on);
            }   
        }
    };
        
    
  /********************** CALLS getData() FUNCTION *************************************************/
  
    private class GetDataTask extends AsyncTask<String, Void, List<MapCluster>>
    {    
      @Override
      protected void onPreExecute()
      {

      }
      
      @Override
      protected void onPostExecute(List<MapCluster> param)
      {
        int color;
        
        //draw map cluster on the map
        if((mMapClusters != null)&&(mMapClusters.size() > 0))
        {
          for(int i = 0; i < mMapClusters.size(); i++)
          {
            MapCluster mapCluster = mMapClusters.get(i);
            
            if(mapCluster.mBcLevel != 0)
            {
              Log.d("GetDataTask", "onPostExecute()--> pos: "+i+ " bc level: "+mapCluster.mBcLevel+" coords: " +mapCluster.mMinLat+", "+mapCluster.mMinLon+", "+mapCluster.mMaxLat+", "+mapCluster.mMaxLon);
            
              if((mapCluster.mBcLevel > 0)&&(mapCluster.mBcLevel <= 10))
                color = ColorHelper.numberToColor(mapCluster.mBcLevel * BC_MULTIPLIER);
              else
                color = ColorHelper.numberToColor(100);
              
              mMapPolygons.add(mGoogleMap.addPolygon(new PolygonOptions()
                    .add(new LatLng(mapCluster.mMinLat, mapCluster.mMinLon), new LatLng(mapCluster.mMinLat, mapCluster.mMaxLon),
                        new LatLng(mapCluster.mMaxLat, mapCluster.mMaxLon), new LatLng(mapCluster.mMaxLat, mapCluster.mMinLon))
                    .strokeColor(Color.TRANSPARENT)
                    .fillColor(Color.parseColor("#66" + String.format("%06X", 0xFFFFFF & color)))));
            }
          }
        }  
        
        if((mProgressDialog2 != null)&&(mProgressDialog2.isShowing()))
          mProgressDialog2.dismiss();
        
        runOnUiThread(new Runnable()
        {
        @Override
        public void run() 
        {
          int clusterNum = 0;
          if(mMapClusters != null)
            clusterNum = mMapClusters.size();
          
          Toast.makeText(Map.this, "Found "+clusterNum+ " black carbon measures", Toast.LENGTH_LONG).show();
          
        }
          
        });
      }
      
    @Override
    protected List<MapCluster> doInBackground(String... params) 
    {
      int statusCode = -1;
      InputStream is = null;
      
      try 
      {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(params[0]);    
        HttpResponse response = httpClient.execute(httpGet);
      
        Log.d("GetDataTask", "doInBackground()--> status line: " + response.getStatusLine());
        
        //if server response is 'HTTP 200 OK'
        if(response.getStatusLine().getStatusCode() == Constants.STATUS_OK)
        {
            if (response.getEntity() != null) 
            {  
              if(mKmlParser == null)
                mKmlParser = new KmlParser();
      
              //get InputStream from response entity
              is = response.getEntity().getContent();

              mMapClusters = mKmlParser.parseKml(is);  
            }
        }
        else
        {
          if((mProgressDialog2 != null)&&(mProgressDialog2.isShowing()))
              mProgressDialog2.dismiss();
          
          Toast.makeText(Map.this, response.getStatusLine().toString(), Toast.LENGTH_LONG).show();
        }
              
      }
      //this exception is invoked when internet connection is up but traffic is not allowed
      //(for example, for networks that needs login but user is not logged)
      catch (HttpHostConnectException e) 
      {
        e.printStackTrace();
      } 
      catch (IllegalArgumentException e) 
      {
        e.printStackTrace();
      } 
      catch (ClientProtocolException e) 
      {
        e.printStackTrace();
      } 
      catch (IOException e) 
      {
        e.printStackTrace();
      }
        finally
        {
          try 
            {
            if(is != null)
              is.close();
            } 
            catch (IOException e) 
            {
              e.printStackTrace();
            }
        }
      
      Log.d("GetDataTask", "run()--> status code: " +statusCode);
      
      return mMapClusters;
    }
      
    }
  
    /********************** SHARE SECTION ***************************************************************/
    
  //get button references and set text on them
  private void getShareButtonsRef(Dialog dialog)
  {
    mValidFbSession = mFacebookManager.isSessionValid();
    mValidTwSession = Utils.getValidTwSession(getApplicationContext());// mTwitterManager.isSessionValid();  
    
    //if(mButtons[0] == null)
    //{
      mButtons[0] = (Button)dialog.findViewById(R.id.facebook_log_button);
      mButtons[0].setOnClickListener(new OnClickListener()
      {
        @Override
        public void onClick(View arg0) 
        {
          //read network type index on which upload data is allowed: 0 - only wifi; 1 - both wifi and mobile
          int networkTypeIndex = Utils.getUploadNetworkTypeIndex(getApplicationContext());
          
          //1 - is internet connection available? 
          boolean[] connectivity = Utils.haveNetworkConnection(getApplicationContext());
          
          //if user wants to upload only on wifi networks, connectivity[0] (network connectivity) must be true
          if(networkTypeIndex == 0)
          {
            if(connectivity[0])
              mConnectivityOn = true;
            else
              mConnectivityOn = false;
          }
          else //if user wants to upload both on wifi/mobile networks
            mConnectivityOn = connectivity[0] || connectivity[1];
          
          if(mValidFbSession)
          {
            mFacebookManager.clearCredentials();
          }
          else
          {
            if(mConnectivityOn)
            {
              mFacebookManager.authorizeFbUser();
            }
            else
            {
              noConnectivityDialog();
            }
          }
        }        
      });
    //}
    //if(mButtons[1] == null)
    //{
      mButtons[1] = (Button)dialog.findViewById(R.id.twitter_log_button);
      mButtons[1].setOnClickListener(new OnClickListener()
      {
        @Override
        public void onClick(View arg0) 
        {
          //read network type index on which upload data is allowed: 0 - only wifi; 1 - both wifi and mobile
          int networkTypeIndex = Utils.getUploadNetworkTypeIndex(getApplicationContext());
          
          //1 - is internet connection available? 
          boolean[] connectivity = Utils.haveNetworkConnection(getApplicationContext());
          
          //if user wants to upload only on wifi networks, connectivity[0] (network connectivity) must be true
          if(networkTypeIndex == 0)
          {
            if(connectivity[0])
              mConnectivityOn = true;
            else
              mConnectivityOn = false;
          }
          else //if user wants to upload both on wifi/mobile networks
            mConnectivityOn = connectivity[0] || connectivity[1];
          
          if(mValidTwSession)
          {
            mTwitterManager.shutdown();
                    
                    mValidTwSession = false;
                    mButtons[1].setText(getResources().getString(R.string.login_twitter_text));
                    Utils.setValidTwSession(false, getApplicationContext());
                    Toast.makeText(Map.this, "unauthorized", Toast.LENGTH_SHORT).show();
          }
          else
          {
            if(mConnectivityOn)
            {
              mTwitterManager.initTwitter();
            }
            else
            {
              noConnectivityDialog();
            }
          }
        }        
      });
    //}
    
    Log.d("Share", "getShareButtonsRef()--> login facebook: " +mValidFbSession);
    Log.d("Share", "getShareButtonsRef()--> login twitter: " +mValidTwSession);
    
    //display right text (login/logout) on facebook button
    if(mValidFbSession)
      mButtons[0].setText(getResources().getString(R.string.logout_facebook_text));
    else
      mButtons[0].setText(getResources().getString(R.string.login_facebook_text));
    
    //display text (login/logout) on twitter button
    if(mValidTwSession)
      mButtons[1].setText(getResources().getString(R.string.logout_twitter_text));
    else
      mButtons[1].setText(getResources().getString(R.string.login_twitter_text));
  }
  
  private Handler mFacebookHandler = new Handler()
  {
      @Override
      public void handleMessage(Message msg)
      {        
      switch(msg.what)
        {
        case Constants.LOGIN_COMPLETED:
          Log.d("Share", "FacebookHandler --> Login completed");
          mButtons[0].setText(getResources().getString(R.string.logout_facebook_text));
          mValidFbSession = true;        
          Utils.setValidFbSession(true, getApplicationContext());
        break;
        
        case Constants.LOGIN_CLOSED:
          Log.d("Share", "FacebookHandler --> Login closed");
          mButtons[0].setText(getResources().getString(R.string.login_facebook_text));
          mValidFbSession = false;  
          Utils.setValidFbSession(false, getApplicationContext());
        break;
        
        case Constants.LOGIN_CANCEL:
          Log.d("Share", "FacebookHandler --> Login cancel");
          mValidFbSession = false;
          Utils.setValidFbSession(false, getApplicationContext());
        break;
        
        case Constants.LOGIN_ERROR:
          Log.d("Share", "FacebookHandler --> Login error");
          mValidFbSession = false;
          Utils.setValidFbSession(false, getApplicationContext());
        break;
        
        case Constants.LOGIN_FACEBOOK_ERROR:
          Log.d("Share", "FacebookHandler --> Login facebook error");
          mValidFbSession = false;
          Utils.setValidFbSession(false, getApplicationContext());
        break;
        }
      }
  };

    /********************** INVOKED WHEN TwitterLogin RETURNS **********************************************************/
    
    protected void onActivityResult(int requestCode, int resultCode, Intent intent)
    {
        super.onActivityResult(requestCode, resultCode, intent);
        
        if (requestCode == 0) 
        {
            if (resultCode == RESULT_OK) 
            {
              Log.d("Map", "Twitter auth RESULT OK");
              
              String oauthVerifier = intent.getExtras().getString(Constants.IEXTRA_OAUTH_VERIFIER);
              final boolean result = mTwitterManager.authoriseNewUser(oauthVerifier);
              
                new Handler().postDelayed(new Runnable()
                {
          @Override
          public void run() 
          {
            if(result)
            {
              mValidTwSession = true;
              mButtons[1].setText(getResources().getString(R.string.logout_twitter_text));  
              Utils.setValidTwSession(true, getApplicationContext());
            }
            else
            {
                    mValidTwSession = false;
                    mButtons[1].setText(getResources().getString(R.string.login_twitter_text));
            }
          }
                  
                }, 500);
            } 
            else if (resultCode == RESULT_CANCELED) 
            {
              mValidTwSession = false;
              mButtons[1].setText(getResources().getString(R.string.login_twitter_text));
              Utils.setValidTwSession(false, getApplicationContext());
                Log.d("Map", "Twitter auth canceled.");
            }
          
        }
    }

    private void insertAnnDialog(final ExtendedLatLng annLatLng)
    {
      final Dialog insertDialog = new Dialog(Map.this);
    insertDialog.setContentView(R.layout.insert_dialog);
    insertDialog.getWindow().setLayout(LayoutParams.MATCH_PARENT, 
        LayoutParams.WRAP_CONTENT);
    insertDialog.setTitle(R.string.annotation_insertion);
    insertDialog.setCancelable(false);    

    //get reference to send button
    final Button sendButton = (Button)insertDialog.findViewById(R.id.send_button);
    sendButton.setEnabled(false); //active only if there's text

    //get reference to cancel/close window button
    final Button cancelButton = (Button)insertDialog.findViewById(R.id.cancel_button);
    cancelButton.setEnabled(true); //active all time
    cancelButton.setOnClickListener(new OnClickListener()
    {
      @Override
      public void onClick(View v) 
      {
        insertDialog.dismiss();
      }          
    });

    //get reference to edittext in which user writes annotation
    final EditText editText = (EditText)insertDialog.findViewById(R.id.annotation_editText);
    editText.addTextChangedListener(new TextWatcher() 
        {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) 
            {                  
              //if modified text length is more than 0, activate send button
              if(s.length() > 0)
                sendButton.setEnabled(true);
              else
                sendButton.setEnabled(false);
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

            @Override
            public void afterTextChanged(Editable s) {}
         });

    //get checkbox references
    CheckBox facebookChBox = (CheckBox)insertDialog.findViewById(R.id.facebook_checkBox);
    CheckBox twitterChBox = (CheckBox)insertDialog.findViewById(R.id.twitter_checkBox);
    
    //activate check boxes depends from log in facebook/twitter
    boolean[] logs = new boolean[2];
    logs[0] = Utils.getValidFbSession(getApplicationContext());
    logs[1] = Utils.getValidTwSession(getApplicationContext());
    
    facebookChBox.setEnabled(logs[0]);
    twitterChBox.setEnabled(logs[1]);

    //checked on check boxes
    final boolean[] checkeds = Utils.getShareCheckedOn(getApplicationContext());
    if(checkeds[0] == true)
      facebookChBox.setChecked(true);
    else
      facebookChBox.setChecked(false);
    if(checkeds[1] == true)
      twitterChBox.setChecked(true);
    else
      twitterChBox.setChecked(false);        
    
    facebookChBox.setOnCheckedChangeListener(new OnCheckedChangeListener()
    {
      @Override
      public void onCheckedChanged(CompoundButton arg0,
          boolean checked) 
      {
        Utils.setShareCheckedOn(checked, checkeds[1], getApplicationContext());
        checkeds[0] = checked;
      }          
    });
    
    twitterChBox.setOnCheckedChangeListener(new OnCheckedChangeListener()
    {
      @Override
      public void onCheckedChanged(CompoundButton arg0,
          boolean checked) 
      {
        Utils.setShareCheckedOn(checkeds[0], checked, getApplicationContext());
        checkeds[1] = checked;
      }          
    });
    
    //send annotation to server and on facebook/twitter if user is logged on 
    sendButton.setOnClickListener(new OnClickListener()
    {
      @Override
      public void onClick(View v) 
      {
        //1 - read inserted annotation
        String annotation = editText.getText().toString();
        
        //2 - update record on db with annotation and save recordId        
        double recordId = annLatLng.mRecordId;
                
        int result = mDbManager.updateRecordAnnotation(recordId, annotation);
        
        if(result == 1)
          Toast.makeText(getApplicationContext(), "Updated record", Toast.LENGTH_LONG).show();
        else
          Toast.makeText(getApplicationContext(), "Error!", Toast.LENGTH_LONG).show();
        
        boolean[] checks = Utils.getShareCheckedOn(getApplicationContext());
        
        //3 - share on facebook is user wants and internet is active now
        if(checks[0] == true)
        {
          Record annotatedRecord = mDbManager.loadRecordById(recordId);
          try 
          {
            FacebookManager fb = FacebookManager.getInstance(null,null);
            if(fb != null)
              fb.postMessageOnWall(annotatedRecord);
                  } 
          catch (Exception e) 
          {
                      e.printStackTrace();
                  }                
        }
        
        //4 - share on twitter is user wants and internet is active now
        if(checks[1] == true)
        {
          Record annotatedRecord = mDbManager.loadRecordById(recordId);
          
          try 
          {
            TwitterManager twManager = TwitterManager.getInstance(null);
            twManager.postMessage(annotatedRecord);
                  } 
          catch (Exception e) 
          {
                      e.printStackTrace();
                  }
        }

        //5 - show marker for annotated record
        Record annotatedRecord = mDbManager.loadRecordById(recordId);
          
        String userAnn = annotatedRecord.mUserData1;
                 
          if(!userAnn.equals("")&&(annotatedRecord.mValues[0] != 0))
          {
            BitmapDescriptor icon = BitmapDescriptorFactory.fromResource(R.drawable.annotation_marker);
            Marker marker = mGoogleMap.addMarker(new MarkerOptions()
                .position(new LatLng(annotatedRecord.mValues[0], annotatedRecord.mValues[1]))
                .title("BC: "+String.valueOf(annotatedRecord.mBcMobile)+ " "+getResources().getString(R.string.micrograms))
                .snippet("Annotation: " +userAnn)
                .icon(icon)
                .anchor(0f, 1f));
          }
          
        insertDialog.dismiss();        
      }          
    });
    
    insertDialog.show();
    }
    
    /********************* GET DATA FROM SERVER (BC LEVELS AROUND USER CURRENT POSITION) ******************************/
    
    //on click listener of get black carbon levels around user from server
    private OnClickListener mGetBcLevelsOnClickListener = new OnClickListener()
    {
    @Override
    public void onClick(View arg0) 
    {    
      //VERIFY INTERNET CONNECTION 
      
      //read network type index on which upload data is allowed: 0 - only wifi; 1 - both wifi and mobile
      //int networkTypeIndex = Utils.getUploadNetworkTypeIndex(getApplicationContext());
      
      //1 - is internet connection available? 
      boolean[] connectivity = Utils.haveNetworkConnection(getApplicationContext());
      
      /*
      //if user wants to download only on wifi networks, connectivity[0] (network connectivity) must be true
      if(networkTypeIndex == 0)
      {
        if(connectivity[0])
          mConnectivityOn = true;
        else
          mConnectivityOn = false;
      }
      else //if user wants to upload both on wifi/mobile networks
        mConnectivityOn = connectivity[0] || connectivity[1];
      */
      
      //almost one type of connection (network, mobile) must be available
      mConnectivityOn = connectivity[0] || connectivity[1];
      
      //if internet connection is not available, inform user and return
      if(!mConnectivityOn)
      {
        Toast.makeText(getApplicationContext(), getResources().getString(R.string.alert_dialog_no_internet), Toast.LENGTH_LONG).show();
        return;
      }
      
      //DOWNLOAD DATA
      new Handler().post(new Runnable(){

        @Override
        public void run() 
        {
          createProgressDialog2(getResources().getString(R.string.progress_dialog_please_wait), true);  
        }
        
      });
    }     
    };
}




Java Source Code List

android.UnusedStub.java
org.csp.everyaware.ColorHelper.java
org.csp.everyaware.Constants.java
org.csp.everyaware.Credits.java
org.csp.everyaware.ExtendedLatLng.java
org.csp.everyaware.Installation.java
org.csp.everyaware.KmlParser.java
org.csp.everyaware.ManageAccount.java
org.csp.everyaware.Options.java
org.csp.everyaware.Start.java
org.csp.everyaware.Utils.java
org.csp.everyaware.bluetooth.BluetoothBroadcastReceiver.java
org.csp.everyaware.bluetooth.BluetoothHistoryManager.java
org.csp.everyaware.bluetooth.BluetoothManager.java
org.csp.everyaware.bluetooth.BluetoothObject.java
org.csp.everyaware.db.AnnotatedRecord.java
org.csp.everyaware.db.DbManager.java
org.csp.everyaware.db.MapCluster.java
org.csp.everyaware.db.MarkerRecord.java
org.csp.everyaware.db.Record.java
org.csp.everyaware.db.SemanticSessionDetails.java
org.csp.everyaware.db.Track.java
org.csp.everyaware.facebooksdk.AsyncFacebookRunner.java
org.csp.everyaware.facebooksdk.DialogError.java
org.csp.everyaware.facebooksdk.FacebookError.java
org.csp.everyaware.facebooksdk.Facebook.java
org.csp.everyaware.facebooksdk.FbDialog.java
org.csp.everyaware.facebooksdk.Util.java
org.csp.everyaware.fragments.FragmentWizardStep0.java
org.csp.everyaware.fragments.FragmentWizardStep1.java
org.csp.everyaware.fragments.FragmentWizardStep2.java
org.csp.everyaware.gps.GpsTrackingService.java
org.csp.everyaware.internet.FacebookManager.java
org.csp.everyaware.internet.StoreAndForwardService.java
org.csp.everyaware.internet.TwitterLogin.java
org.csp.everyaware.internet.TwitterManager.java
org.csp.everyaware.offline.Graph.java
org.csp.everyaware.offline.Map.java
org.csp.everyaware.offline.MyTracks.java
org.csp.everyaware.offline.Tabs.java
org.csp.everyaware.tabactivities.Graph.java
org.csp.everyaware.tabactivities.Map.java
org.csp.everyaware.tabactivities.Monitor.java
org.csp.everyaware.tabactivities.Tabs.java