rpi.rpiface.VoteActivity.java Source code

Java tutorial

Introduction

Here is the source code for rpi.rpiface.VoteActivity.java

Source

package rpi.rpiface;

import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

/**
 * Copyright (C) 2013 Javier Garca, Julio Alberto Gonzlez
 * <p>
 * This file is part of Rpi-Face. Rpi-Face 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.
 * <p>
 * Rpi-Face 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.
 * <p>
 * You should have received a copy of the GNU General Public License along with
 * Rpi-Face. If not, see <http://www.gnu.org/licenses/>.
 * <p>
 * <p>
 * Esta clase se encarga de realizar las votaciones al servidor
 * 
 * @author Francisco Javier Garca Gmez y Julio Alberto Gonzlez Marn
 * @version 1.0
 * @since 2013-03-26
 * 
 */

public class VoteActivity extends Activity implements OnClickListener {

    /**
     * Etiqueta para el log
     */
    private static final String LOGTAG = SpeakFaceActivity.class.getCanonicalName();
    /**
     * Parmetro usado en la peticin post
     */
    private static final String RPI_PARAM = "vote";
    /**
     * Nombre de la variable para obtener el recuento de votos
     */
    private static final String KEY_QUERY = "query";
    /**
     * Valor de la variable para obtener el recuento de votos
     */
    private static final String VALUE_VOTECOUNT = "votecount";
    /**
     * Nombre de la variable que guarda el nmero de votos positivos en cambios
     * de estado
     */
    private static final String VOTE_STATE_PLUS = "rpi.rpiface.vote.plus";
    /**
     * Nombre de la variable que guarda el nmero de votos negativos en cambios
     * de estado
     */
    private static final String VOTE_STATE_MINUS = "rpi.rpiface.vote.minus";
    /**
     * Botn para votar positivo
     */
    private Button botonYes;
    /**
     * Botn para votar negativo
     */
    private Button botonNo;
    /**
     * Preferencias del usuario
     */
    private SharedPreferences preferences;
    private int plus = 0;
    private int minus = 0;

