1. Code
  2. Coding Fundamentals
  3. Tools

Construye un Lanzador Personalizado en Android

Scroll to top

Spanish (Español) translation by Rafael Chavarría (you can also view the original English article)

Final product imageFinal product imageFinal product image
What You'll Be Creating

Introducción

En la forma más básica, un lanzador es una aplicación que hace lo siguiente:

  • representa la pantalla de inicio de un dispositivo
  • lista y lanza aplicaciones que están instaladas en el dispositivo

En otras palabras, es la aplicación que aparece cuando presionas el botón de inicio. A menos que ya hayas instalado un lanzador personalizado, actualmente estás usando el lanzador por defecto que viene con tu instalación de Android. Muchos frabricantes de dispositivos tienen sus propios lanzadores personalizados por defecto que conforman tu apariencia propietaria, por ejemplo el Samsung TouchWiz y HTC Sense.

En este tutorial, vamos a crear un lanzador simple con una interfaz de usuario básica. Tendrá dos pantallas:

  • una pantalla de inicio mostrando el papel tapiz del dispositivo
  • una pantalla mostrando los iconos y detalles de las aplicaciones instaladas en el dispositivo

1. Requerimientos

Necesitas tener lo siguiente instalado y configurado en tu máquina de desarrollo:

  • SDK de Android y herramientas de plataforma
  • IDE Eclipse 3.7.2 o superior con el complemento ADT
  • un emulador o dispositivo Android ejecutando Android 2.2 o superior

Puedes descargar el SDK y herramientas de plataforma en el portal de desarrollador Android.

2. Configuración de Proyecto

Lanza Eclipse y crea un nuevo proyecto de aplicación Android. Estoy nombrando la aplicación SimpleLauncher, pero puedes nombrarlo como quieras. Asegúrate de usar un paquete único. La versión más baja de SDK que nuestro lazador soporta es Froyo y el SDK destino es Jelly Bean.

Ya que no queremos crear una Activity, deselecciona Crear Activity. Haz clic en Terminar para continuar.

3. Manifiesto de Proyecto

El siguiente paso es modificar el archivo AndroidManifest.xml agregando dos actividades. La primera Activity muestra la pantalla de inicio. Nombrémoslo HomeActivity como se muestra abajo.

1
<activity
2
    android:name="ah.hathi.simplelauncher.HomeActivity"
3
    android:label="Simple Launcher Home"
4
    android:theme="@android:style/Theme.Wallpaper.NoTitleBar.Fullscreen"
5
    android:launchMode="singleTask"
6
    android:stateNotNeeded="true"
7
    >
8
    <intent-filter>
9
      <action android:name="android.intent.action.MAIN" />
10
      <category android:name="android.intent.category.HOME" />
11
      <category android:name="android.intent.category.DEFAULT" />
12
    </intent-filter>         
13
</activity>

Al agregar las categorías android.intent.category.HOME y android.intent.category.DEFAULT al grupo intent-filter, la Activity asociada se comporta como un lanzador y se muestra como una opción cuando presionas el botón inicio del dispositivo.

También necesitamos establecer el launchMode a singleTask para asegurar que solo una instancia de este Activity es retenida por el sistema a la vez. Para mostrar el papel tapiz del usuario, establece el tema a Theme.Wallpaper.NoTitleBar.FullScreen.

La segunda Activity que necesitamos agregar muestra las aplicaciones que están instaladas en el dispositivo del usuario. También es responsable de lanzar aplicaciones. No necesitamos ninguna configuración especial para esta Acivity. Nombrala AppsListActivity.

1
<activity
2
    android:name="ah.hathi.simplelauncher.AppsListActivity"
3
    android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
4
    >            
5
</activity>

4. Retículas de Actividad

Crea un archivo XML para la clase HomeActivity en la carpeta del proyecto res/layout y nómbralo activity_home.xml. La retícula tiene un solo Button que responde a los botones de clic. Hacer clic en el botón lleva al usuario de la pantalla de inicio a la lista de aplicaciones.

1
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
2
    xmlns:tools="http://schemas.android.com/tools"
3
    android:layout_width="match_parent"
4
    android:layout_height="match_parent"
5
    tools:context=".HomeActivity" >
6
7
    <Button
8
        android:id="@+id/apps_button"
9
        android:layout_width="wrap_content"
10
        android:layout_height="wrap_content"
11
        android:layout_alignParentRight="true"
12
        android:layout_alignParentTop="true"
13
        android:layout_marginRight="10dp"
14
        android:layout_marginTop="10dp"
15
        android:text="Show Apps"
16
        android:onClick="showApps"
17
        />
18
19
</RelativeLayout>

