Curl Pink Linux

Hola de nuevo a todos, el día de hoy vamos a continuar con la celebracion por las primeras 10000 visitas y para eso, vamos a ver un poco de linux, mas concretamente una distribucion hecha por el mismisimo dueño del blog Curl Pink. Recuerda visitar su blog, ahi encontraras muchas cosas sobre linux y Gentoo.

Curl Pink Linux.

Descripción.


Curl Pink Linux es una distribución muy minimalista basada en OpenSUSE. Está pensada para servir de base de una distribución futura para el Rasberry Pi y al mismo tiempo como una distribución que usa Awesome como entorno de escritorio.
Su inicio desde el LiveDVD en VirtualBox es más rápido que el de otras live-distros y puede servir para tener un OpenSUSE ultra ligero. Ahora que Curl Pink Linux existe, gracias a su simplicidad, ya no me interesa Arch Linux.

Nota: Aun no está disponible el instalador

Programas.

Fui muy estricta con la selección de programas de forma que solo incluí los programas que eran absolutamente necesarios. También incluí Libreoffice -así como Abiword-, que por lo general no están incluidos en distribuciones minimalistas, y también incluí a firefox con algunas extensiones, y finalmente dos programas especiales.

Programas especiales:

Laverna:

Laverna es un programa para tomar notas como Tomboy o Gnote, pero más avanzado y portable. Lo incluí a modo de demostración en mi sitio. Pero las notas no se guardan en mi servidor, sino que se guardan en tu computadora. Es de código abierto.

Encripta tus notas y puedes guardarlas en tu servidor favorito y sincronizarlas en todos tus dispositivos. Sobre el server, puedes hacer el tuyo, yo hice el mío basado en Gentoo (Por cierto, Gentoo no es la distribución más sencilla para hacer esto)

Tor-browser:

En la era post-Snowden es importante controlar la información personal. Así que Tor también está incluido y en un futuro lanzamiento  torify puede ser usado para ejecutar cualquier comando dentro de la red Tor. Por ejemplo

torify wget curl.pink/gentoo.tar

Programas por categorias.

Accesorios.

Gentoo es un gestionador de archivos muy minimalista incluso más que SpaceFM, también PcmanFM está incluido.

Programación.

Juegos

Incluí tres juegos de lógica e inteligencia muy ligeros, divertidos y quizá adictivos, puedes jugar ajedrez con la consola utilizando el comando gnuchess y también está xbomb para jugar al buscaminas

Gráficos
Feh es más una utilidad de cli, por lo tanto es la opción más ligera para visualizar imágenes.

Internet

Multimedia:
Sonata estará listo out-of-the-box en futuras versiones de la distro, mientras tanto vás a tener que configurar mpd

Oficina

Otros

Firefox


Firefox incluye estas extensiones:

browsec VPN: Ayuda a evitar rastreos.
Ublock: bloquea la publicidad.
No Script: desactivar javascripts en sitios que no son confiables.

Utilidades de consola:



  • imagemagick (convert)
  • screenfetch
  • mplayer
  • mpd & ncmpcpp (música)
  • moc (música)
  • midnight commander (archivos)
  • youtube-dl
  • openssh
  • transmission (torrents)
  • irssi
  • finch (pidgin ncurses interface)
  • kernel sources
  • bc
  • lvm
  • mdraid
  • iw
  • alien (Convierte debs en rpm)
  • dpkg
  • fortune
  • iputils
  • nmap
  • cowsay
  • ponysay
  • testdisk
  • net-tools
  • zerofree
  • gnome-screenshot
  • scrot

Aqui está la lista exacta de comandos disponibles: http://curl.pink/paste/25

Windows Key + F1: Combinaciones de teclas de Awesome.

Y bien, por ahora es todo, el post original está en el blog de Curl pink, para que puedas usar está distribucion, necesitas un PC de 64 bits (y de ahi el mínimo). El ISO lo puedes descargar de aqui (md5: dee746e61d83dbdf7adf6ec83f2b616a). No dudes en probarlo.

