com.f8full.casserolesencours.CasserolesEnCoursActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.f8full.casserolesencours.CasserolesEnCoursActivity.java

Source

/*------------------------------------------------------------------------------
 **     Ident: Fabrice Veniard
 **    Author: Fabrice Veniard
 ** Copyright: (c) May 26, 2012 Fabrice Veniard All Rights Reserved.
 **------------------------------------------------------------------------------
 ** Fabrice Veniard                  |  No part of this file may be reproduced  
 ** @f8full                          |  or transmitted in any form or by any        
 **                                  |  means, electronic or mechanical, for the      
 ** H2J Montral                     |  purpose, without the express written    
 ** Qubec                           |  permission of the copyright holder.
 *------------------------------------------------------------------------------
 *
 *   This file is part of casserolesencours.
 *
 *   casserolesencours 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.
 *
 *   casserolesencours 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 casserolesencours.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package com.f8full.casserolesencours;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
import au.com.bytecode.opencsv.CSVReader;

import com.alohar.core.Alohar;
import com.alohar.user.callback.ALEventListener;
import com.alohar.user.callback.ALMotionListener;
import com.alohar.user.content.ALMotionManager;
import com.alohar.user.content.ALPlaceManager;
import com.alohar.user.content.data.ALEvents;
import com.alohar.user.content.data.MotionState;
//import com.alohar.user.content.data.UserStay;
import com.f8full.casserolesencours.R;
import com.google.api.client.auth.oauth2.AuthorizationCodeTokenRequest;
import com.google.api.client.auth.oauth2.ClientParametersAuthentication;
import com.google.api.client.auth.oauth2.TokenResponse;
import com.google.api.client.googleapis.GoogleUrl;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.extensions.android2.auth.GoogleAccountManager;
import com.google.api.client.googleapis.services.GoogleClient;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpResponseException;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.http.xml.atom.AtomContent;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.client.util.GenericData;
import com.google.api.client.xml.XmlNamespaceDictionary;

/*import com.google.api.client.googleapis.services.GoogleClient;
import com.google.api.services.docs.DocsClient;
import com.google.api.services.docs.DocsUrl;
import com.google.api.services.docs.model.DocumentListEntry;
import com.google.api.services.docs.model.DocumentListFeed;*/

import org.json.JSONException;
import org.json.JSONObject;
import org.livinglabmontreal.AtomCategory;
import org.livinglabmontreal.AtomRole;
import org.livinglabmontreal.AtomScope;
import org.livinglabmontreal.OAuth2AccessTokenActivity;
import org.livinglabmontreal.OAuth2ClientCredentials;
import com.google.api.client.googleapis.services.GoogleClient.Builder;

public class CasserolesEnCoursActivity extends Activity implements ALEventListener, ALMotionListener {
    private static final String PREF_NAME = "casserolesencours";
    private static final String PREF_KEY = "aloharuid";
    ///////////////////////////////////////////////////////////////////////////////////
    public static final int APP_ID = 111;

    ////////////////////////////////////////////////////////////////////////////////////////
    //Account casserolesencours@gmail.com
    public static final String API_KEY = "47e49bd099908705ae5ec227de1bab7cdef20b45";
    private static final String PREF_REFRESH_TOKEN = "refreshToken";
    private static final int REQUEST_OAUTH2_AUTHENTICATE = 0;
    private static final String SERVICE_URL = "https://www.google.com/fusiontables/api/query/";
    ///////////////////////////////////////////////////////////////////////////////////////

    private static final String PREF_TABLE_ENCID = "tableEncID";
    private static final String PREF_TABLE_STATUS = "tableStatus";

    private static final String PREF_REGREQUESTTABLE_ENCID = "reqTableID";
    private static final String PREF_VIEWONMASTERTABLE_ENCID = "viewOnMasterTableID";

    public String mFusionTableEncID;
    public String mRegisterRequestTableID;

    public String mViewOnMasterID;
    String NOTIFIACTION_SERVICE_STRING = Context.NOTIFICATION_SERVICE;
    NotificationManager mNotificationManager;
    Notification mNotification;

    private ALMotionManager mMotionManager;
    private boolean mIsStationary = true;
    private ScheduledThreadPoolExecutor mLocationPollThreadExecutor = new ScheduledThreadPoolExecutor(20);

    View mAloharAuthLayout, mMainLayout, mProgress;
    TextView mAccountView, mStatusView;
    /** The main handler. */
    Handler mMainHandler;

    /** The uid. */
    public String mAloharUid;
    private Future<?> mLocPollFrq0 = null;
    private ALPlaceManager mPlaceManager;
    private Future<?> mLocPollFrq1 = null;
    private Future<?> mLocPollFrq2 = null;
    private Future<?> mLocPollFrq3 = null;
    private Alohar mAlohar;
    private SharedPreferences mPrefs;
    private ToggleButton mServiceToggleButton;
    //private EventsManager mEventManager;
    private EditText mUIDView;

    GoogleCredential mGOOGCredential;// = new GoogleCredential();

    HttpTransport mNetHttpTransport = new NetHttpTransport();
    JsonFactory mJaksonJSONFactory = new JacksonFactory();

    GoogleClient mGOOGClient;// = new GoogleClient(mNetHttpTransport, mJaksonJSONFactory, SERVICE_URL);
    private TextView mPollFrequencyText;

    private Spinner mTimeFilterSpinner;
    private Spinner mDistanceFilterSpinner;

    private ArrayAdapter<CharSequence> mTimeFilterAdapter;
    private ArrayAdapter<CharSequence> mDistanceFilterAdapter;

    /** Logging level for HTTP requests/responses. */
    private static final Level LOGGING_LEVEL = Level.ALL;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Logger.getLogger("com.google.api.client").setLevel(LOGGING_LEVEL);

        //That ease dev of technical stuff BUT is not wanted on a mid/longer term
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        mTimeFilterSpinner = (Spinner) findViewById(R.id.timeFilterSpinner);
        mTimeFilterAdapter = ArrayAdapter.createFromResource(this, R.array.timeFilter_choices,
                android.R.layout.simple_spinner_item);
        mTimeFilterAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        mTimeFilterSpinner.setAdapter(mTimeFilterAdapter);

        mDistanceFilterSpinner = (Spinner) findViewById(R.id.distanceFilterSpinner);
        mDistanceFilterAdapter = ArrayAdapter.createFromResource(this, R.array.distanceFilter_choices,
                android.R.layout.simple_spinner_item);
        mDistanceFilterAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        mDistanceFilterSpinner.setAdapter(mDistanceFilterAdapter);

        mAloharAuthLayout = findViewById(R.id.auth_layout);
        mMainLayout = findViewById(R.id.main_layout);
        mProgress = findViewById(R.id.progress_spin);

        mAccountView = (TextView) findViewById(R.id.account);

        mMainHandler = new Handler();

        mStatusView = (TextView) findViewById(R.id.service_status);
        mServiceToggleButton = (ToggleButton) findViewById(R.id.toggle);
        mUIDView = (EditText) findViewById(R.id.uid);

        mNotificationManager = (NotificationManager) getSystemService(NOTIFIACTION_SERVICE_STRING);

        mAlohar = Alohar.init(getApplication());

        mPlaceManager = mAlohar.getPlaceManager();
        mMotionManager = mAlohar.getMotionManager();

        //mEventManager = EventsManager.getInstance();
        //register listener
        //mPlaceManager.registerPlaceEventListener(mEventManager);
        mMotionManager.registerMotionListener(this);

        //Alohar original, I'm testing the other one
        //mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
        mPrefs = getSharedPreferences(PREF_NAME, MODE_PRIVATE);

        mAloharUid = mPrefs.getString(PREF_KEY, null);
        if (mAloharUid == null) {
            mAlohar.register(APP_ID, API_KEY, this);
        }

        mFusionTableEncID = mPrefs.getString(PREF_TABLE_ENCID, null);

        mRegisterRequestTableID = mPrefs.getString(PREF_REGREQUESTTABLE_ENCID, null);

        if (mRegisterRequestTableID == null) {
            ((Button) findViewById(R.id.refreshRegistration)).setEnabled(false);
        } else {
            ((Button) findViewById(R.id.refreshRegistration)).setEnabled(true);
            ((Button) findViewById(R.id.registerTable)).setEnabled(false);
        }

        mViewOnMasterID = mPrefs.getString(PREF_VIEWONMASTERTABLE_ENCID, null);

        if (mViewOnMasterID == null) {
            ((Button) findViewById(R.id.refreshRegistration)).setEnabled(true);
        } else {
            ((Button) findViewById(R.id.refreshRegistration)).setEnabled(false);
        }

        if (mAlohar.isServiceRunning()) {
            //findViewById(R.id.timeFilterSpinner).setClickable(true);
            mDistanceFilterSpinner.setEnabled(true);
        } else {
            //findViewById(R.id.timeFilterSpinner).setClickable(false);
            mDistanceFilterSpinner.setEnabled(false);
        }