Después, crea un archivo XML para la clase AppsListActivity en la carpeta del proyecto res/layout y nómbralo activity_apps_list.xml. La retícula contiene un ListView que ocupa la pantalla entera.

1
<?xml version="1.0" encoding="utf-8"?>
2
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
    android:layout_width="match_parent"
4
    android:layout_height="match_parent"
5
    android:orientation="vertical" >
6
    
7
    <ListView
8
        android:id="@+id/apps_list"
9
        android:layout_width="match_parent"
10
        android:layout_height="match_parent"
11
        >        
12
    </ListView>    
13
14
</LinearLayout>

Finalmente, crea un tercer archivo XML en la misma ubicación y nómbralo list_item.xml. Este archivo define la retícula de un elemento en la ListView. Cada elemento de vista de lista representa una aplicación instalada en el dispositivo del usuario. Muestra el icono, etiqueta y nombre de paquete de la aplicación. Mostramos el icono de aplicación usando una instancia ImageView e instancias TextView para la etiqueta y nombre de paquete.

1
<?xml version="1.0" encoding="utf-8"?>
2
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
    android:layout_width="match_parent"
4
    android:layout_height="match_parent"
5
    android:padding="10dp"
6
    >
7
8
    <ImageView
9
        android:id="@+id/item_app_icon"
10
        android:layout_width="wrap_content"
11
        android:layout_height="wrap_content"
12
        android:layout_alignParentLeft="true"
13
        android:layout_centerVertical="true"        
14
        />
15
    
16
    <TextView 
17
        android:id="@+id/item_app_label"
18
        android:layout_width="wrap_content"
19
        android:layout_height="wrap_content"
20
        android:layout_toRightOf="@+id/item_app_icon"
21
        android:paddingLeft="10dp"
22
        />
23
24
    <TextView 
25
        android:id="@+id/item_app_name"
26
        android:layout_width="wrap_content"
27
        android:layout_height="wrap_content"
28
        android:layout_below="@+id/item_app_label"
29
        android:layout_toRightOf="@+id/item_app_icon"
30
        android:paddingLeft="10dp"
31
        />
32
    
33
</RelativeLayout>

5. Implementando las Clases de Actividad

HomeActivity

Con las retículas de la aplicación creadas, es tiempo de crear las dos clases Activity. Ciamdp creamos las dos clases, asegúrate de que el nombre de cada clase empate al que especificaste en el archivo del manifiesto del proyecto anteriormente.

Crea una nueva clase llamada HomeActivity y establece android.app.Activity como su super clase.

1
package ah.hathi.simplelauncher;
2
3
import android.app.Activity;
4
import android.content.Intent;
5
import android.os.Bundle;
6
import android.view.View;
7
8
public class HomeActivity extends Activity {
9
    
10
	@Override
11
	protected void onCreate(Bundle savedInstanceState) {
12
		super.onCreate(savedInstanceState);
13
		setContentView(R.layout.activity_home);
14
	}
15
	
16
	public void showApps(View v){
17
		Intent i = new Intent(this, AppsListActivity.class);
18
		startActivity(i);
19
	}
20
}

En el método onCreate de la clase, invocamos setContentView, pasando la retícula que creamos anteriormente. Recordarás que agregamos un botón a la retícula activity_home que dispara un método llamado showApps. Ahora necesitamos implementar ese método en la clase HomeActivity. La implementación es bastante sencilla, creamos un Intent para la clase AppsListActivity y la iniciamos.

AppsListActivity

Crea otra clase Activity llamada AppsListActivity y establece android.app.Activity como su superclase. En el método de la clase onCreate, invocamos setContentView, pasando la retícula activity_apps_list que creamos anteriormente.

1
package ah.hathi.simplelauncher;
2
3
import android.app.Activity;
4
import android.content.Intent;
5
import android.os.Bundle;
6
import android.view.View;
7
8
public class AppsListActivity extends Activity {
9
    
10
	@Override
11
	protected void onCreate(Bundle savedInstanceState) {	
12
		super.onCreate(savedInstanceState);
13
		setContentView(R.layout.activity_apps_list);
14
	}
15
		
16
}

Aunque nuestro lanzador aún no está terminado, puedes guardarlo y ejecutar tu aplicación en este punto. Cuando presionas el botón de inicio de la aplicación, deberías ver una ventana emergente preguntando cuál lanzador te gustaría usar.

Si eliges Simple Launcher Home, deberías ver tu nueva pantalla de inicio con un solo botón en la esquina superior derecha de la pantalla. Deberías ver también el papel tapiz actual de tu dispositivo.

Regresa a Eclipse y crea una clase llamada AppDetail que contendrá los detalles de una aplicación, su nombre de paquete, etiqueta e icono de aplicación. La interfaz es bastante básica como puedes ver abajo.