Los leo luego.

Vamos a encriptar #2 - El cifrado de Vigenère

Hola de nuevo a todos, el día de hoya vamos a continuar con la celebración por las 10000 visitas que ha recibido el blog, y para ello vamos a ver un poco de lo que en un inicio fue la causa de abrir este blog.


 Cómo recordaras, uno de los primeros fue: "¿Un acertijo, Por qué no?", el reto fue resuelto no hace mucho. La persona que logro descifrarlo ahora tiene su lugar en el salon de la fama. Para continuar con el tema de encriptacion, hoy vamos a ver uno de los métodos de cifrado más sencillo (y funcional) a mi gusto.

El cifrado de Vigenere.

Para empezar, ¿que es el cifrado de Vigenere? Bien, se puede resumir de la siguiente manera:
El cifrado Vigenère es un cifrado basado en diferentes series de caracteres o letras del cifrado César formando estos caracteres una tabla, llamada tabla de Vigenère, que se usa como clave. El cifrado de Vigenère es un cifrado de sustitución simple polialfabético.
El cifrado Vigenère se ha reinventado muchas veces. El método original fue descrito por Giovan Battista Belasso en su libro de 1553 La cifra del Sig. Giovan Battista Belasso. Sin embargo, fue incorrectamente atribuido más tarde a Blaise de Vigenère, concretamente en el siglo XIX, y por ello aún se le conoce como el "cifrado Vigenère".
Wikipedia/Cifrado de Vigenere.

Cómo cifrar.

Antes que nada vamos a revisar un par de puntos importantes. Para empezar con el cifrado de Vigenere, debemos hacer uso del cifrado A1Z27. El cifrado A1Z27  consiste en asignar un valor numerico a cada letra del alfabeto, pero hay que recordar que; dependiendo del idioma; este tiene más o menos letras. Si se usa el alfabeto en inglés, tendriamos algo cómo lo siguiente

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26


Cómo notarás, si le asignamos el valor de 1 a "A" 2 a "B" y asi sucesivamente hasta "Z" tendremos una numeracion que solo llega hasta 26.
En el alfabeto en español hay que tener en cuenta que hay una letra más. La letra "Ñ" que no siempre se toma en cuenta en el alfabeto inglés. Si numeramos otra vez pero tomando en cuenta la letra "Ñ" tendremos algo como lo que sigue:

A B C D E F G H I J K L M N Ñ O P Q R S T U V W X Y Z
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

Siempre será necesario saber el idioma original para hacer los ajustes necesarios pero para fines practicos, en todos los ejemplo que te encuentres en este blog, siempre se usará el alfabeto en español (A1Z27).
Una vez aclarado lo anterior, empecemos con lo que sería el método para encriptar usando el cifrado de Vigenere.

Supongamos que queremos enviar de forma el siguiente mesaje: HelloWorld. Siempre debemos de usar una contraseña para este caso voy a usar "USG" (pero puede ser cualquier frase/palabra).
Usando el método A1Z27 procedemos a asignar el valor a cada letra de la contraseña:

  • U = 22.
  • S = 20.
  • G = 7.
Luego a cada palabra de la frase a encriptar, también le asignamos el valor correspondiente a cada letra:

  • H = 8.
  • E = 5.
  • L = 12.
  • L = 12.
  • O = 16.
  • W = 24.
  • O = 16.
  • R =  19.
  • L = 12.
  • D = 4.