    /**
     * Crea la actividad
     * 
     * @param savedInstanceState
     * */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_vote);
        botonYes = (Button) findViewById(R.id.button_yes);
        botonNo = (Button) findViewById(R.id.button_no);
        botonYes.setOnClickListener(this);
        botonNo.setOnClickListener(this);
        preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        restoreState(savedInstanceState, preferences);
    }

    /**
     * Recupera el recuento de votos si la actividad se est recuperando de un
     * cambio de estado, o lo obtiene del servidor si la actividad se est
     * creando.
     * 
     * @param savedInstanceState
     *            Estado guardado de la actividad, o <b>null</b> si la actividad
     *            se est creando.
     * @param preferences
     *            Preferencias de la aplicacin.
     */
    private void restoreState(Bundle savedInstanceState, SharedPreferences preferences) {
        if (savedInstanceState == null) {
            updateVoteCount(preferences);
            return;
        }
        if (savedInstanceState.containsKey(VOTE_STATE_PLUS) && savedInstanceState.containsKey(VOTE_STATE_MINUS)) {
            botonYes.setText(savedInstanceState.getInt(VOTE_STATE_PLUS, 0));
            botonNo.setText(savedInstanceState.getInt(VOTE_STATE_MINUS, 0));
        } else {
            updateVoteCount(preferences);
        }
    }

    /**
     * Guarda el recuento de votos en los cambios de estado.
     * 
     * @param outState
     *            Estructura donde se guardarn los valores.
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        outState.putInt(VOTE_STATE_PLUS, plus);
        outState.putInt(VOTE_STATE_MINUS, minus);
    }

    /**
     * Actualiza y muestra el recuento de votos
     * 
     * @param preferences
     *            Preferencias de la aplicacin
     */
    private void updateVoteCount(SharedPreferences preferences) {
        String rpi = preferences.getString(PreferencesActivity.PREFS_URL, Url.RPI);
        String rpiPort = preferences.getString(PreferencesActivity.PREFS_PORT, Url.RPI_PORT);
        String rpiPath = preferences.getString(PreferencesActivity.PREFS_PATH, Url.RPI_PATH);
        new GetVoteCount(getApplicationContext()).execute(VALUE_VOTECOUNT, rpi, rpiPort, rpiPath, KEY_QUERY);
    }

    /**
     * Cdigo que se ejecuta cuando se hace click en un objeto con detector
     * 
     * @param v
     *            Objeto sobre el cual se ha hecho click
     */
    public void onClick(View v) {

        switch (v.getId()) {
        case R.id.button_yes:
            Log.v(LOGTAG, "Se ha pulsado en el botn positivo");
            doPost(true);
            break;
        case R.id.button_no:
            Log.v(LOGTAG, "Se ha pulsado en el botn negativo");
            doPost(false);
            break;

        default:
            Toast.makeText(getApplicationContext(), "Error, esa opcin no est implementada", Toast.LENGTH_SHORT)
                    .show();
            break;
        }

    }

    /**
     * Cdigo que se encarga de establecer los parmetros de la peticin post
     * 
     * @param vote
     *            Si es 1 es un voto positivo, si es 0 es un voto negativo
     */
    private void doPost(boolean vote) {

        String rpi = preferences.getString(PreferencesActivity.PREFS_URL, Url.RPI);
        String rpiPort = preferences.getString(PreferencesActivity.PREFS_PORT, Url.RPI_PORT);
        String rpiPath = preferences.getString(PreferencesActivity.PREFS_PATH, Url.RPI_PATH);
        Log.v(LOGTAG + " Voto a enviar:", vote ? "Positivo" : "Negativo");
        // Se crea un postAsynctask que har la peticin post al servidor
        PostVote postVote = new PostVote(getApplicationContext());
        // Se ejecuta el asynctask pasndole los parmetros correspondientes
        postVote.execute(vote ? "1" : "0", rpi, rpiPort, rpiPath, RPI_PARAM);
    }

    /**
     * Se ejecuta cada vez que se llama al men estando en la actividad
     * 
     * @param menu
     */
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_menu, menu);
        return true;
    }

    /**
     * Se ejecuta cuando se pulsa un botn del menu
     * 
     * @param item
     */
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_settings:
            Intent intentPrefs = new Intent(this, PreferencesActivity.class);
            startActivity(intentPrefs);
            return true;
        case R.id.menu_exit:
            finish();
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    /**
     * Obtiene asncronamente el recuento de votos
     * 
     * @author Francisco Javier Garca Gmez y Julio Alberto Gonzlez Marn
     * @version 1.0
     * @since 2013-04-01
     */
    private class GetVoteCount extends AsyncTask<String, Void, Boolean> {
        /**
         * Contexto de la aplicacin
         */
        private Context context;

        /**
         * Crea un nuevo GetAsyncTask.
         * 
         * @param context
         *            Contexto de la aplicacin.
         */
        public GetVoteCount(Context context) {
            this.context = context;
        }

        /**
         * Se ejecuta al principio
         */
        protected void onPreExecute() {
            Log.i(LOGTAG + " Asynctask", "Async iniciada");
        }

        /**
         * Se ejecuta en paralelo sin bloquear el sistema
         * 
         * @param param
         *            Array de parmetros: el primero se corresponde con el
         *            movimiento a realizar, el segundo con la direccin, el
         *            tercero con el puerto y el cuarto con el path
         */
        protected Boolean doInBackground(String... param) {
            // Se asignan variables a los parmetros del asynctask
            String value = param[0];
            String rpi = param[1];
            String port = param[2];
            String rpiPath = param[3];
            String rpiParam = param[4];
            // Se crea un cliente http
            HttpClient httpClient = new DefaultHttpClient();
            // Se crea una lista con los parmetros
            List<NameValuePair> params = new LinkedList<NameValuePair>();
            params.add(new BasicNameValuePair(rpiParam, value));
            // Se pasa la lista a un string debidamente formateado
            String paramString = URLEncodedUtils.format(params, "iso-8859-15");
            // Se crea la url
            String url = rpi + ":" + port + rpiPath + "?" + paramString;
            Log.i(LOGTAG + " Asynctask" + " Http get:", url);
            // Se crea un objeto httpget
            HttpGet httpGet = new HttpGet(url);
            HttpResponse response = null;
            try {
                // Se ejecuta el cliente pasndole como parmetro la peticin
                // get.
                response = httpClient.execute(httpGet);
                Log.i(LOGTAG + " Asynctask" + " Http Response:", response.toString());
            } catch (ClientProtocolException e) {
                Log.i(LOGTAG + " Asynctask" + " Http Response:", "Error en el protocolo http");
                e.printStackTrace();
                return false;
            } catch (IOException e) {
                Log.i(LOGTAG + " Asynctask" + " Http Response:",
                        "Conexin abortada. No se pudo contactar con el servidor");
                e.printStackTrace();
                return false;
            }
            Scanner count;
            try {
                count = new Scanner(response.getEntity().getContent());
                plus = count.nextInt();
                minus = count.nextInt();
                count.close();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return true;

        }

        /**
         * Se ejecuta al final
         * 
         * @param result
         *            Resultado de la tarea en segundo plano
         */
        protected void onPostExecute(Boolean result) {
            Log.i(LOGTAG + " Asynctask", "Async terminada");
            if (!result) {
                Toast.makeText(context, "Hubo problemas con el servidor. Reintntelo ms tarde.",
                        Toast.LENGTH_SHORT).show();
            } else {
                botonYes.setText("S (" + plus + ")");
                botonNo.setText("No (" + minus + ")");
            }
        }

    }

    /**
     * Enva un voto al servidor.
     * 
     * @author Francisco Javier Garca Gmez y Julio Alberto Gonzlez Marn
     * @version 1.0
     * @since 2013-04-01
     */
    public class PostVote extends AsyncTask<String, Void, Boolean> {
        /**
         * Contexto de la aplicacin
         */
        private Context context;

        /**
         * Crea un nuevo PostAsyncTask.
         * 
         * @param context
         *            Contexto de la aplicacin.
         */
        public PostVote(Context context) {
            this.context = context;
        }

        /**
         * Se ejecuta al principio
         */
        protected void onPreExecute() {
            Log.i(LOGTAG + " Asynctask", "Async iniciada");
        }

        /**
         * Se ejecuta en paralelo sin bloquear el sistema
         * 
         * @param param
         *            Array de parmetros: el primero se corresponde con el
         *            texto a envir, el segundo con la direccin, el tercero con
         *            el puerto y el cuarto con el path
         */
        protected Boolean doInBackground(String... param) {
            // Se asignan variables a los parmetros del asynctask
            String value = param[0];
            String rpi = param[1];
            String port = param[2];
            String rpiPath = param[3];
            String rpiParam = param[4];
            // Se crea un cliente http
            HttpClient httpClient = new DefaultHttpClient();
            // Se crea la url
            String url = rpi + ":" + port + rpiPath;
            // Se crea un objeto httpPost
            HttpPost httpPost = new HttpPost(url);
            // Se crea una lista con los parmetros
            List<NameValuePair> params = new LinkedList<NameValuePair>();
            params.add(new BasicNameValuePair(rpiParam, value));

            // String paramString = URLEncodedUtils.format(params,
            // "iso-8859-15");
            Log.i(LOGTAG + " Asynctask" + " Http get:", url);

            try {
                // Se le pasan los parmetros debidamente formateados al
                // httpPost
                httpPost.setEntity(new UrlEncodedFormEntity(params, "iso-8859-15"));
                // Se ejecuta el cliente pasndole como parmetro la peticin
                // post.
                HttpResponse response = httpClient.execute(httpPost);
                Log.i(LOGTAG + " Asynctask" + " Http Response:", response.toString());
            } catch (ClientProtocolException e) {
                e.printStackTrace();
                return false;
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
            return true;
        }

        /**
         * Se ejecuta al final
         * 
         * @param result
         *            Resultado de la tarea en segundo plano.
         */
        protected void onPostExecute(Boolean result) {
            Log.i(LOGTAG + " Asynctask", "Async terminada");
            if (!result) {
                Toast.makeText(context, "Hubo problemas con el servidor. Reintntelo ms tarde.",
                        Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(context, "Enviado correctamente.", Toast.LENGTH_SHORT).show();
                updateVoteCount(preferences);
            }
        }

    }
}