1
package ah.hathi.simplelauncher;
2
3
import android.graphics.drawable.Drawable;
4
5
public class AppDetail {
6
        CharSequence label;
7
        CharSequence name;
8
        Drawable icon;
9
}

6. Recuperando Aplicaciones

En el método loadApps de la clase AppsListActivity, usamos el método queryIntentActivities de la clase PackageManager para recuperar todos los Intents que tienen una categoría de Intent.CATEGORY_LAUNCHER. La consulta devuelve una lista de las aplicaciones que pueden ser lanzadas por un lanzador. Recorremos los resultados de la consulta y agregamos cada elemento a una lista llamada apps. Echa un vistazo al siguiente código para clarificar.

1
private PackageManager manager;
2
private List<AppDetail> apps;	
3
private void loadApps(){
4
	manager = getPackageManager();
5
	apps = new ArrayList<AppDetail>();
6
	
7
	Intent i = new Intent(Intent.ACTION_MAIN, null);
8
	i.addCategory(Intent.CATEGORY_LAUNCHER);
9
	
10
	List<ResolveInfo> availableActivities = manager.queryIntentActivities(i, 0);
11
	for(ResolveInfo ri:availableActivities){
12
		AppDetail app = new AppDetail();
13
		app.label = ri.loadLabel(manager);
14
		app.name = ri.activityInfo.packageName;
15
		app.icon = ri.activityInfo.loadIcon(manager);
16
		apps.add(app);
17
	}
18
}

7. Mostrando la Lista de Aplicaciones

Con la variable apps conteniendo todos los detalles que necesitamos, podemos mostrar la lista de aplicaciones mostrando la clase ListView. Creamos un simple ArrayAdapter y sobreescribimos su método getView para generar los elementos de la lista. Después asociamos la ListView con el adaptador.

1
private ListView list;    
2
private void loadListView(){
3
	list = (ListView)findViewById(R.id.apps_list);
4
	
5
	ArrayAdapter<AppDetail> adapter = new ArrayAdapter<AppDetail>(this, 
6
			R.layout.list_item, 
7
			apps) {
8
		@Override
9
		public View getView(int position, View convertView, ViewGroup parent) {
10
			if(convertView == null){
11
				convertView = getLayoutInflater().inflate(R.layout.list_item, null);
12
			}
13
			
14
			ImageView appIcon = (ImageView)convertView.findViewById(R.id.item_app_icon);
15
			appIcon.setImageDrawable(apps.get(position).icon);
16
			
17
			TextView appLabel = (TextView)convertView.findViewById(R.id.item_app_label);
18
			appLabel.setText(apps.get(position).label);
19
			
20
			TextView appName = (TextView)convertView.findViewById(R.id.item_app_name);
21
			appName.setText(apps.get(position).name);
22
			
23
			return convertView;
24
		}
25
	};
26
	
27
	list.setAdapter(adapter);			
28
}

8. Escuchando Clics

Cuando el usuario hace clic en un elemento en la ListView, la aplicación correspondiente debería ser lanzada por nuestro lanzador. Usamos el método getLaunchIntentForPackage de la clase PackageManager para crear un Intent con el cuál iniciemos la aplicación. Echa un vistazo al siguiente código.

1
private void addClickListener(){    	
2
	list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
3
		@Override
4
		public void onItemClick(AdapterView<?> av, View v, int pos,
5
				long id) {
6
			Intent i = manager.getLaunchIntentForPackage(apps.get(pos).name.toString());
7
			AppsListActivity.this.startActivity(i);
8
		}
9
	});
10
}

9. Juntándolo Todo

Para hacer que todo trabaje junto, necesitamos invocar loadApps, loadListView, y addClickListener en el método onCreate de la clase AppsListActivity como se muestra abajo.

1
protected void onCreate(Bundle savedInstanceState) {	
2
	super.onCreate(savedInstanceState);
3
	setContentView(R.layout.activity_apps_list);
4
	
5
	loadApps();
6
	loadListView();
7
	addClickListener();
8
}

Construye y ejecuta tu aplicación una vez más para ver el resultado. Ahora deberías poder ver las aplicaciones que pueden ser lanzadas cuando hagas clic en el botón en la pantalla de inicio de nuestro lanzador. Haz clic sobre un elemento para lanzar la aplicación correspondiente.

Conclusión

Ahora tienes tu propio lanzador personalizado. Es muy básico, pero puedes agregar todas las personalizaciones que quieras. Si quieres indagar más en lanzadores personalizados, te aliento a echar un vistazo a las aplicaciones de muestra en el Portal de Desarrollador Android.