Ahora procedemos a "sumar" las letras, la primer letra de la contraseña, se le sumara a la primer letra de la frase a encriptar, la segunda con la segunda y asi sucesicamente, si la frase o la contraseña tiene menor numero de letras que la otra, repetiremos desde el inicio, en el ejemplo quedaría de la siguiente manera:

  • H + U (8 + 22 = 30)
  • E + S (5 + 20 = 25)
  • L + G (12 + 7 = 19)
  • L + U (12 + 22 = 34)
  • O + S (16 + 20 = 36)
  • W + G (24 + 7 = 31)
  • O + U (16 + 22 = 38)
  • R + S (19 + 20 = 39)
  • L + G (12 + 7 = 19)
  • D + U (4 + 22 = 26)
Para obtener el resultado, debemos de obtener el residual del numero que nos resulto entre 27 que es el numero de letras que componen el alfabeto. La operación que se encarga de esto es "mod" y la podemos expresar de la siguiente manera: 30 mod 27 = 3. Al realizar la opereacion en todas la sumas, siempre obtendremos un numero igual o menor a 27 y cada uno correspondera a cada letra del alfabeto.
El resultado de aplicar el cifrado de Vigenere en la frase "HELLOWORLD" con la contraseña "USG" es:

  • 30 mod 27 = 3 = C
  • 25 mod 27 = 25 = X
  • 19 mod 27 = 19 = R
  • 34 mod 27 = 7 = G
  • 36 mod 27 = 9 = I
  • 31 mod 27 = 4 = D
  • 38 mod 27 = 11 = K
  • 39 mod 27 = 12 = L
  • 19 mod 27 = 19 = R
  • 26 mod 27 = 26 = Y
HELLOWORLD = CXRGIDKLRY.

Cómo descifrar.

Ahora viene una parte importante de todo el proceso, devolver a una forma legible una frase que este cifrada. Siempre será necesario saber la contraseña que se uso para cifrar la frase. utilizando el ejemplo anterior; la contraseña es: "USG".
Par desencriptar lo primero que vamos a hacer es restar el numero correspondiente a la letra de la contraseña al letra ya de la frase ya cifrada, al igual que en la anterior, se avanzará de una en una y a cada letra se le restará su valor, si la frase o la contraseña son mas largas, se repetira hasta completar la palabra más larga.

  • 3-22 = -19
  • 25 - 20 = 5
  • 19 - 7 = 12
  • 7 - 22 = -15
  • ...
Al realizar las restas si el numero es negativo o menor que 1, procederemos a sumarle 27 (el numero de letras que tiene el alfabeto).
  • -19 + 27 = 8 = H
  • 5 = 5 = E
  • 12 = 12 = L
  • -15 + 27 = 12 = L
  • ...
Si el numero es mayor a 27 hay que realizar también la operación mod.
Ahora sabiendo esto, no me queda nada más que decir:
gizgxvgñlbi USG

LLegamos a 10000.

Hola a todos el día de hoy es un gran día, finalmente hemos llegado a las primeras 10000 visitas, a pesar de no ser un numero tan grande, vale la pena celebrarlo.

Dentro de las celebraciones tenemos:

  1. Nuevo estilo para el blog.
  2. La respuesta al reto #1 del blog de XWork (con su explicación).
  3. El reto #2 del blog de XWork.
  4. Actualización de algunos de los programas que ya se habían publicado.
Por ahora no me queda más que agradecerles a todos, ahora vamos por las 20000. Si en los próximos días notas que algo no funciona bien, es porque se esta actualizando.

Gracias totales.
Los leo luego.

Vamos a programar #30 - El código de Clock View (Android)

Hola de nuevo a todos, el día de hoy vamos a explicar el código que hace funcionar la aplicación de android Clock View.


La interfaz.

Antes que nada vamos a empezar ´por la interfaz, para el caso de Clock View esta compuesta de 2 partes. La primera son todos los botones de "acción" y parte principal de la aplicacion; la segunda solo es la lista que se encarga de mostrar todos los dispositivos que estén emparejados al dispositivo.

