Controlador de prótesis con Myo, Android y Arduino vía Bluetooth

Uno de mis proyectos más recientes tiene que ver con la creación de una prótesis de mano articulada que permita a los usuarios realizar el control de los movimientos a través del uso del brazalete de captura de movimientos Myo.

Para ello hemos creado una aplicación en Android que permita la comunicación Myo-Android-Arduino-Servomotores para lograr el movimiento final.

image
Myo y Arduino?? Oh si!!

La fuente del proyecto en Android está en https://github.com/sansagara/BluetoothArmController

Aplicacion para SMS premium

Los SMS premium están en franca decadencia. Sin embargo, dependiendo de la calidad del servicio provisto, todavía es posible obtener una ganancia decente.

Un cliente me planteó la idea de crear una aplicación Android que permita precisamente esto: Enviar una respuesta automáticamente a los SMS recibidos, de acuerdo al contenido del mismo. Por ejemplo, si se recibe el texto Triple, se envíe una respuesta apropiada.

Para ello, obviamente se requiere una Base de Datos que pueda ser modificada en tiempo real, para permitir cierto dinamismo en las respuestas. He decidido usar el excelente servicio prestado por Parse.com ya que facilita el trabajo. Para mayor detalle, siempre se puede consultar la documentación.

Parse.com class with object details
Parse.com class with object details

Por último, es de hacer notar que desde Android 4.4, ninguna aplicacion puede tener el control total de de los SMS a menos que el usuario seleccione nuestra aplicacion como la aplicacion de SMS por defecto. Pero esto se puede evitar usando simplemente SmsManager

El Gist en GiHub:


package com.leonelatencio.mysms;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.provider.Telephony;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.util.Log;
import com.parse.FindCallback;
import com.parse.GetCallback;
import com.parse.ParseException;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import java.util.List;
/**
* Created by Leonel on 18-04-2015.
*/
public class SmsListener extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(intent.getAction())) {
for (SmsMessage smsMessage : Telephony.Sms.Intents.getMessagesFromIntent(intent)) {
final String messageBody = smsMessage.getMessageBody();
final String messageFrom = smsMessage.getOriginatingAddress();
//Log Received SMS
Log.d("SMS", "Message received: " + messageBody + " From: " + messageFrom);
//Save received SMS to Parse
ParseObject testObject = new ParseObject("SMSRec");
testObject.put("From", messageFrom);
testObject.put("Message", messageBody);
testObject.saveInBackground();
//Query Reply Message in Parse
ParseQuery<ParseObject> query = ParseQuery.getQuery("SMSContent");
query.whereEqualTo("keyWord", messageBody);
query.getFirstInBackground(new GetCallback<ParseObject>() {
public void done(ParseObject object, ParseException e) {
if (object == null) {
Log.d("SMS", "Cant find a response.");
} else {
String responseBody = object.getString("responseText");
Log.d("SMS", "Found a response to" + messageBody + ":/n" + responseBody);
//Finally, try to send SMS.
sendSMS(messageFrom, responseBody);
}
}
});
}
}
}
public void sendSMS(String replyTo, String replyBody){
try {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(replyTo, null, replyBody, null, null);
//Log sent message.
Log.d("SMS", "Sending message: " + replyBody + " To: " + replyTo);
} catch (Exception ex) {
//Log failed SMS.
Log.d("SMS", "Sending failed: " + replyBody + " To: " + replyTo);
}
}
}

Main Activity
Main Activity

Android Custom Adapter con Fragments

ListView view of app
ListView view of app

He estado tomando un par de cursos online sobre Desarrollo de Aplicaciones Android, para ayudarme en un proyecto que tengo en mente, usando un Custom Drawer para navegar entre secciones (Fragments) y usando Parse.com como backend para la obtencion de la data. Les dejo un mini-tutorial.

main_fragment.xml
Este es el fragmento que se necesita mostrar. Tiene un TextView en la parte superior para usar como titulo
This is the fragment you need to show on the app. Notice the ListView has an ID. It also has a TextView to show headlines



    


    

    


adapter_layout.xml
Este es el diseno que nuestro ‘Custom Adapter’ usara para insertar la data a cada Fila de nuestro ‘ListView’
This is the layout our custom adapter is going to use to fetch the data into each Row in our ListView. The style here is going to show as each item for the main List

 

    

    

 

