Impartido por Jorge Luis Hernández C. / @lesthack
Marzo 2013
El Curso de desarrollo móvil esta diseñado para:
Desarrollo bajo el SDK de Android para aplicaciones nativas, poderosas y veloces.
Desarrollo bajo tecnologías web aplicadas en dispositivos móviles. Rápidas, bonitas y faciles de crear.
Sesión 1
Android SDK Parte 1
Sesión 2
Android SDK Parte 2
Sesión 3
PhoneGap + Jquery Mobile Parte 1
Sesión 4
PhoneGap + Jquery Mobile Parte 2
Sesión 5
Tools with Node.js, Websockets and Git
Sesión 6
Generando un Proyecto
Sesión 1
PhoneGap + Jquery Mobile Parte 1
Sesión 2
PhoneGap + Jquery Mobile Parte 2
Sesión 3
Git + Utilerias
Sesión 4
Android SDK Parte 1
Sesión 5
Android SDK Parte 2
Sesión 6
Generando un Proyecto
Penetración de las plataformas mobiles en el mercado (2012)
Fuente Original: http://es.wikipedia.org/wiki/Sistema_operativo_móvil
PhoneGap is a free and open source framework that allows you to create mobile apps using standardized web APIs for the platforms you care about.
Guía Jquery Mobile
Nota: el directorio del SDK deberá esta incluido en la variable PATH Environment del Sistema Operativo.
create FirstApp
Como incluir el directorio del SDK en la variable Path Environment.
export PATH=${PATH}:/opt/android-sdk-linux/platform-tools:/opt/android-sdk-linux/tools
Parameters:
Buttons:
Groups:
Sliders:
Range Slider:
Flip Switch:
Checkbox:
Radiobutton:
input Element
textarea Element
ul | ol Elementes
ul | ol Elementes
a Element
div Element
div Element
div Elements Content
div Element
Programación Básica con Jquery Mobile
Uso de Phonegap
Proyecto: App Cinepolis
Para profundizar en los temas, se recomienda acceder a la documentación oficial de las tecnologías. Phonegap y Jquery Mobile..
// getElementsByTagName $("div") // getElementById $("#idobject") // getElementByClassName $(".classname") // Herencia $("ol li") $("#root a") // Precisos $("a.menu_item")
// Agregando clases $("string").addClass("classname"); // Eliminando clases $("string").removeClass("classname"); // tiene esta clase ? $("string").hasClass("classname"); // Modificación directa del CSS $("string").css("propiedad", "valor");
function hola(){ alert("Hola mundo"); } // Click $("button").click(hola); // Doble Click $("button").dblclick(hola); // Hover $("button").hover(hola);
// Click $("button").click(function(){ alert("Esta es una función anónima"); });
$.ajax({ url: "local/dir", data: {}, success: function(data){ console.log(data); } );
// tap Event $("string").on("tap", function(event){ console.log(event); } ) // orientation $(window).on("orientationchange", function(event){ console.log(event); } ); // taphold $("string").on("taphold", function(event){ console.log(event); } ) // taphold $("string").on("swipeleft", function(event){ console.log(event); } )
app/AndroidManifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
app/res/xml/config.xml
<plugin name="Camera" value="org.apache.cordova.CameraLauncher" />
Javascript
navigator.camera.getPicture(onSuccess, onFail, { quality: 50, destinationType: Camera.DestinationType.FILE_URI }); function onSuccess(imageURI) { var image = document.getElementById('myImage'); image.src = imageURI; } function onFail(message) { alert('Failed because: ' + message); }
app/res/xml/config.xml
<plugin name="Accelerometer" value="org.apache.cordova.AccelListener" />
Javascript
function onSuccess(acceleration) { alert('Acceleration X: ' + acceleration.x + '\n' + 'Acceleration Y: ' + acceleration.y + '\n' + 'Acceleration Z: ' + acceleration.z + '\n' + 'Timestamp: ' + acceleration.timestamp + '\n'); }; function onError() { alert('onError!'); }; navigator.accelerometer.getCurrentAcceleration(onSuccess, onError);
app/res/xml/config.xml
<plugin name="Compass" value="org.apache.cordova.CompassListener" />
Javascript
function onSuccess(heading) { alert('Heading: ' + heading.magneticHeading); }; function onError(error) { alert('CompassError: ' + error.code); }; navigator.compass.getCurrentHeading(onSuccess, onError);
app/AndroidManifest
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
app/res/xml/config.xml
<plugin name="Geolocation" value="org.apache.cordova.GeoBroker" />
Javascript
navigator.geolocation.getCurrentPosition(onSuccess, onError); var onSuccess = function(position) { console.log('Latitude: ' + position.coords.latitude); console.log('Longitude: ' + position.coords.longitude); console.log('Altitude: ' + position.coords.altitude); console.log('Accuracy: ' + position.coords.accuracy); console.log('Altitude Accuracy: ' + position.coords.altitudeAccuracy); console.log('Heading: ' + position.coords.heading); console.log('Speed: ' + position.coords.speed); console.log('Timestamp: ' + position.timestamp); }; function onError(error) { alert('code: ' + error.code + '. message: ' + error.message); }
Generar una aplicación móvil que pueda obtener datos reales de la cartelera al día de Cinépolis y mostrarla de una forma ordenada, simple, básica, pero funcional y elegante.
Uso de Git
Introducción al SDK de Android
Proyecto: SimpleChat
At the heart of GitHub is an open source version control system (VCS) called Git*. Created by the same team that created Linux, Git is responsible for everything GitHub related that happens locally on your computer.
git add . # Agrega todo el contenido modificado git add README # Agrega solo un archivo git commit -a -m "Agregando todo" git commit -m "Agregando solo aquel que hizo add" git push origin master git status git log git rm git mv git checkout -- file git reset HAED file
git branch test git checkout test git checkout -b test # Este es equivalente a los 2 anteiores vim README git commit -a -m "Modificando README" git checkout master git merge test git branch -d test
Nota: Tomada de unos viejos slides de un Taller de Android del 2011
Nota: Tomada de unos viejos slides de un Taller de Android del 2011
Controles:
Funciones básicas
Proyecto: Pantalla Login
Nota: El contenido de esta sesión fue tomado del sitio sgoliver Curso de Programación Android
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText android:id="@+id/TxtNombre"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inputType="text" />
</FrameLayout>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText android:id="@+id/TxtDato1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inputType="text"
android:layout_weight="1" />
</LinearLayout>
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TableRow>
<TextView android:text="Celda 1.1" />
<TextView android:text="Celda 1.2" />
<TextView android:text="Celda 1.3" />
</TableRow>
<TableRow>
<TextView android:text="Celda 2.1" />
<TextView android:text="Celda 2.2" />
<TextView android:text="Celda 2.3" />
</TableRow>
<TableRow>
<TextView android:text="Celda 3.1"
android:layout_span="2" />
<TextView android:text="Celda 3.2" />
</TableRow>
</TableLayout>
<GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:rowCount="2"
android:columnCount="3"
android:orientation="horizontal" >
<TextView android:text="Celda 1.1" />
<TextView android:text="Celda 1.2" />
<TextView android:text="Celda 1.3" />
<TextView android:text="Celda 2.1" />
<TextView android:text="Celda 2.2" />
<TextView android:text="Celda 2.3" />
<TextView android:text="Celda 3.1"
android:layout_columnSpan="2" />
<TextView android:text="Celda 3.2" />
</GridLayout>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<EditText android:id="@+id/TxtNombre"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text" />
<Button android:id="@+id/BtnAceptar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/TxtNombre"
android:layout_alignParentRight="true" />
</RelativeLayout>
<Button android:id="@+id/BtnBoton1"
android:text="@string/pulsame"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
btnBoton1 = (Button)findViewById(R.id.BtnBoton1);
btnBoton1.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0)
{
lblMensaje.setText("Botón 1 pulsado!");
}
});
<ToggleButton android:id="@+id/BtnBoton2"
android:textOn="@string/on"
android:textOff="@string/off"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
btnBoton2 = (ToggleButton)findViewById(R.id.BtnBoton2);
btnBoton2.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0)
{
if(btnBoton2.isChecked())
lblMensaje.setText("Botón 2: ON");
else
lblMensaje.setText("Botón 2: OFF");
}
});
<ImageButton android:id="@+id/BtnBoton3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/icono_ok"
android:src="@drawable/ok" />
btnBoton3 = (Button)findViewById(R.id.BtnBoton3);
btnBoton3.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0)
{
lblMensaje.setText("Botón 3 pulsado!");
}
});
<ImageView android:id="@+id/ImgFoto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon"
android:contentDescription="@string/imagen_ejemplo" />
ImageView img= (ImageView)findViewById(R.id.ImgFoto);
img.setImageResource(R.drawable.icon);
<TextView android:id="@+id/LblEtiqueta"
android:layout_width="matchfill_parent"
android:layout_height="wrap_content"
android:text="@string/escribe_algoEscribe algo:"
android:background="#AA44FF"
android:typeface="monospace" />
final TextView lblEtiqueta = (TextView)findViewById(R.id.LblEtiqueta);
String texto = lblEtiqueta.getText().toString();
texto += "123";
lblEtiqueta.setText(texto);
lblEtiqueta.setBackgroundColor(Color.BLUE);
<EditText android:id="@+id/TxtTexto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text" />
final EditText txtTexto = (EditText)findViewById(R.id.TxtTexto);
String texto = txtTexto.getText().toString();
txtTexto.setText("Hola mundo!")
<Spinner android:id="@+id/CmbOpciones"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
cmbOpciones = (Spinner)findViewById(R.id.CmbOpciones);
final String[] datos =
new String[]{"Elem1","Elem2","Elem3","Elem4","Elem5"};
ArrayAdapter<String> adaptador =
new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, datos);
adaptador.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
cmbOpciones.setAdapter(adaptador);
cmbOpciones.setOnItemSelectedListener(
new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView> parent,
android.view.View v, int position, long id) {
lblMensaje.setText("Seleccionado: " + datos[position]);
}
public void onNothingSelected(AdapterView> parent) {
lblMensaje.setText("");
}
});
<ListView android:id="@+id/LstOpciones"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
final String[] datos =
new String[]{"Elem1","Elem2","Elem3","Elem4","Elem5"};
ArrayAdapter<String> adaptador =
new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, datos);
lstOpciones = (ListView)findViewById(R.id.LstOpciones);
lstOpciones.setAdapter(adaptador);
<GridView android:id="@+id/GridOpciones"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="auto_fit"
android:columnWidth="80px"
android:horizontalSpacing="5dp"
android:verticalSpacing="10dp"
android:stretchMode="columnWidth" />
private String[] datos = new String[25];
//...
for(int i=1; i<=25; i++)
datos[i-1] = "Dato " + i;
ArrayAdapter<String> adaptador =
new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, datos);
grdOpciones = (GridView)findViewById(R.id.GridOpciones);
grdOpciones.setAdapter(adaptador);
Simple aplicación que verifica la autenticidad de un usuario
Funciones avanzadas
Nota: El contenido de esta sesión fue tomado del sitio sgoliver Curso de Programación Android
Is a relational database management system contained in a small (~350 KB) C programming library.
SQLite is ACID-compliant and implements most of the SQL standard, using a dynamically and weakly typed SQL syntax that does not guarantee the domain integrity.
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
public class UsuariosSQLiteHelper extends SQLiteOpenHelper {
String sqlCreate = "...";
public UsuariosSQLiteHelper(Context contexto, String name,
CursorFactory factory, int version) {
super(contexto, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(sqlCreate);
}
@Override
public void onUpgrade(SQLiteDatabase db, int versionAnterior, int versionNueva) {
}
}
import android.app.Activity;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
public class MiActividad extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
UsuariosSQLiteHelper usdbh = new UsuariosSQLiteHelper(this, "MiBasededatos", null, 1);
SQLiteDatabase db = usdbh.getWritableDatabase();
}
}
db.execSQL("INSERT INTO tabla (campo1,campo2) VALUES ('valor1','valor2') ");
db.execSQL("DELETE FROM tabla WHERE campo1='valor1' ");
db.execSQL("UPDATE tabla SET campo1='valor1' WHERE campo2='valor2' ");
String[] args = new String[] {"valor1"};
Cursor c = db.rawQuery("SELECT * FROM tabla WHERE campo1=? ", args);
if (c.moveToFirst()) {
do {
String campo1 = c.getString(0);
String campo2 = c.getString(1);
} while(c.moveToNext());
}