Para mostrar la interfaz principal, en el Layout principal, debemos de agregar el siguiente código.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:id="@+id/activity_main"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:paddingBottom="@dimen/activity_vertical_margin"
 android:paddingLeft="@dimen/activity_horizontal_margin"
 android:paddingRight="@dimen/activity_horizontal_margin"
 android:paddingTop="@dimen/activity_vertical_margin"
 tools:context="com.mdev.clockview.MainActivity">

 <ScrollView
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:layout_alignParentTop="true"
  android:layout_alignParentLeft="true"
  android:layout_alignParentStart="true">

  <LinearLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:orientation="vertical">

   <TextView
    android:text="La hora actual es:"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/TXTView"
    tools:ignore="HardcodedText" />

   <TextClock
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="14dp"
    android:id="@+id/TXTClock"
    android:typeface="sans"
    android:textAlignment="center"
    android:textSize="30sp"
    android:fontFamily="monospace"/>

   <Button
    android:text="Conectar con arduino."
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/BtnConnect"
    android:textAlignment="center"
    android:textAllCaps="false" />

   <Button
    android:text="Cambiar 12/24 Horas."
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/BtnFormat" />

   <Button
    android:text="No/Mostrar segundos."
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/BtnShowS"/>

   <Button
    android:text="Apagar/Encender matrices"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/BtnOn"/>

   <Button
    android:text="Sincronizar hora."
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/BtnSync"/>

   <TextView
    android:text="Nivel de brillo:"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="11dp"
    android:layout_marginStart="11dp"
    android:layout_marginTop="10dp"
    android:id="@+id/textView2" />

   <SeekBar
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="12dp"
    android:id="@+id/SKBrillo"
    android:max="15"
    android:progress="5" />

   <TextView
    android:text="Brillo: 15"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/txtSeekValue"/>

   <TextView
    android:text="Esperando a ClockView."
    android:layout_width="match_parent"
    android:id="@+id/TxtArduinoReturn"
    android:layout_height="wrap_content" />

   <Button
    android:text="Desconectar"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/BtnDisconnect" />
  </LinearLayout>
 </ScrollView>
</RelativeLayout>

Tras implementar el código, la aplicacion lucira algo similar a la siguiente imagen:



Cómo verás, solo consta de 6 botones, una barra de seek y las etiquetas para mostrar texto.
La funcion de cada uno, la veremos en el código Java, pero antes, vamos a terminar con la interfaz. La lista que contiene los dispositivos emparejados, es un layout que solo contiene un list view y su código es el siguiente;

<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:id="@+id/bt_list"
 android:orientation="vertical"
 android:layout_width="match_parent"
 android:layout_height="match_parent">

 <ListView
  android:id="@+id/BTList"
  android:layout_width="match_parent"
  android:layout_height="200dp"
  android:headerDividersEnabled="true"
  android:footerDividersEnabled="false">
 </ListView>

</LinearLayout>

Con esto completamos la parte de la interfaz, además en el código completo he agregado el diseño para cuando la orientacion del dispositivo es vertical y para cuando es horizontal, en lo personal preferí forzar a que la aplicacion siempre este en horizontal, pero eres libre de cambiarla a tu gusto.

El código en java.

El código en Java, lo he modificado un poco desde la última vez, corregi algunos errores, uno de ellos era: cuando se intentaba hacer la conexion y esta fallaba, al hacer click en cualquier botón, este intentaba mandar algo a traves del socket que supestemente debio de haber sido creado, al no estar disponible, la aplicion "crasheaba" y salia; el error se debia que a pesar de no haber conexion, la condicion que se debia de comprobar era verdadera debido a que se verificaba si el bluetooth estaba activado; la condicion se podia cumplir, pero eso significaria necesariamente que el socket ya se hubiera creado. Para solucionarlo, simplemente use un flag boleano que solo se cambiaba cuando se abria o cerraba la conexion, ahora si no hay conexion, simplemente no se intenta enviar nada.

Ademas coerregi algunos detalles y bugs minimos. El código actualizado es el siguiente:

