jueves, 23 de febrero de 2012

Geeksphone. Smartphone ibérico.

Escribo esta entrada para hacer un poquito de patria.

La empresa Geekphone es una empresa española que se dedica a hacer smarphones que usan sistema operativo Android y que no desmerecen a los que hay en el mercado y que está muy bien de precio.

 Yoigo me ha "regalado" un Android Samsung mini que está muy bien, pero me hubiera hecho más ilusión que me regalaran un Geekphone ZERO. En fin, por ahora por lo que veo en la web de Geekphone, solo Pepephone ofrece el dispositivo.



A ver si cunde el ejemplo en otros operadores que operan en España.

En Xataka hacen un análisis del dispositivo.

  GeeksPhone Zero, análisis (I)
  GeeksPhone Zero, análisis (II)

Actualización:

Veo que además Javier Agüera, que parece ser es el creador de esta empresa, de 19 años!!!!!, ha sido galardonado con el Premio TR35 que el Massachussets Institute Technology (MIT) concede a jóvenes emprendedores menores de 35 años. Simplemente impresionante. Aquí dejo el enlace a la noticia

 Un emprendedor de 19 años gana el TR35 del MIT


Además están a punto de sacar al mercado el Geeksphone TWO.

Primera Aplicación. Parte 4. Localización GPS

Queda para terminar la aplicación, actuar con el dispositivo GPS para obtener la localización del dispositivo móvil. Para ello, se implementa el interfaz android.location.LocationListener, que escucha cambios de localización del dispositivo. Para ello se crea la clase GpsLocationListener, que en un cambio de localización, consulta a la base de datos para saber si existen radares en las inmediaciones del dispositivo, y en caso de encontrar entradas para esas coordenadas, se avisa al conductor mediante un sonido y con un mensaje de aviso, mediante la clase android.widget.Toast
public class GpsLocationListener implements LocationListener {
Se sobreescribe el método onLocationChanged;
 public void onLocationChanged(Location location) {
  
  if (location != null) {
   Log.d("LOCATION CHANGED LATITUDE", location.getLatitude() + "");
   Log.d("LOCATION CHANGED LONGITUDE", location.getLongitude() + "");
   
   dLatitude = location.getLatitude();
   dLongitude = location.getLongitude();

   cursorRadarsByLocation = db.selectRadarsByLocation(location);
   cursorRadarsByLocation.moveToFirst();
      
            while (!cursorRadarsByLocation.isAfterLast()){          
             Location radarLocation = new Location(location);
             radarLocation.setLatitude(cursorRadarsByLocation.getDouble(0));
             radarLocation.setLongitude(cursorRadarsByLocation.getDouble(1));
             
Log.v("GpsLocationListener", "RadarDB: " + radarLocation.getLatitude() + " lon " +radarLocation.getLongitude() + " GPS: " + location.getLatitude() +":" + location.getLongitude() + " : Distance: " + radarLocation.distanceTo(location));

    if(radarLocation.distanceTo(location)<500){
Log.v("GpsLocationListener", "RADAR! la:" + location.getLatitude() + " lo:" + location.getLongitude());    
        
     View layout = inflater.inflate(R.layout.toast_layout, null);
     
     ImageView image = (ImageView) layout.findViewById(R.id.image);
     image.setImageResource(R.drawable.radar);
     TextView text = (TextView) layout.findViewById(R.id.text);
     text.setText("RADAR! la:" + location.getLatitude() + " lo:" + location.getLongitude());
     
     Toast toast = new Toast(context.getApplicationContext());
     toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
     toast.setDuration(Toast.LENGTH_LONG);
     toast.setView(layout);
     toast.show();


        sm.playSound(2);
             }
    cursorRadarsByLocation.moveToNext();
            }
  }
 }

En este método, se almacenan las coordenadas de la nueva localización y se realiza una consulta a la base de datos mediante una llamada al método selectRadarsByLocation. En caso de encontrar radares en las inmediaciones, se verifica que el radar se encuentre en las inmendiaciones mediante el método distanceTo de la clase Location, y en caso de cumplir la condición, se avisa al usuario mediante una imagen y un sonido. Para crear un componente que Toast con una imagen y un texto, se crea el layout toast_layout.xml y se almacena en "res/layout"
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/toast_layout_root"
              android:orientation="horizontal"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:padding="10dp"
              android:background="#DAAA"
              >
    <ImageView android:id="@+id/image"
               android:layout_width="wrap_content"
               android:layout_height="fill_parent"
               android:layout_marginRight="10dp"
               />
    <TextView android:id="@+id/text"
              android:layout_width="wrap_content"
              android:layout_height="fill_parent"
              android:textColor="#FFF"
              />
</LinearLayout>

Este layout esta compuesto por una imagen ImageView identificado por "@+id/image" y un texto TextView identificado por "@+id/text". Posteriormente, en el método onLocationChanged se recuperan estas vistas mediante sus identificadores R.id.image y R.id.text. Este layout se asigna a la vista del objeto toast y se muestra llamando a su método show.
View layout = inflater.inflate(R.layout.toast_layout, null);
     
     ImageView image = (ImageView) layout.findViewById(R.id.image);
     image.setImageResource(R.drawable.radar);
     TextView text = (TextView) layout.findViewById(R.id.text);
     text.setText("RADAR! la:" + location.getLatitude() + " lo:" + location.getLongitude());
     
     Toast toast = new Toast(context.getApplicationContext());
     toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
     toast.setDuration(Toast.LENGTH_LONG);
     toast.setView(layout);
     toast.show();
Posteriormente se llama al manager de sonido mediante una clase SoundManager sm, que se ha implementado previamente
package com.m607.sound;

import java.util.HashMap;

import android.content.Context;
import android.media.AudioManager;
import android.media.SoundPool;
import android.util.Log;



public class SoundManager {
 
 private  SoundPool spSoundPool; 
 private  HashMap<Integer, Integer> hmSoundPoolMap; 
 private  AudioManager  amAudioManager;
 private  Context context;
 
 
 public SoundManager()
 {
  
 }
  
 public void initSounds(Context theContext) { 
   context = theContext;
      spSoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 0); 
      hmSoundPoolMap = new HashMap<Integer, Integer>(); 
      amAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);       
 } 
 
 public void addSound(int Index,int SoundID)
 {
  hmSoundPoolMap.put(Index, spSoundPool.load(context, SoundID, 1));
 }
 
 public void playSound(int index) { 
      int streamVolume = amAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); 
      spSoundPool.play(hmSoundPoolMap.get(index), streamVolume, streamVolume, 1, 0, 1f); 
 }
 
 public void playLoopedSound(int index) { 
  
      int streamVolume = amAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); 
      spSoundPool.play(hmSoundPoolMap.get(index), streamVolume, streamVolume, 1, -1, 1f); 
 }
}
Esta clase se instancia en la clase en el Service principal, de la siguiente manera
     sm = new SoundManager();
     sm.initSounds(getBaseContext());
     sm.addSound(1, R.raw.sound);
     sm.addSound(2, R.raw.beep4);
     sm.addSound(3, R.raw.beep9);
     
Los sonidos, como las imágenes, se han almacenado en res/raw y se recuperan como se muestra en el trozo de código anterior.