CustomAdapter.java
Este es nuestro adaptor. Usa el objeto placesObject para colocar el texto en los campos de adapter_layout.xml
This is our custom adapter that uses a ParseObject placesObject to set the text of our adapter_layout.xml fields

/**
 * Custom Adapter for Places List
 * Created by Leonel on 01-01-2015.
 */

public class PlacesAdapter extends ArrayAdapter {
    protected Context mContext;
    protected List mPlaces;

    public PlacesAdapter(Context context, List place) {
        super(context, R.layout.places_custom_fragment, place);
        mContext = context;
        mPlaces = place;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder;

        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(
                    R.layout.places_custom_fragment, null);
            holder = new ViewHolder();
            holder.placeName = (TextView) convertView
                    .findViewById(R.id.txtPlace);
            holder.placeDescription = (TextView) convertView
                    .findViewById(R.id.txtPlaceDescription);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        ParseObject placesObject = mPlaces.get(position);

        // title
        String place = placesObject.getString("placeName");
        holder.placeName.setText(place);

        // content
        String description = placesObject.getString("placeDescription");
        holder.placeDescription.setText(description);

        return convertView;
    }

    public static class ViewHolder {
        TextView placeName;
        TextView placeDescription;
    }
}

MainFragment.java
Creamos la consulta a Parse.com y lo enviamos a nuestro adaptor para ser expandido
In our onActivityCreated, we make our Parse.com query and send it to our adapter to be expanded.


public class PlacesFragment extends Fragment {

	private boolean mSearchCheck;
        protected List mPlaces;

        @Override
	public void onActivityCreated(Bundle savedInstanceState) {
        // TODO Populate ListView with Data from Parse

        //Query All Places

        final ListView mlist = (ListView)getView().findViewById(R.id.listMain);

        ParseQuery query = ParseQuery.getQuery("Places");
        query.findInBackground(new FindCallback() {
            @Override
            public void done(List place, ParseException e) {
                if (e == null) {
                    mPlaces = place;

                    PlacesAdapter adapter = new PlacesAdapter(getActivity(), mPlaces);
                    mlist.setAdapter(adapter);
                } else {
                }
            }
        });
}

Vínculo al proyecto en GitHub
Vinculo al curso en Udemy

Notas de Preparación para el examen de certificación de Linux Foundation

En un Google Hangout con varios candidatos y próximos certificados por la Linux Foundation como «System Administrator», me fue compartida por su autor el siguiente trabajo de recopilación (Podría llamarse manual) de los conocimientos básicos que debe tener quien tome el examen.

Linux Foundation Certified System Administrator (LFCS) [PDF, 900Kb]

Twitter suprimirá las contraseñas de acceso: ¿Cómo entraremos en nuestra cuenta?

 

Twitter Passwords

En la conferencia de desarrolladores en San Francisco, Jeff Seibert, director de plataformas móviles de Twitter, presentó el sistema Digits, que la red social ofrece de forma gratuita en 28 idiomas de 216 países.

El funcionamiento del Digits será sencillo: al introducir el número de móvil asociado a la cuenta, le llega un SMS con un código temporal. Para cada sesión hay que repetir la operación. Los gastos del envío del mensaje corren a cargo de Twitter.

A su juicio, el nuevo sistema es mejor que la combinación actual de un ‘e-mail’, que resulta difícil de teclear en los teléfonos móviles y son más susceptible de pirateo.

«Cada vez más y más, el número de teléfono se convierte en el identificador principal de un individuo en comparación con  la dirección de correo electrónico. En los mercados en desarrollo a menudo es el único identificador, ya que algunos propietarios de teléfonos inteligentes a menudo no tienen direcciones de correo electrónico», anunció Twitter en un comunicado.

Aplicativo Aprobar Pagos con Bootstrap3 y Footables

Acá un aplicativo para la aprobación de pagos. Permite insertar, aprobar y revisar las órdenes de pago según el perfil del usuario.

Elementos Utilizados:

Sistema de Pagos
Sistema de Pagos

Autenticando tu Aplicativo con Google Apps

En la empresa donde hago consultoría tenían la necesidad de autenticar su aplicaciones web con la misma contraseña de Google Apps for Business, de manera de mantener solo una clave alrededor de la empresa y aprovechar las ventajas que esto trae consigo.

Esto debemos hacerlo con OAUTH2. Acá el tutorial para realizarlo en PHP:

https://developers.google.com/api-client-library/php/auth/web-app