package com.mdev.clockview;

import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Handler;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.Calendar;

import static com.mdev.clockview.R.layout.paired_devices_list;

public class MainActivity extends Activity {

 BluetoothAdapter myBluetoothAdapter = null;
 Button BtnConnect, BtnOnOff, BtnSecondsShow, BtnSyncHour, BtnChangeFormat,BtnDisconnect;
 SeekBar SkBright;
 TextView TxtArduinoRec, TxtBrigthValue;

 String address = null;
 private ProgressDialog progress;
 BluetoothSocket btSocket = null;
 private boolean isBtConnected = false;
 private static final UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
 final int RECEIVE_MESSAGE = 1;
 private StringBuilder sb = new StringBuilder();
 private ConnectedThread mConnectedThread;
 Handler h;

 private Set<BluetoothDevice> pairedDevices;
 ListView myListView;
 ArrayAdapter BTArrayAdapter;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  //setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
  BtnConnect = (Button)findViewById(R.id.BtnConnect);
  myListView = (ListView)findViewById(R.id.BTList);
  TxtArduinoRec = (TextView)findViewById(R.id.TxtArduinoReturn);
  BtnOnOff = (Button)findViewById(R.id.BtnOn);
  BtnSecondsShow = (Button)findViewById(R.id.BtnShowS);
  BtnSyncHour = (Button)findViewById(R.id.BtnSync);
  BtnChangeFormat = (Button)findViewById(R.id.BtnFormat);
  BtnDisconnect = (Button)findViewById(R.id.BtnDisconnect);
  SkBright = (SeekBar)findViewById(R.id.SKBrillo);
  TxtBrigthValue = (TextView)findViewById(R.id.txtSeekValue);

  myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