        String tableStatus = mPrefs.getString(PREF_TABLE_STATUS, null);
        if (tableStatus == null) {
            tableStatus = getString(R.string.geolocationStatusRegRequired);
            //Setup interface
            //Done in XML file
        } else {
            //setup interface
            if (tableStatus.equals(getString(R.string.geolocationAnonymizePending))) {
                ((TextView) findViewById(R.id.geolocationStatus))
                        .setTextColor(getResources().getColor(R.color.text_orange));
                ((TextView) findViewById(R.id.geolocationStatus))
                        .setText(getString(R.string.geolocationAnonymizePending));

                ((Button) findViewById(R.id.registerAnonymize)).setVisibility(View.GONE);
                ((Button) findViewById(R.id.checkAnonymize)).setVisibility(View.VISIBLE);
            } else if (tableStatus.equals(getString(R.string.geolocationAnonymizeProcessed))) {
                ((TextView) findViewById(R.id.geolocationStatus))
                        .setTextColor(getResources().getColor(R.color.text_green));
                ((TextView) findViewById(R.id.geolocationStatus))
                        .setText(getString(R.string.geolocationAnonymizeProcessed));

                ((Button) findViewById(R.id.checkAnonymize)).setVisibility(View.GONE);
                ((Button) findViewById(R.id.registerAnonymize)).setVisibility(View.GONE);
                ((Button) findViewById(R.id.logWithGoogle)).setVisibility(View.GONE);
                ((Button) findViewById(R.id.toggleGeolocation)).setVisibility(View.VISIBLE);
                findViewById(R.id.geolocationServiceStatus).setVisibility(View.VISIBLE);
                findViewById(R.id.myDataCheckbox).setEnabled(true);
            } else if (tableStatus.equals(getString(R.string.geolocationStatusRegStart))) {
                findViewById(R.id.logWithGoogle).setVisibility(View.GONE);
                findViewById(R.id.registerAnonymize).setVisibility(View.VISIBLE);
                ((TextView) findViewById(R.id.geolocationStatus))
                        .setTextColor(getResources().getColor(R.color.text_orange));
                ((TextView) findViewById(R.id.geolocationStatus))
                        .setText(getString(R.string.geolocationStatusRegStart));
            }
        }

        ((TextView) findViewById(R.id.tableStatus)).setText(tableStatus);

        if (mAloharUid != null) {
            mUIDView.setText(String.valueOf(mAloharUid));
            onAuthenClick(mUIDView);
        } else {
            mAloharAuthLayout.setVisibility(View.VISIBLE);
        }

        mGOOGCredential = new GoogleCredential.Builder().setTransport(mNetHttpTransport)
                .setJsonFactory(mJaksonJSONFactory)//.build();
                .setClientSecrets(OAuth2ClientCredentials.CLIENT_ID, OAuth2ClientCredentials.CLIENT_SECRET).build();

        mGOOGCredential.setAccessToken(null);
        mGOOGCredential.setRefreshToken(mPrefs.getString(PREF_REFRESH_TOKEN, null));

        //Logger.getLogger("com.google.api.client").setLevel(LOGGING_LEVEL);

        Builder truc = GoogleClient.builder(mNetHttpTransport, mJaksonJSONFactory, new GenericUrl(SERVICE_URL));
        truc.setHttpRequestInitializer(mGOOGCredential);

        mGOOGClient = truc.build();

        mPollFrequencyText = (TextView) findViewById(R.id.pollFrequencyText);
        mPollFrequencyText.setText("N/A when stationary");
        //Something is wrong with the color, I'll see that cosmetic side later
        //mPollFrequencyText.setTextColor(R.color.text_violet);

        mLocationPollThreadExecutor.setKeepAliveTime(0, TimeUnit.SECONDS);

        RadioGroup pollFrequencyRadioGroup = (RadioGroup) findViewById(R.id.pollFrequencyRadioGroup);

        pollFrequencyRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {

                cancelActiveTasks();
                startTaskForId(checkedId, true);
            }
        });

        findViewById(R.id.frequency0).setEnabled(false);
        findViewById(R.id.frequency1).setEnabled(false);
        findViewById(R.id.frequency2).setEnabled(false);
        findViewById(R.id.frequency3).setEnabled(false);

    }

    /* (non-Javadoc)
     * @see android.app.Activity#onPostCreate(android.os.Bundle)
     */
    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        //update the title
        String title = String.format("%s v%s %d", getString(R.string.app_name), getString(R.string.version),
                mAlohar.version());
        setTitle(title);
    }

    /* (non-Javadoc)
     * @see android.app.Activity#onResume()
     */
    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        updateServiceStatus();
        //update current user stay
        //UserStay stay = mPlaceManager.getLastKnownStay();
        /*if (stay != null) {
        ((TextView)findViewById(R.id.current_stay)).setText(stay.toString());
          }*/
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
        case REQUEST_OAUTH2_AUTHENTICATE:
            if (resultCode == RESULT_OK) {
                //here I have authorization code
                final String code = data.getStringExtra("authcode");

                //This is not great, my thread pool is polluted
                mLocationPollThreadExecutor.execute(new Runnable() {
                    public void run() {
                        try {
                            TokenResponse accessTokenResponse = new AuthorizationCodeTokenRequest(
                                    new NetHttpTransport(), new JacksonFactory(),
                                    new GenericUrl("https://accounts.google.com/o/oauth2/token"), code)
                                            .setRedirectUri(OAuth2ClientCredentials.REDIRECT_URI)
                                            .setScopes(OAuth2ClientCredentials.SCOPE)
                                            .setClientAuthentication(new ClientParametersAuthentication(
                                                    OAuth2ClientCredentials.CLIENT_ID,
                                                    OAuth2ClientCredentials.CLIENT_SECRET))
                                            .execute();

                            mMainHandler.post(new Runnable() {

                                public void run() {

                                    findViewById(R.id.logWithGoogle).setVisibility(View.GONE);
                                    findViewById(R.id.registerAnonymize).setVisibility(View.VISIBLE);
                                    ((TextView) findViewById(R.id.geolocationStatus))
                                            .setTextColor(getResources().getColor(R.color.text_orange));
                                    ((TextView) findViewById(R.id.geolocationStatus))
                                            .setText(getString(R.string.geolocationStatusRegStart));
                                    setTableStatus(getString(R.string.geolocationStatusRegStart));
                                }
                            });

                            setRefreshToken(accessTokenResponse.getRefreshToken());
                            mGOOGCredential.setFromTokenResponse(accessTokenResponse);

                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                });

            } else {
                //Auth code grabing wnet wrong, relaunch activity (that could give a wonderfull infinite loop on no network access ?
                //For now on just do nothing
            }
            break;
        }
    }

    void setRefreshToken(String refreshToken) {
        SharedPreferences.Editor editor = mPrefs.edit();
        editor.putString(PREF_REFRESH_TOKEN, refreshToken);
        editor.commit();
    }

    void setViewOnMasterTableID(String viewOnMasterID) {
        SharedPreferences.Editor editor = mPrefs.edit();
        editor.putString(PREF_VIEWONMASTERTABLE_ENCID, viewOnMasterID);
        editor.commit();
    }

    void setRegRequestTableID(String tableEncID) {
        SharedPreferences.Editor editor = mPrefs.edit();
        editor.putString(PREF_REGREQUESTTABLE_ENCID, tableEncID);
        editor.commit();
    }

    void setTableEncID(String tableEncID) {
        SharedPreferences.Editor editor = mPrefs.edit();
        editor.putString(PREF_TABLE_ENCID, tableEncID);

        editor.commit();
    }

    void setTableStatus(String status) {
        SharedPreferences.Editor editor = mPrefs.edit();

        editor.putString(PREF_TABLE_STATUS, status);
        editor.commit();
    }

    /**
     * Update service status.
     */
    private void updateServiceStatus() {
        if (mAlohar.isServiceRunning()) {
            mServiceToggleButton.setChecked(true);
            mStatusView.setText("Service is running!");
        } else {
            mServiceToggleButton.setChecked(false);
            mStatusView.setText("Service stopped");
        }
    }

    /**
     * On register click.
     *
     * @param v the view
     */
    public void onRegisterClick(View v) {
        mAloharAuthLayout.setVisibility(View.GONE);
        mMainLayout.setVisibility(View.GONE);
        mProgress.setVisibility(View.VISIBLE);
        mAlohar.register(APP_ID, API_KEY, this);
    }

    /**
     * On authen click.
     *
     * @param v the view
     */
    public void onAuthenClick(View v) {
        String inputUID = mUIDView.getText().toString();
        if (inputUID.trim().length() == 0) {
            toastError("Please give a valid UID");
        } else {
            mAloharUid = inputUID;
            try {
                mAlohar.authenticate(mAloharUid, APP_ID, API_KEY, this);
            } catch (Exception e) {
                //             e.printStackTrace();
            }
        }
        mProgress.setVisibility(View.VISIBLE);
    }

    public void onViewerModeClick(View view) {
        //TODO: View only my data on the map
        /*if(mViewOnMasterID == null)
        {
           toastMessage(getString(R.string.anonimizeRequired));
        return;
        }*/

        String timeFilter = ((Spinner) findViewById(R.id.timeFilterSpinner)).getSelectedItem().toString();
        String distanceFilter = ((Spinner) findViewById(R.id.distanceFilterSpinner)).getSelectedItem().toString();

        String whereClause = "";

        if (distanceFilter.equals("--") == false)
        //time filtering requested by user
        {
            if (mAlohar.getPlaceManager().getCurrentLocation().getLatitude() == 0.0
                    || mAlohar.getPlaceManager().getCurrentLocation().getLongitude() == 0.0) {
                //Location not available
                toastMessage(getString(R.string.locationFilterError));
            } else {
                String WhereClauseDistanceFilter = "";

                switch (((Spinner) findViewById(R.id.distanceFilterSpinner)).getSelectedItemPosition()) {
                case 1:
                    WhereClauseDistanceFilter = "100";
                    break;
                case 2:
                    WhereClauseDistanceFilter = "300";
                    break;
                case 3:
                    WhereClauseDistanceFilter = "500";
                    break;
                case 4:
                    WhereClauseDistanceFilter = "1000";
                    break;
                case 5:
                    WhereClauseDistanceFilter = "20000";
                    break;
                }

                //double testLat = 45.5334;
                //double testLong = -73.5838;

                //WHERE Pharmacy='yes' AND 
                whereClause += "WHERE ST_INTERSECTS(Location, CIRCLE(LATLNG("
                        + Double.toString(mAlohar.getPlaceManager().getCurrentLocation().getLatitude())
                        //+ Double.toString(testLat)
                        + "," + Double.toString(mAlohar.getPlaceManager().getCurrentLocation().getLongitude())
                        //+ Double.toString(testLong)
                        + ")," + WhereClauseDistanceFilter + ")) ";
                //37.3242,-121.9806),5000))"
            }
        }

        if (timeFilter.equals("--") == false)
        //time filtering requested by user
        {
            if (whereClause.isEmpty() == false) {
                whereClause += "AND ";
            } else {
                whereClause += "WHERE ";
            }

            Calendar cl = Calendar.getInstance();
            cl.setTime(new Date());
            switch (((Spinner) findViewById(R.id.timeFilterSpinner)).getSelectedItemPosition()) {
            case 1:
                cl.add(Calendar.MINUTE, -5);
                break;
            case 2:
                cl.add(Calendar.MINUTE, -15);
                break;
            case 3:
                cl.add(Calendar.MINUTE, -45);
                break;
            case 4:
                cl.add(Calendar.HOUR, -2);
                break;
            }

            whereClause += "Date>='" + DateFormat.getDateTimeInstance().format(cl.getTime()) + "' ";
        }

        //1cmlx9aChHUYTWwYivaZucr7NHNsP_ulvEPX1FoM is master table public view ID
        String fromTableID = "1cmlx9aChHUYTWwYivaZucr7NHNsP_ulvEPX1FoM";

        if (((CheckBox) findViewById(R.id.myDataCheckbox)).isChecked()) {
            fromTableID = mViewOnMasterID;
        }

        //excellent, just do a request to grab the locations and pass them around

        final String SqlQuery = "SELECT Date, Location, Description FROM " + fromTableID + " " + whereClause
                + "ORDER BY Date DESC LIMIT " + ((EditText) findViewById(R.id.nbIconsMax)).getText();

        final boolean myLocationEnabled = !(((CheckBox) findViewById(R.id.worldMapChkBx)).isChecked());
        final boolean timeColored = ((CheckBox) findViewById(R.id.timeColoredCheckbox)).isChecked();

        new Thread((new Runnable() {

            public void run() {
                try {

                    String encodedQuery = URLEncoder.encode(SqlQuery, "UTF-8");

                    GoogleUrl GUrl = new GoogleUrl(SERVICE_URL + "?sql=" + encodedQuery + "&encid=true");

                    HttpRequest request = mGOOGClient.getRequestFactory().buildGetRequest(GUrl);
                    HttpHeaders headers = new HttpHeaders();

                    headers.setContentLength("0");//Required so that Fusion Table API considers request
                    request.setHeaders(headers);

                    HttpResponse response = request.execute();

                    if (response.getStatusCode() == 200) {
                        //Here I have my data
                        InputStreamReader inputStreamReader = new InputStreamReader(response.getContent());
                        BufferedReader bufferedStreamReader = new BufferedReader(inputStreamReader);
                        CSVReader reader = new CSVReader(bufferedStreamReader);
                        // The first line is the column names, and the remaining lines are the rows.
                        List<String[]> csvLines = reader.readAll();

                        List<String> columns = Arrays.asList(csvLines.get(0));
                        List<String[]> rows = csvLines.subList(1, csvLines.size());

                        if (rows.size() == 0) {
                            toastMessage("Table vide !");
                            return;
                        }

                        ArrayList<String> rowData = new ArrayList<String>();

                        for (String[] row : rows) {
                            String toAdd = "";
                            for (String cell : row) {
                                //No , in data, or things are gonna go horribly wrong here
                                toAdd += cell + "|";
                            }

                            //I have this last pesky separator ,it will give me an empty String on the other side
                            rowData.add(toAdd);
                        }

                        Intent mapIntent = new Intent(getApplicationContext(),
                                CasserolesEnCoursViewerActivity.class);
                        mapIntent.putStringArrayListExtra("rowsData", rowData);
                        mapIntent.putExtra("timeColored", timeColored);
                        mapIntent.putExtra("myLocation", myLocationEnabled);

                        if (myLocationEnabled)
                            toastMessage(getString(R.string.lastContributionTapHintLocal));
                        else
                            toastMessage(getString(R.string.lastContributionTapHintWorld));
                        //mapIntent.putExtra("relativeTime", ((CheckBox)findViewById(R.id.relativeTimeCheckbox)).isChecked());
                        startActivity(mapIntent);

                    }

                } catch (HttpResponseException e) {
                    if (e.getStatusCode() == 401) {
                        mGOOGCredential.setAccessToken(null);

                        SharedPreferences.Editor editor2 = mPrefs.edit();
                        editor2.remove(PREF_REFRESH_TOKEN);
                        editor2.commit();

                        toastMessage("OAuth login required, redirecting...");

                        //This last Constant is weird
                        startActivityForResult(
                                new Intent().setClass(getApplicationContext(), OAuth2AccessTokenActivity.class),
                                REQUEST_OAUTH2_AUTHENTICATE);

                    }

                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        })).start();
    }

    /**
     * On service click.
     *
     * @param view the view
     */
    public void onServiceClick(View view) {
        boolean isChecked = ((ToggleButton) view).isChecked();
        if (isChecked) {
            //turn on
            mAlohar.startServices();
            //StatusView.setText("Service is running!");
            ((TextView) findViewById(R.id.geolocationServiceStatus))
                    .setText(getString(R.string.geolocationStatusOn));
            ((TextView) findViewById(R.id.geolocationServiceStatus))
                    .setTextColor(getResources().getColor(R.color.text_red));
            ((TextView) findViewById(R.id.distanceFilterNA)).setVisibility(View.INVISIBLE);
            findViewById(R.id.FrequencyGroupLayout).setVisibility(View.VISIBLE);
            mDistanceFilterSpinner.setEnabled(true);

            //String freq = ((RadioButton)findViewById( ((RadioGroup)findViewById(R.id.pollFrequencyRadioGroup)).getCheckedRadioButtonId() )).getText().toString();
            String text = getString(R.string.geolocationStatusOnNotification);//String.format(getString(R.string.geolocationOnNotification), freq);
            int icon = R.drawable.ic_launcher;
            CharSequence tickerText = text;

            long when = System.currentTimeMillis();

            mNotification = new Notification(icon, tickerText, when);
            mNotification.flags |= Notification.FLAG_ONGOING_EVENT;
            CharSequence contentText = getString(R.string.geolocationOnNotificationNoFreq);
            CharSequence contentTitle = getString(R.string.app_name);
            Intent notificationIntent = new Intent(this, CasserolesEnCoursActivity.class);
            mNotification.contentIntent = PendingIntent.getActivity(this, 0, notificationIntent,
                    Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
            mNotification.setLatestEventInfo(this, contentTitle, contentText, mNotification.contentIntent);
            mNotificationManager.notify(R.layout.main, mNotification);

        } else {
            //turn off
            mAlohar.stopServices();
            ((TextView) findViewById(R.id.geolocationServiceStatus))
                    .setText(getString(R.string.geolocationStatusOff));
            ((TextView) findViewById(R.id.geolocationServiceStatus))
                    .setTextColor(getResources().getColor(R.color.text_green));
            ((TextView) findViewById(R.id.distanceFilterNA)).setVisibility(View.VISIBLE);
            findViewById(R.id.FrequencyGroupLayout).setVisibility(View.INVISIBLE);
            mDistanceFilterSpinner.setSelection(0);
            mDistanceFilterSpinner.setEnabled(false);

            //((RadioGroup) findViewById(R.id.pollFrequencyRadioGroup)).check(-1);
            cancelActiveTasks();
            mLocationPollThreadExecutor.purge();

            //That is a hack, some code path must be missed, I'm tracking a thread leak bug when app is in background for a long time
            mLocationPollThreadExecutor.shutdown();
            mLocationPollThreadExecutor = new ScheduledThreadPoolExecutor(20);

            mIsStationary = true;
            mNotificationManager.cancel(R.layout.main);
        }
    }

    public void onManifClick(View view) {
        boolean isChecked = ((ToggleButton) view).isChecked();
        final String description;
        if (isChecked) {
            description = "MANIF START";
        } else {
            description = "MANIF END";
        }

        new Thread((new Runnable() {

            public void run() {

                //Threaded : httpTransport is Thread safe, hence concurrent access to the web should be handled
                writeToFusionTable(true, description);

            }
        })).start();
    }

    public void onAntiEmeuteClick(View view) {
        boolean isChecked = ((ToggleButton) view).isChecked();
        final String description;
        if (isChecked) {
            description = "Anti Emeute Start";
        } else {
            description = "Anti Emeute END";
        }

        new Thread((new Runnable() {

            public void run() {

                //Threaded : httpTransport is Thread safe, hence concurrent access to the web should be handled
                writeToFusionTable(true, description);

            }
        })).start();
    }

    public void onSpotDispersionClick(View view) {

        final String description = "Ordre de dispersion ! :S";

        new Thread((new Runnable() {

            public void run() {

                //Threaded : httpTransport is Thread safe, hence concurrent access to the web should be handled
                writeToFusionTable(true, description);

            }
        })).start();
    }

    public void onSpotFusionClick(View view) {

        final String description = "Fusion ! :)";

        new Thread((new Runnable() {

            public void run() {

                //Threaded : httpTransport is Thread safe, hence concurrent access to the web should be handled
                writeToFusionTable(true, description);

            }
        })).start();
    }

    public void onSpotReductionClick(View view) {

        final String description = "reduction ! :s";

        new Thread((new Runnable() {

            public void run() {

                //Threaded : httpTransport is Thread safe, hence concurrent access to the web should be handled
                writeToFusionTable(true, description);

            }
        })).start();
    }

    public void onClearTableClick(View view) {

        //TextView textView = (TextView) findViewById(R.id.tableInfo);
        //textView.setText("Tap create");

        ((Button) findViewById(R.id.clearTable)).setEnabled(false);
        ((Button) findViewById(R.id.registerTable)).setEnabled(false);

        ((Button) findViewById(R.id.registerTable)).setEnabled(false);
        ((Button) findViewById(R.id.refreshRegistration)).setEnabled(false);
        ((Button) findViewById(R.id.createTable)).setEnabled(true);

        mFusionTableEncID = null;
        mRegisterRequestTableID = null;
        mViewOnMasterID = null;

        ((TextView) findViewById(R.id.tableStatus)).setText(R.string.tableStatusNoTable);

        SharedPreferences.Editor editor2 = mPrefs.edit();
        editor2.remove(PREF_TABLE_ENCID);
        editor2.remove(PREF_TABLE_STATUS);
        editor2.remove(PREF_VIEWONMASTERTABLE_ENCID);
        editor2.remove(PREF_REGREQUESTTABLE_ENCID);
        editor2.commit();

    }

    public void onCreateTableClick(View view) {

        new Thread((new Runnable() {

            public void run() {
                try {
                    sendCreateQueryToFusionTable();

                } catch (HttpResponseException e) {
                    if (e.getStatusCode() == 401) {
                        mGOOGCredential.setAccessToken(null);

                        SharedPreferences.Editor editor2 = mPrefs.edit();
                        editor2.remove(PREF_REFRESH_TOKEN);
                        editor2.commit();

                        toastMessage("OAuth login required, redirecting...");

                        //This last Constant is weird
                        startActivityForResult(
                                new Intent().setClass(getApplicationContext(), OAuth2AccessTokenActivity.class),
                                REQUEST_OAUTH2_AUTHENTICATE);

                    }

                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        })).start();
    }

    private void publicizeTable() throws IOException {
        try {

            XmlNamespaceDictionary docDic = new XmlNamespaceDictionary();
            docDic.set("", "http://www.w3.org/2005/Atom");
            docDic.set("gAcl", "http://schemas.google.com/acl/2007");

            GenericData data = new GenericData();
            AtomCategory category = AtomCategory.newKind("accessRule");
            AtomRole role = AtomRole.newRole("reader");
            AtomScope scope = AtomScope.newScope("default");

            data.put("category", category);
            data.put("gAcl:role", role);
            data.put("gAcl:scope", scope);

            AtomContent content = AtomContent.forEntry(docDic, data);

            GoogleUrl GUrl = new GoogleUrl(
                    "https://docs.google.com/feeds/default/private/full/" + mFusionTableEncID + "/acl?v=3");
            HttpRequest request = mGOOGClient.getRequestFactory().buildPostRequest(GUrl, content);

            HttpResponse response = request.execute();

            if (response.getStatusCode() == 201) {
                toastMessage(getString(R.string.publicizeDataTableToast));
                //Success !
            }
        } catch (HttpResponseException e) {
            if (e.getStatusCode() == 409) //Conflict
            {
                toastMessage(getString(R.string.publicizeDataTableToast));
                return;
            }
            throw (e);
        } catch (IOException e) {
            throw (e);
        }

    }

    public void onAnonymizeClick(View view) {
        new Thread((new Runnable() {

            public void run() {
                try {
                    //publicizeTable();   //Make the data table public -- Removed as it's not nescessary, server will 
                    //it will be shared with server for initial data copy and then given back to the user
                    createAndShareRequestTable(); //Create table and share it so it can be found

                } catch (HttpResponseException e) {
                    if (e.getStatusCode() == 401) {
                        mGOOGCredential.setAccessToken(null);

                        SharedPreferences.Editor editor2 = mPrefs.edit();
                        editor2.remove(PREF_REFRESH_TOKEN);
                        editor2.commit();

                        toastMessage("OAuth login required, redirecting...");

                        //This last Constant is weird
                        startActivityForResult(
                                new Intent().setClass(getApplicationContext(), OAuth2AccessTokenActivity.class),
                                REQUEST_OAUTH2_AUTHENTICATE);

                    }

                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        })).start();
    }

    public void onRegisterTableClick(View view) {
        new Thread((new Runnable() {

            public void run() {
                try {
                    //publicizeTable();   //Make the data table public -- Removed as it's not nescessary, server will 
                    //it will be shared with server for initial data copy and then given back to the user
                    createAndShareRequestTable(); //Create table and share it so it can be found

                } catch (HttpResponseException e) {
                    if (e.getStatusCode() == 401) {
                        mGOOGCredential.setAccessToken(null);

                        SharedPreferences.Editor editor2 = mPrefs.edit();
                        editor2.remove(PREF_REFRESH_TOKEN);
                        editor2.commit();

                        toastMessage("OAuth login required, redirecting...");

                        //This last Constant is weird
                        startActivityForResult(
                                new Intent().setClass(getApplicationContext(), OAuth2AccessTokenActivity.class),
                                REQUEST_OAUTH2_AUTHENTICATE);

                    }

                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        })).start();
    }

    public void onAnonymizeRefreshClick(View v) {

        if (mRegisterRequestTableID == null)
            return;

        new Thread((new Runnable() {

            public void run() {
                try {
                    //Getting view on master table on which the contributor has write access
                    String SqlQuery = "SELECT Date, RequestedViewOnMasterTable_ID FROM " + mRegisterRequestTableID
                            + " ORDER BY Date ASC";

                    String encodedQuery = URLEncoder.encode(SqlQuery, "UTF-8");

                    GoogleUrl GUrl = new GoogleUrl(SERVICE_URL + "?sql=" + encodedQuery + "&encid=true");

                    HttpRequest request = mGOOGClient.getRequestFactory().buildGetRequest(GUrl);
                    HttpHeaders headers = new HttpHeaders();

                    headers.setContentLength("0");//Required so that Fusion Table API considers request
                    request.setHeaders(headers);

                    HttpResponse response = request.execute();

                    if (response.getStatusCode() == 200) {
                        //Here I have my data
                        InputStreamReader inputStreamReader = new InputStreamReader(response.getContent());
                        BufferedReader bufferedStreamReader = new BufferedReader(inputStreamReader);
                        CSVReader reader = new CSVReader(bufferedStreamReader);
                        // The first line is the column names, and the remaining lines are the rows.
                        List<String[]> csvLines = reader.readAll();
                        List<String> columns = Arrays.asList(csvLines.get(0));
                        List<String[]> rows = csvLines.subList(1, csvLines.size());

                        if (rows.size() < 3 || rows.size() >= 4) {
                            toastMessage(getString(R.string.regNotProcessed));

                            return;
                        } else {
                            //hack to select the right row
                            for (String[] curRowContent : rows) {
                                //Ref id for length, this is my current ID 
                                String potentialID = curRowContent[1];
                                if (potentialID.length() == "13WOJlilS1fbwVoO9z1H4bVIqWxcxZJeesZL5qGg".length()) {
                                    //found ID
                                    mViewOnMasterID = potentialID;
                                    setViewOnMasterTableID(mViewOnMasterID);
                                    break;
                                }
                            }

                            mMainHandler.post(new Runnable() {

                                public void run() {

                                    ((TextView) findViewById(R.id.geolocationStatus))
                                            .setTextColor(getResources().getColor(R.color.text_green));
                                    ((TextView) findViewById(R.id.geolocationStatus))
                                            .setText(getString(R.string.geolocationAnonymizeProcessed));

                                    setTableStatus(getString(R.string.geolocationAnonymizeProcessed));

                                    findViewById(R.id.myDataCheckbox).setEnabled(true);

                                    ((Button) findViewById(R.id.checkAnonymize)).setVisibility(View.GONE);
                                    ((Button) findViewById(R.id.toggleGeolocation)).setVisibility(View.VISIBLE);
                                    findViewById(R.id.geolocationServiceStatus).setVisibility(View.VISIBLE);
                                }
                            });

                        }

                    }

                } catch (HttpResponseException e) {
                    if (e.getStatusCode() == 401) {
                        mGOOGCredential.setAccessToken(null);

                        SharedPreferences.Editor editor2 = mPrefs.edit();
                        editor2.remove(PREF_REFRESH_TOKEN);
                        editor2.commit();

                        toastMessage("OAuth login required, redirecting...");

                        //This last Constant is weird
                        startActivityForResult(
                                new Intent().setClass(getApplicationContext(), OAuth2AccessTokenActivity.class),
                                REQUEST_OAUTH2_AUTHENTICATE);

                    }

                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        })).start();

    }

    private void createAndShareRequestTable() throws JSONException, HttpResponseException, IOException {
        String SqlQuery = "CREATE TABLE " + getString(R.string.registerRequestTableName)
                + " (Date:DATETIME, RequestedViewOnMasterTable_ID:STRING)";

        String encodedQuery = URLEncoder.encode(SqlQuery, "UTF-8");

        GoogleUrl GUrl = new GoogleUrl(SERVICE_URL + "?sql=" + encodedQuery + "&encid=true");

        try {

            HttpRequest request = mGOOGClient.getRequestFactory().buildPostRequest(GUrl, null);
            HttpHeaders headers = new HttpHeaders();

            headers.setContentLength("0");//Required so that Fusion Table API considers request
            request.setHeaders(headers);

            HttpResponse response = request.execute();

            if (response.getStatusCode() == 200) {
                //Table created, insert relevant data
                //Extract encrypted ID
                String tableName = "NONAME";

                InputStreamReader inputStreamReader = new InputStreamReader(response.getContent());
                BufferedReader bufferedStreamReader = new BufferedReader(inputStreamReader);
                CSVReader reader = new CSVReader(bufferedStreamReader);
                // The first line is the column names, and the remaining lines are the rows.
                List<String[]> csvLines = reader.readAll();
                List<String> columns = Arrays.asList(csvLines.get(0));
                List<String[]> rows = csvLines.subList(1, csvLines.size());

                //TextView textView = (TextView) findViewById(R.id.nameField);
                String regRequestTableIDToShare = rows.get(0)[0];

                setRegRequestTableID(regRequestTableIDToShare);
                mRegisterRequestTableID = regRequestTableIDToShare;

                //Now insert data
                SqlQuery = "INSERT INTO " + regRequestTableIDToShare
                        + " (Date, RequestedViewOnMasterTable_ID) VALUES ('"
                        + DateFormat.getDateTimeInstance().format(new Date()) + "', '"
                        + getString(R.string.regTableReqRegisteredTextStart) + " "
                        + getString(R.string.updateRegStatusButtonText) + " "
                        + getString(R.string.regTableReqRegisteredTextEnd) + "')";

                encodedQuery = URLEncoder.encode(SqlQuery, "UTF-8");

                GUrl = new GoogleUrl(SERVICE_URL + "?sql=" + encodedQuery);

                try {

                    HttpRequest requestFillRegTable = mGOOGClient.getRequestFactory().buildPostRequest(GUrl, null);
                    headers = new HttpHeaders();

                    headers.setContentLength("0");//Required so that Fusion Table API considers request
                    requestFillRegTable.setHeaders(headers);

                    HttpResponse responseFillRegTable = requestFillRegTable.execute();

                    if (responseFillRegTable.getStatusCode() == 200) {
                        toastMessage("Request table timestamped :)");

                    }

                } catch (HttpResponseException e) {
                    throw e;

                } catch (IOException e) {

                    throw e;
                }

                //now share it with user casserolesencours@gmail.com
                try {
                    //               <entry xmlns="http://www.w3.org/2005/Atom" xmlns:gAcl='http://schemas.google.com/acl/2007'>
                    //                 <category scheme='http://schemas.google.com/g/2005#kind'
                    //                   term='http://schemas.google.com/acl/2007#accessRule'/>
                    //                 <gAcl:role value='writer'/>
                    //                 <gAcl:scope type='user' value='new_writer@example.com'/>
                    //               </entry>

                    XmlNamespaceDictionary docDic = new XmlNamespaceDictionary();
                    docDic.set("", "http://www.w3.org/2005/Atom");
                    docDic.set("gAcl", "http://schemas.google.com/acl/2007");

                    GenericData data = new GenericData();
                    AtomCategory category = AtomCategory.newKind("accessRule");
                    AtomRole role = AtomRole.newRole("writer");
                    AtomScope scope = AtomScope.newScope("user", "casserolesencours@gmail.com");

                    data.put("category", category);
                    data.put("gAcl:role", role);
                    data.put("gAcl:scope", scope);

                    AtomContent content = AtomContent.forEntry(docDic, data);

                    GUrl = new GoogleUrl("https://docs.google.com/feeds/default/private/full/"
                            + regRequestTableIDToShare + "/acl?v=3&send-notification-emails=false");
                    HttpRequest requestShare = mGOOGClient.getRequestFactory().buildPostRequest(GUrl, content);

                    HttpResponse responseShare = requestShare.execute();

                    if (responseShare.getStatusCode() == 201) {
                        toastMessage(getString(R.string.registerShareTableOKToast));

                        mMainHandler.post(new Runnable() {

                            public void run() {

                                ((TextView) findViewById(R.id.geolocationStatus))
                                        .setTextColor(getResources().getColor(R.color.text_orange));
                                ((TextView) findViewById(R.id.geolocationStatus))
                                        .setText(getString(R.string.geolocationAnonymizePending));

                                setTableStatus(getString(R.string.geolocationAnonymizePending));

                                ((Button) findViewById(R.id.registerAnonymize)).setVisibility(View.GONE);
                                ((Button) findViewById(R.id.checkAnonymize)).setVisibility(View.VISIBLE);
                            }
                        });

                    }
                } catch (HttpResponseException e) {
                    if (e.getStatusCode() == 409) //Conflict
                    {
                        toastMessage("SHOULD NOT HAPPEN");
                    }

                    throw (e);
                } catch (IOException e) {
                    throw (e);
                }
            }

        } catch (HttpResponseException e) {
            throw e;

        } catch (IOException e) {

            throw e;
        }

    }

    private void sendCreateQueryToFusionTable() throws JSONException, HttpResponseException, IOException {
        String today = DateFormat.getDateInstance().format(new Date());
        String todayFileFormatted = today.replace(" ", "_").replace(",", "_");

        String SqlQuery = "CREATE TABLE CasserolesEnCours" + todayFileFormatted
                + " (Date:DATETIME, Location:LOCATION, Manual:STRING, Description:STRING, IsStationary:STRING)";

        String encodedQuery = URLEncoder.encode(SqlQuery, "UTF-8");

        GoogleUrl GUrl = new GoogleUrl(SERVICE_URL + "?sql=" + encodedQuery + "&encid=true");

        try {

            HttpRequest request = mGOOGClient.getRequestFactory().buildPostRequest(GUrl, null);
            HttpHeaders headers = new HttpHeaders();

            headers.setContentLength("0");//Required so that Fusion Table API considers request
            request.setHeaders(headers);

            HttpResponse response = request.execute();

            if (response.getStatusCode() == 200) {
                InputStreamReader inputStreamReader = new InputStreamReader(response.getContent());
                BufferedReader bufferedStreamReader = new BufferedReader(inputStreamReader);
                CSVReader reader = new CSVReader(bufferedStreamReader);
                // The first line is the column names, and the remaining lines are the rows.
                List<String[]> csvLines = reader.readAll();
                List<String> columns = Arrays.asList(csvLines.get(0));
                List<String[]> rows = csvLines.subList(1, csvLines.size());

                //TextView textView = (TextView) findViewById(R.id.nameField);
                mFusionTableEncID = rows.get(0)[0];
                setTableEncID(mFusionTableEncID);
                setTableStatus(getString(R.string.tableStatusPrivate));

                //TODO : add request to retrieve NAME of table instead of ID

                mMainHandler.post(new Runnable() {

                    public void run() {
                        //TextView textView = (TextView) findViewById(R.id.tableInfo);
                        //textView.setText(mFusionTableEncID);

                        ((TextView) findViewById(R.id.tableStatus)).setText(getString(R.string.tableStatusPrivate));
                        ((Button) findViewById(R.id.clearTable)).setEnabled(true);
                        ((Button) findViewById(R.id.registerTable)).setEnabled(true);
                        ((Button) findViewById(R.id.createTable)).setEnabled(false);
                    }
                });

                toastMessage("Fusion table create request 200 OK :)--" + mFusionTableEncID);//dataList.get(0).getString("DESC"));
            }

        } catch (HttpResponseException e) {
            throw e;

        } catch (IOException e) {

            throw e;
        }
    }

    /* (non-Javadoc)
     * @see com.alohar.user.callback.ALMotionListener#onMotionStateChanged(com.alohar.user.content.data.MotionState, com.alohar.user.content.data.MotionState)
     */
    public void onMotionStateChanged(MotionState oldState, MotionState newState) {

        if (oldState == MotionState.STATIONARY
                || (newState != MotionState.BIGMOVEMENT && newState != MotionState.MICROMOVEMENT)) {
            //LOG IN TABLE
            final String motionStateSwitch = oldState.name() + "=>" + newState.name();

            final String userStateSwitch = "Stationary=" + mMotionManager.isStationary() + "|OnCommute="
                    + mMotionManager.isOnCommute();

            new Thread((new Runnable() {

                public void run() {

                    //Threaded : httpTransport is Thread safe, hence concurrent access to the web should be handled
                    writeToFusionTable(false, motionStateSwitch);

                }
            })).start();

            mMainHandler.post(new Runnable() {

                public void run() {
                    ((TextView) findViewById(R.id.motion_state)).setText(motionStateSwitch);
                    ((TextView) findViewById(R.id.user_state)).setText(userStateSwitch);
                }
            });
        }

        if (mIsStationary && mMotionManager.isStationary() == false)
        //We started to move, enable frequency controls
        {
            findViewById(R.id.frequency0).setEnabled(true);
            findViewById(R.id.frequency1).setEnabled(true);
            findViewById(R.id.frequency2).setEnabled(true);
            findViewById(R.id.frequency3).setEnabled(true);

            RadioGroup pollFrequencyRadioGroup = (RadioGroup) findViewById(R.id.pollFrequencyRadioGroup);
            if (pollFrequencyRadioGroup.getCheckedRadioButtonId() == -1) {
                //check(...) inderictly calls startTaskForId(...)
                ((RadioGroup) findViewById(R.id.pollFrequencyRadioGroup)).check(R.id.frequency2);
            } else {
                //START SCHEDULED THREADED ACTIVTY TO PUSH Location TO FUSION TABLE
                startTaskForId(pollFrequencyRadioGroup.getCheckedRadioButtonId(), false);
            }

            ((TextView) findViewById(R.id.pollFrequencyText)).setText("{Polling frequency}:");
            //((TextView) findViewById(R.id.pollFrequencyText)).setTextColor(R.color.text_blue);
        } else if (mIsStationary == false && mMotionManager.isStationary())
        //We just stopped, disable 
        {
            findViewById(R.id.frequency0).setEnabled(false);
            findViewById(R.id.frequency1).setEnabled(false);
            findViewById(R.id.frequency2).setEnabled(false);
            findViewById(R.id.frequency3).setEnabled(false);

            //((RadioGroup) findViewById(R.id.pollFrequencyRadioGroup)).check(-1);
            cancelActiveTasks();
            mLocationPollThreadExecutor.purge();

            //Should I thread this as the Alohar's guy did by posting a new thread on the main handle ?
            ((TextView) findViewById(R.id.pollFrequencyText)).setText("{N/A when stationary}");

            //((TextView) findViewById(R.id.pollFrequencyText)).setTextColor(R.color.text_violet);

            new Thread((new Runnable() {

                public void run() {

                    //Threaded : httpTransport is Thread safe, hence concurrent access to the web should be handled
                    writeToFusionTable(false, "Location poll STOP--Purged");

                }
            })).start();

        }

        mIsStationary = mMotionManager.isStationary();
    }

    /////////////////////////////////////////////////////////////////////////////
    protected void writeToFusionTable(boolean manual, String desc) {
        if (mAlohar.getPlaceManager().getCurrentLocation().getLatitude() == 0.0
                || mAlohar.getPlaceManager().getCurrentLocation().getLongitude() == 0.0) {
            toastMessage(getString(R.string.nullocationErrorMessage));
            return;
        }

        JSONObject newData = new JSONObject();

        try {
            newData.put("DESC", desc);
            newData.put("LOCATION", getLatLongPosition());
            newData.put("DATE", DateFormat.getDateTimeInstance().format(new Date()));

        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        writeToFusionTable(manual, newData);

    }

    protected void writeToFusionTable(boolean manual, JSONObject timeNDescNLoc) {
        String Location;
        try {
            Location = timeNDescNLoc.getString("LOCATION");
        } catch (JSONException e1) {
            return;
        }

        if (Location.contains("0.0")) {
            toastMessage(getString(R.string.nullocationErrorMessage));
            return;
        }

        JSONObject newData = new JSONObject();

        String debugOrder = "";

        try {
            newData.put("DATE", timeNDescNLoc.getString("DATE"));
            newData.put("LOCATION", timeNDescNLoc.getString("LOCATION"));
            newData.put("DESC", timeNDescNLoc.getString("DESC"));

            /////////////////////////////////////////////////////////////
            //Additional data

            newData.put("MANUAL", manual);
            newData.put("STATIONARY", mMotionManager.isStationary());
            //newData.put("COMMUTE", mMotionManager.isOnCommute());   

            //TODO Second parameter (SD log on ERROR) should come from upper levels
            pushDataToFusionTable(newData, true);

        } catch (JSONException e) {
            // TODO Auto-generated catch block
            toastError("JSON error while formatting JSON data for query");
            return;
        }

    }

    private void pushDataToFusionTable(JSONObject data, boolean logOnError) throws JSONException {
        ArrayList<JSONObject> dataList = new ArrayList<JSONObject>();
        dataList.add(data);

        try {
            pushDataToFusionTable(dataList);

        } catch (HttpResponseException e) {
            if (e.getStatusCode() == 401) {
                mGOOGCredential.setAccessToken(null);

                SharedPreferences.Editor editor2 = mPrefs.edit();
                editor2.remove(PREF_REFRESH_TOKEN);
                editor2.commit();

                toastMessage("OAuth login required, redirecting...");

                //This last Constant is weird
                startActivityForResult(
                        new Intent().setClass(getApplicationContext(), OAuth2AccessTokenActivity.class),
                        REQUEST_OAUTH2_AUTHENTICATE);

            }

            if (logOnError) {
                toastMessage("Fusion table INSERT failed...attempt to CSV log...");

                //Here I have to generate an error CSV file corresponding to the missed row of data
                //I add a fine timestamp on the data to avoid threads locking (unique filename), worse case two rows of data
                //will contains the exact same date string.
                try {
                    data.put("ERROR_TIMESTAMP", new Date().getTime());
                } catch (JSONException e1) {
                    //Things went horribly horribly wrong, losing data for now
                    toastError("Error timestamp JSON write failed...dropping row :(");
                    return;
                }

                if (writeToSD_CSVError(data)) {
                    toastMessage("Happy dance ! -- Error CSV log succeded, remember to flush.");
                    //HAPPY DANCE !!
                } else {
                    //Things went horribly horribly wrong, losing data for now
                    toastError("Error CSV writing failed...dropping row :(");
                }
            } else {
                toastMessage("Fusion table INSERT failed and logOnError==false");
            }
        } catch (IOException e) {
            if (logOnError) {
                toastMessage("Fusion table INSERT failed...attempt to CSV log...");

                //Here I have to generate an error CSV file corresponding to the missed row of data
                //I add a fine timestamp on the data to avoid threads locking, worse case two rows of data
                //will contains the exact same date string.
                try {
                    data.put("ERROR_TIMESTAMP", new Date().getTime());
                } catch (JSONException e1) {
                    //Things went horribly horribly wrong, losing data for now
                    toastError("Error timestamp JSON write failed...dropping row :(");
                    return;
                }

                if (writeToSD_CSVError(data)) {
                    toastMessage("Happy dance ! -- Error CSV log succeded, remember to flush.");
                    //HAPPY DANCE !!
                } else {
                    //Things went horribly horribly wrong, losing data for now
                    toastError("Error CSV writing failed...dropping row :(");
                }
            } else {
                toastMessage("Fusion table INSERT failed and logOnError==false");
            }
        }
    }

    private void pushDataToFusionTable(ArrayList<JSONObject> dataList)
            throws JSONException, HttpResponseException, IOException {
        if (mViewOnMasterID == null) {
            toastMessage(getString(R.string.anonimizeRequired));
            return;
        }
        String SqlQuery = "";

        //Can I pass JSON around to input data into the table ? (Like in the request body or something)

        for (int i = 0; i < dataList.size(); ++i) {
            //SqlQuery += "INSERT INTO " + mFusionTableEncID + " (Date, Location, Manual, Description, IsStationary) VALUES ('"//fv#casseroles
            //TODO : the following request when table is registered, in addition to the one the personal table
            SqlQuery += "INSERT INTO " + mViewOnMasterID
                    + " (Date, Location, Manual, Description, IsStationary, RequestTableID) VALUES ('"//fv#casseroles

                    + dataList.get(i).getString("DATE") + "', '" + dataList.get(i).getString("LOCATION")//"45.5334 -73.5838"
                    + "', '" + dataList.get(i).getBoolean("MANUAL") + "', '" + dataList.get(i).getString("DESC")
                    + "', '" + dataList.get(i).getBoolean("STATIONARY") + "', '" + mRegisterRequestTableID
                    /*+ "', '"
                        + dataList.get(i).getBoolean("COMMUTE")*/
                    + "')";
            if (dataList.size() != 1) {
                SqlQuery += ";";
            }

        }

        String encodedQuery = URLEncoder.encode(SqlQuery, "UTF-8");

        GoogleUrl GUrl = new GoogleUrl(SERVICE_URL + "?sql=" + encodedQuery);//&access_token=" + credential.getAccessToken());

        try {

            HttpRequest request = mGOOGClient.getRequestFactory().buildPostRequest(GUrl, null);
            HttpHeaders headers = new HttpHeaders();

            headers.setContentLength("0");//Required so that Fusion Table API considers request
            request.setHeaders(headers);

            HttpResponse response = request.execute();

            if (response.getStatusCode() == 200) {
                toastMessage("Fusion table update request 200 OK :)--" + dataList.get(0).getString("DESC"));
                //Does nothing if nothing to flush
                flushErrorRows();
            }

        } catch (HttpResponseException e) {
            throw e;

        } catch (IOException e) {

            throw e;
        }

    }

    private boolean writeToSD_CSVError(JSONObject data) {
        File sdCard = getSDCardFile(true);//getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);

        if (sdCard == null)
            return false;

        File dir = new File(sdCard.getAbsolutePath() + "/" + getString(R.string.app_name) + "/OutputErrorLog");
        if (!dir.exists()) {
            dir.mkdirs();
        }

        String today;

        try {
            today = data.getString("DATE") + "_" + data.getLong("ERROR_TIMESTAMP");
        } catch (JSONException e1) {
            //Data contains no date or error timestamp, abort
            return false;
        } //DateFormat.getDateTimeInstance().format(new Date());

        String todayFileFormatted = today.replace(" ", "_").replace(",", "_").replace(":", "_");

        File fileCheck = getApplicationContext().getFileStreamPath(todayFileFormatted + "_ErrorRow.csv");
        if (fileCheck.exists()) {
            //This is an error, the file should be unique, but somebody came before us
            //Let's just restamp the error and try again

            try {
                data.put("ERROR_TIMESTAMP", new Date().getTime());
            } catch (JSONException e) {
                return false;
            }

            return writeToSD_CSVError(data);

        }
        //No else : all path lead to return

        File file = new File(dir, todayFileFormatted + "_ErrorRow.csv");
        //This creates the file if it doesn't already exists

        FileWriter writer = null;
        try {
            writer = new FileWriter(file, true);
        } catch (IOException e) {
            return false;
        }

        String toWrite = null;

        try {
            //////////////////////////////////////////////////////////////
            ///DATA DEFINITION
            toWrite = "\"" + data.getString("DATE") + "\"," + data.getString("LOCATION") + ","
                    + data.getBoolean("MANUAL") + "," + data.getString("DESC") + "," + data.getBoolean("STATIONARY")
                    + /*"," + data.getBoolean("COMMUTE") +*/ "\r\n";
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            return false;
        }

        try {
            writer.write("Date,Location,Manual,Description,IsStationary\r\n");
            //writer.write("Date,Location,Manual,Description,IsStationary,IsOnCommute\r\n");
            writer.write(toWrite);
            writer.flush();
            writer.close();
        } catch (IOException e) {
            return false;
        }

        return true;
    }

    private File getSDCardFile(boolean checkWriteAccess) {
        boolean externalStorageAvailable = false;
        boolean externalStorageWriteable = false;
        String state = Environment.getExternalStorageState();

        if (Environment.MEDIA_MOUNTED.equals(state)) {
            // We can read and write the media
            externalStorageAvailable = externalStorageWriteable = true;
        } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
            // We can only read the media
            externalStorageAvailable = true;
            externalStorageWriteable = false;
        } else {
            // Something else is wrong. It may be one of many other states, but all we need
            //  to know is we can neither read nor write
            externalStorageAvailable = externalStorageWriteable = false;
        }

        if (externalStorageAvailable == false)
            return null;
        else if (checkWriteAccess && !externalStorageWriteable)
            return null;
        else
            return getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);

    }

    /**
     * Toast toastMessage.
     *
     * @param message the message
     */
    public void toastMessage(final String message) {
        mMainHandler.post(new Runnable() {

            public void run() {
                Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();

            }
        });
    }

    private static final int MENU_FLUSH = 1;
    private static final int MENU_EXIT = 2;
    private static final int MENU_FLUSHSQL = 3;

    /* (non-Javadoc)
     * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
     */
    /*@Override
    public boolean onCreateOptionsMenu(Menu menu) {
       menu.add(0, MENU_FLUSH, 0, "flush");
       menu.add(0, MENU_EXIT, 0, "Exit");
       menu.add(0, MENU_FLUSHSQL, 0, "Flush SQL");
        
       return super.onCreateOptionsMenu(menu);
    }*/

    /* (non-Javadoc)
     * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case MENU_FLUSH:
            // try to trigger one post every 15 minutes
            mAlohar.flush();
            return true;
        case MENU_EXIT:
            mAlohar.stopServices();
            mAlohar.teardown();
            this.finish();
            return true;
        case MENU_FLUSHSQL:
            flushErrorRows();
            return true;

        }
        return super.onOptionsItemSelected(item);
    }

    private void flushErrorRows() {
        File sdCard = getSDCardFile(true);//getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
        String truc = sdCard.getAbsolutePath() + "/" + getString(R.string.app_name) + "/OutputErrorLog";
        File dir = new File(sdCard.getAbsolutePath() + "/" + getString(R.string.app_name) + "/OutputErrorLog");

        if (!dir.exists()) {
            return;
        }

        File[] errorFiles = dir.listFiles();

        if (errorFiles.length == 0) {
            //toastMessage("Nothing to flush");
            return;
        }

        final ArrayList<JSONObject> dataList = new ArrayList<JSONObject>();

        for (int i = 0; i < errorFiles.length; ++i)
        //I will create a big SQL query string containing every error rows separated by ;
        {
            FileInputStream fis;
            try {
                fis = new FileInputStream(errorFiles[i]);
                InputStreamReader inputStreamReader = new InputStreamReader(fis);
                BufferedReader bufferedStreamReader = new BufferedReader(inputStreamReader);
                CSVReader reader = new CSVReader(bufferedStreamReader);

                // The first line is the column names, and the remaining lines are the rows.
                List<String[]> csvLines;

                csvLines = reader.readAll();
                //List<String> columns = Arrays.asList(csvLines.get(0));
                List<String[]> rows = csvLines.subList(1, csvLines.size());
                //rows length should be 1 : 1 line of data

                //Let's construct a JSONObject from the second line
                JSONObject data = new JSONObject();

                /////////////////////////////////////////////
                //DATA Definition
                data.put("DATE", rows.get(0)[0]);
                data.put("LOCATION", rows.get(0)[1]);

                data.put("MANUAL", rows.get(0)[2]);
                data.put("DESC", rows.get(0)[3]);
                data.put("STATIONARY", rows.get(0)[4]);
                //data.put("COMMUTE", rows.get(0)[5]);

                dataList.add(data);

            } catch (FileNotFoundException e1) {
                //That should never happen
                toastError("Can't flush SQL CSV error files");
                return;

            } catch (IOException e) {
                toastError("Can't flush SQL CSV error files");
                return;
            } catch (JSONException e) {
                toastError("Can't flush SQL CSV error files");
                return;
            }

        }

        new Thread((new Runnable() {

            public void run() {
                try {
                    pushDataToFusionTable(dataList);
                } catch (HttpResponseException e) {
                    if (e.getStatusCode() == 401) {
                        mGOOGCredential.setAccessToken(null);

                        SharedPreferences.Editor editor2 = mPrefs.edit();
                        editor2.remove(PREF_REFRESH_TOKEN);
                        editor2.commit();
                        //accountName = null;

                        toastMessage("OAuth login required, please reflush afterwards... redirecting...");

                        startActivityForResult(
                                new Intent().setClass(getApplicationContext(), OAuth2AccessTokenActivity.class),
                                REQUEST_OAUTH2_AUTHENTICATE);
                        return;
                    }
                } catch (JSONException e) {
                    toastError("Can't flush SQL CSV error files");
                    return;
                } catch (IOException e) {
                    toastError("Can't flush SQL CSV error files");
                    return;
                }

                //if I get there everything went fine with my request, so I can delete files
                //NOT THREAD SAFE, multiple button clics could lead to nightmare
                //File sdCard = Environment.getExternalStorageDirectory();
                File sdCard = getSDCardFile(true);//getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);

                File dir = new File(
                        sdCard.getAbsolutePath() + "/" + getString(R.string.app_name) + "/OutputErrorLog");
                if (!dir.exists()) {
                    return;
                }

                File[] errorFiles = dir.listFiles();
                //Reenable button in interface to prevent multiple threads trying to delete files
                for (int i = 0; i < errorFiles.length; ++i)
                //I will create a big string containing every error rows separated by ;
                {
                    errorFiles[i].delete();
                    //Could return false
                }

                toastMessage("SQL flushing successfull " + errorFiles.length + " row(s) uploaded");
            }
        })).start();

    }

    private void cancelActiveTasks() {
        //mLocPollFrq2
        if (mLocPollFrq0 != null) {
            mLocPollFrq0.cancel(true);
            mLocPollFrq0 = null;
        } else if (mLocPollFrq1 != null) {
            mLocPollFrq1.cancel(true);
            mLocPollFrq1 = null;
        } else if (mLocPollFrq2 != null) {
            mLocPollFrq2.cancel(true);
            mLocPollFrq2 = null;
        } else if (mLocPollFrq3 != null) {
            mLocPollFrq3.cancel(true);
            mLocPollFrq3 = null;
        }
    }

    private void startTaskForId(int radioButtonID, final boolean manual) {

        String eventDescTemp = "";

        //Will do for now, insure only one task at a time, we could have overlap if wanted later on
        cancelActiveTasks();

        final JSONObject newData = new JSONObject(); //Just a convenient map ?

        try {

            newData.put("DESC", "Scheduled poll");
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        //That should be a switch
        if (radioButtonID == R.id.frequency0) {
            try {
                //Retrieve status message from ui in one function only
                newData.put("DESC", "Scheduled status update. UI says : "
                        + ((EditText) findViewById(R.id.statusText)).getText().toString());
            } catch (JSONException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }

            eventDescTemp = "frequency -- now: 10min";

            //Threaded
            mLocPollFrq0 = mLocationPollThreadExecutor.scheduleAtFixedRate(new Runnable() {
                public void run() {
                    try {
                        newData.put("DATE", DateFormat.getDateTimeInstance().format(new Date()));
                        newData.put("LOCATION", getLatLongPosition());
                    } catch (JSONException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    //Threaded : httpTransport is Thread safe, hence concurrent access to the web should be handled
                    writeToFusionTable(false, newData);
                }
            },
                    //60000, 60000, TimeUnit.MILLISECONDS);            
                    10, 10, TimeUnit.MINUTES);
        } else if (radioButtonID == R.id.frequency1) {
            try {
                //Retrieve status message from ui in one function only
                newData.put("DESC", "Scheduled status update. UI says : "
                        + ((EditText) findViewById(R.id.statusText)).getText().toString());
            } catch (JSONException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }

            eventDescTemp = "frequency -- now: 5min";

            //Threaded
            mLocPollFrq1 = mLocationPollThreadExecutor.scheduleAtFixedRate(new Runnable() {
                public void run() {
                    try {
                        newData.put("DATE", DateFormat.getDateTimeInstance().format(new Date()));
                        newData.put("LOCATION", getLatLongPosition());
                    } catch (JSONException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    //Threaded : httpTransport is Thread safe, hence concurrent access to the web should be handled
                    writeToFusionTable(false, newData);
                }
            },
                    //30000, 30000, TimeUnit.MILLISECONDS);                                
                    5, 5, TimeUnit.MINUTES);
        } else if (radioButtonID == R.id.frequency2) {
            try {
                //Retrieve status message from ui in one function only
                newData.put("DESC", "Scheduled status update. UI says : "
                        + ((EditText) findViewById(R.id.statusText)).getText().toString());
            } catch (JSONException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            eventDescTemp = "frequency -- now: 3mins";

            //Threaded
            mLocPollFrq2 = mLocationPollThreadExecutor.scheduleAtFixedRate(new Runnable() {
                public void run() {
                    try {
                        newData.put("DATE", DateFormat.getDateTimeInstance().format(new Date()));
                        newData.put("LOCATION", getLatLongPosition());
                    } catch (JSONException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                    //Threaded : httpTransport is Thread safe, hence concurrent access to the web should be handled
                    writeToFusionTable(false, newData);
                }
            },
                    //15000, 15000, TimeUnit.MILLISECONDS);                                
                    3, 3, TimeUnit.MINUTES);
        } else if (radioButtonID == R.id.frequency3) {
            try {
                //Retrieve status message from ui in one function only
                newData.put("DESC", "Scheduled status update. UI says : "
                        + ((EditText) findViewById(R.id.statusText)).getText().toString());
            } catch (JSONException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }

            eventDescTemp = "frequency -- now: 1min";

            //Threaded
            mLocPollFrq3 = mLocationPollThreadExecutor.scheduleAtFixedRate(new Runnable() {
                public void run() {
                    try {
                        newData.put("DATE", DateFormat.getDateTimeInstance().format(new Date()));
                        newData.put("LOCATION", getLatLongPosition());
                    } catch (JSONException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    //Threaded : httpTransport is Thread safe, hence concurrent access to the web should be handled
                    writeToFusionTable(false, newData);
                }
            },
                    //5000, 5000, TimeUnit.MILLISECONDS);                                
                    1, 1, TimeUnit.MINUTES);
        }

        final String eventDesc = eventDescTemp;

        //This is to thread the input of the changing frequency message, that's why tasks are delayed by their frequency
        new Thread((new Runnable() {

            public void run() {

                //Threaded : httpTransport is Thread safe, hence concurrent access to the web should be handled
                writeToFusionTable(manual, eventDesc);

            }
        })).start();

    }

    private String getLatLongPosition() {
        //Attempt to align values in CSV file but that failed
        //DecimalFormat df = new DecimalFormat("#.###############");

        //return df.format(mPlaceManager.getCurrentLocation().getLatitude()) + " " + df.format(mPlaceManager.getCurrentLocation().getLongitude());
        return mPlaceManager.getCurrentLocation().getLatitude() + " "
                + mPlaceManager.getCurrentLocation().getLongitude();
    }

    /**
     * Toast error.
     *
     * @param message the message
     */
    public void toastError(final String message) {
        mMainHandler.post(new Runnable() {

            public void run() {
                Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
                mAloharAuthLayout.setVisibility(View.VISIBLE);
                mMainLayout.setVisibility(View.GONE);
                mProgress.setVisibility(View.GONE);
            }
        });
    }

    /* (non-Javadoc)
     * @see com.alohar.user.callback.ALEventListener#handleEvent(com.alohar.user.content.data.ALEvents, java.lang.Object)
     */
    public void handleEvent(ALEvents event, Object data) {
        if (event == ALEvents.AUTHENTICATE_CALLBACK || event == ALEvents.REGISTRATION_CALLBACK) {
            if (data instanceof String) {
                mAloharUid = (String) data;
                Log.i("CobraDemo", "######UID=" + mAloharUid);
                //SharedPreferences prefs = getSharedPreferences(PREF_NAME,MODE_PRIVATE);//PreferenceManager.getDefaultSharedPreferences(this);
                mPrefs.edit().putString(PREF_KEY, mAloharUid).commit();
            }

            //alohar service is ready to start
            mMainHandler.post(new Runnable() {

                public void run() {
                    //switch to main layout
                    mAloharAuthLayout.setVisibility(View.GONE);
                    mMainLayout.setVisibility(View.VISIBLE);
                    mProgress.setVisibility(View.GONE);
                    mAccountView.setText(mAloharUid);
                }
            });
        } else if (event == ALEvents.GENERAL_ERROR_CALLBACK || event == ALEvents.SERVER_ERROR_CALLBACK) {
            toastError((String) data);
        }
    }
}