  if (myBluetoothAdapter == null) {
   msg("El bluetooth no es soportado por este dispositivo");
  }
  else {
   msg("Esperando la conexion");
  }
  SkBright.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){

   @Override
   public void onProgressChanged(SeekBar seekBar, int progress,
            boolean fromUser) {
    TxtBrigthValue.setText("Brillo: " + String.valueOf(progress));
    if (isBtConnected)
    {
     String result = String.format(">SETB%1$02d", progress);
     mConnectedThread.write(result);
    }
   }

   @Override
   public void onStartTrackingTouch(SeekBar seekBar) {
   }

   @Override
   public void onStopTrackingTouch(SeekBar seekBar) {

   }
  });
  BtnConnect.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
    if (!myBluetoothAdapter.isEnabled()) {
     Intent turnOnIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
     startActivityForResult(turnOnIntent, 1);
    }else{
     showBTDialog();
    }
   }
  });
  BtnOnOff.setOnClickListener(new View.OnClickListener()
  {
   @Override
   public void onClick(View view){
    if (isBtConnected)
    {
     mConnectedThread.write(">SCRA");
    }
   }
  });

  BtnSecondsShow.setOnClickListener(new View.OnClickListener()
  {
   @Override
   public void onClick(View view){
    if (isBtConnected)
    {
     mConnectedThread.write(">DISS");
    }
   }
  });

  BtnSyncHour.setOnClickListener(new View.OnClickListener()
  {
   @Override
   public void onClick(View view){
    if (isBtConnected)
    {
     mConnectedThread.write(BuildHour(true));
    }
   }
  });

  BtnChangeFormat.setOnClickListener(new View.OnClickListener()
  {
   @Override
   public void onClick(View view){
    if (isBtConnected)
    {
     mConnectedThread.write(">SETF");
    }
   }
  });
  BtnDisconnect.setOnClickListener(new View.OnClickListener()
  {
   @Override
   public void onClick(View view){
    if (isBtConnected)
    {
     Disconnect();
    }
   }
  });
  //encargado de procesar los mensajes.
  h = new Handler() {
   public void handleMessage(android.os.Message msg) {
    switch (msg.what)
    {
     case RECEIVE_MESSAGE:
      byte[] readBuf = (byte[]) msg.obj;
      String strIncom = new String(readBuf, 0, msg.arg1);
      sb.append(strIncom);
      int endOfLineIndex = sb.indexOf("\r\n");
      if (endOfLineIndex > 0)
      {
       String sbprint = sb.substring(0, endOfLineIndex);
       sb.delete(0, sb.length());
       TxtArduinoRec.setText("Data from Arduino: " + sbprint);
      }
     break;
    }
   };
  };

 }
 private void msg(String s)
 {
  Toast.makeText(getApplicationContext(),s,Toast.LENGTH_LONG).show();
 }
 private String BuildHour(boolean ForArduino){
  //>SETH2016122119001004
  //>SETHAAAAMMDDHHMMSSWW
  Calendar c = Calendar.getInstance();
  int DiaSemana = c.get(Calendar.DAY_OF_WEEK);
  int Anio = c.get(Calendar.YEAR);
  int Mes = c.get(Calendar.MONTH);
  int Dia = c.get(Calendar.DAY_OF_MONTH);
  int Horas = c.get(Calendar.HOUR_OF_DAY);
  int Minutos = c.get(Calendar.MINUTE);
  int Segundos = c.get(Calendar.SECOND);
  String Fecha = null;
  if (ForArduino == true){
   Fecha = String.format(">SETH%1$04d%2$02d%3$02d%4$02d%5$02d%6$02d%7$02d",
     Anio, Mes + 1, Dia, Horas, Minutos,Segundos, DiaSema);
   msg(Fecha);
  }else {
   Fecha = String.format("%1$04d/%2$02d/%3$02d - %4$02d:%5$02d:%6$02d",
     Anio, Mes + 1, Dia, Horas, Minutos,Segundos);
  }
  return Fecha;
 }

 private void Disconnect()
 {
  if (btSocket!=null)
  {
   try
   {
    btSocket.close();
    isBtConnected = false;
   }
   catch (IOException e)
   { msg("Error");}
  }
 }

 private AdapterView.OnItemClickListener myListClickListener = new AdapterView.OnItemClickListener()
 {
  public void onItemClick (AdapterView<?> av, View v, int arg2, long arg3) {
   if (myBluetoothAdapter.isEnabled()) {
    String info = ((TextView) v).getText().toString();
    address = info.substring(info.length() - 17);
    msg(info);

   } else {
    msg("El Bluetooth debe de estar encendido.");
   }
  }
 };


 public void showBTDialog() {
  final AlertDialog.Builder popDialog = new AlertDialog.Builder(this);
  final LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
  final View Viewlayout = inflater.inflate(paired_devices_list, (ViewGroup) findViewById(R.id.bt_list));

  popDialog.setTitle("Dispositivos Bluetooth:");
  popDialog.setView(Viewlayout);

  myListView = (ListView) Viewlayout.findViewById(R.id.BTList);
  BTArrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
  myListView.setAdapter(BTArrayAdapter);
  pairedDevices = myBluetoothAdapter.getBondedDevices();

  for(BluetoothDevice device : pairedDevices)
   BTArrayAdapter.add(device.getName()+ "\n" + device.getAddress());

  myListView.setOnItemClickListener(myListClickListener);
  // Button OK
  popDialog.setPositiveButton("Conectar",
    new DialogInterface.OnClickListener() {
     public void onClick(DialogInterface dialog, int which) {
      if (address != null)
      {
       new ConnectBT().execute();
      }
      dialog.dismiss();
     }
    });
  popDialog.create();
  popDialog.show();

 }
 private class ConnectedThread extends Thread {
  private final InputStream mmInStream;
  private final OutputStream mmOutStream;

  public ConnectedThread(BluetoothSocket socket) {
   InputStream tmpIn = null;
   OutputStream tmpOut = null;
   try {
    tmpIn = socket.getInputStream();
    tmpOut = socket.getOutputStream();
   } catch (IOException e) { }

   mmInStream = tmpIn;
   mmOutStream = tmpOut;
  }

  public void run() {
   byte[] buffer = new byte[256];
   int bytes;
   while (true) {
    try {
     bytes = mmInStream.read(buffer);
     h.obtainMessage(RECEIVE_MESSAGE, bytes, -1, buffer).sendToTarget();
    } catch (IOException e) {
     break;
    }
   }
  }

  public void write(String message) {
   byte[] msgBuffer = message.getBytes();
   try {
    mmOutStream.write(msgBuffer);
   } catch (IOException e) {
    msg("Error al enviar: " + e.getMessage());

   }
  }
 }

 private class ConnectBT extends AsyncTask<Void, Void, Void>
 {
  private boolean ConnectSuccess = true;

  @Override
  protected void onPreExecute()
  {
   progress = ProgressDialog.show(MainActivity.this, "Conectando ("+ address +")...", "Espera...!!!");
  }

  @Override
  protected Void doInBackground(Void... devices)
  {
   try
   {
    if (btSocket == null || !isBtConnected)
    {
     myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
     BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
     BluetoothDevice dispositivo = myBluetoothAdapter.getRemoteDevice(address);
     btSocket = createBluetoothSocket(dispositivo);
     btSocket.connect();
    }
   }
   catch (IOException e)
   {
    ConnectSuccess = false;
   }
   return null;
  }

  private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
   if(Build.VERSION.SDK_INT >= 10){
    try {
     final Method  m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", new Class[] { UUID.class });
     return (BluetoothSocket) m.invoke(device, myUUID);
    } catch (Exception e) {
     msg("No se pudo crear la conexion");
    }
   }
   return  device.createRfcommSocketToServiceRecord(myUUID);
  }

  @Override
  protected void onPostExecute(Void result)
  {
   super.onPostExecute(result);

   if (!ConnectSuccess)
   {
    msg("La conexion falló, intentelo de nuevo");
    isBtConnected = false;
   }
   else
   {
    msg("Conectado.");
    isBtConnected = true;
    mConnectedThread = new ConnectedThread(btSocket);
    mConnectedThread.start();
   }
   progress.dismiss();
  }
 }
}

Ahora con el código actualizado vamos a ver que hace cada parte del el.

Clock view está compuesto por tres clases, la primera de ellas es la que se encarga de mostrar todos los componente de la interfaz principal (crear lo eventos para los botones, inflar las cosas necesarias, etc), la segunda es ConnectedThread.

La clase ConnectedThread, es la que se va a encarga de enviar y recibir los datos de y hacia la aplicación.
En ella hay dos métodos: run() y write(). En el método run es donde vamos a leer todos los datos que vienen desde el arduino. Lo pasaremos cómo mensaje y despues el manejado h, se encargará de re-direccionar el contenido y mostrarlo en un textview.
El método write(), servirá para enviar datos hacia el arduino, está es la función que se debe de usar para enviar los comandos, por ejemplo, para enviar el comando para mostrar los segundos, debemos de llamar a la función con el parámetro ">DISS" write(">DISS").
La tercera clase es la que se encarga de crear la conexion y mostrar un dialogo de progreso/espera, cuando la conexión se realiza, deja un socket bluetooth listo para usarse.

Cómo verás, la aplicación es realmente sencilla, pero aun queda mucho por agregar a ambas partes de Clock View, por ahora el código fuente completo lo reservo para cuando ya tenga todas la funciones listas, pero con lo anterior, ya puedes crear tu propia versión.

La parte del código para arduino se actualizará, pero ese en cuanto lo cambie, también actualizaré el vinculo en dropbox.

Por ahora es todo, pero a esto aun le resta bastante para que sea un reloj funcional (más funcional).
Los leo luego.