Diferencia entre revisiones de «PDM Activities»

De MediaWiki
Ir a la navegación Ir a la búsqueda
Línea 629: Línea 629:
 
:* startActivity(new Intent(“nome.definido.etiqueta.action”));  :Chamamos co nome definido na etiqueta action.
 
:* startActivity(new Intent(“nome.definido.etiqueta.action”));  :Chamamos co nome definido na etiqueta action.
 
:: Neste segundo caso teremos que definir unha categoría por defecto, para poder chamar a activity polo seu nome (<category android:name="android.intent.category.DEFAULT" />)
 
:: Neste segundo caso teremos que definir unha categoría por defecto, para poder chamar a activity polo seu nome (<category android:name="android.intent.category.DEFAULT" />)
 +
 +
 +
  
 
: Vexamos un exemplo:
 
: Vexamos un exemplo:
Línea 656: Línea 659:
  
 
* Nome dos action:
 
* Nome dos action:
:* Aínda que o action pode ter calquera nome, por convención se usa este formato nos action definidos por Android: '''.intent.action.nome_acción'''^.
+
:* Aínda que o action pode ter calquera nome, por convención se usa este formato nos action definidos por Android: '''.intent.action.nome_acción'''.
 
:: Por exemplo, 'android.intent.action.MAIN' é o action que define Android para unha activity de tipo 'Launcher'.
 
:: Por exemplo, 'android.intent.action.MAIN' é o action que define Android para unha activity de tipo 'Launcher'.
 
:* No caso das activities definidas por nos que non teñen un action 'predefinido' de Android, o name terá o formato: '''nome_paquete.nome_accion'''.
 
:* No caso das activities definidas por nos que non teñen un action 'predefinido' de Android, o name terá o formato: '''nome_paquete.nome_accion'''.
Línea 775: Línea 778:
  
 
<br />
 
<br />
 +
 
==Etiqueta category==
 
==Etiqueta category==
  

Revisión del 08:54 30 sep 2018

Introdución

  • Como xa comentamos antes, podemos identificar unha 'Activity' con cada unha das pantallas que conforman unha aplicación.
  • Isto non é totalmente certo, xa que podemos ter aplicacións que non teñan interface gráfica, coma os servizos, programas que se executan en segundo plano e que responden a un determinado tipo de evento.


  • Neste punto imos explicar os diferentes métodos polos que pasa unha Activity cando se crea, ponse en segundo plano ou se destrúe.
Indicaremos en cada un deles cales serían as principais funcións que poderíamos programar.
Tamén explicaremos como se define unha activity a nivel de proxecto.




Creando Activities

  • Cada vez que se crea unha activity, aparece unha nova entrada no arquivo AndroidManifiest.xml.
Vexamos un exemplo, e crearemos unha nova activity no asistente:


  • Como vimos no asistente, á hora de crear unha activity aparecen dúas opcións que non marcamos:
  • Launcher Acivity: Fai que dita activity poida ser lanzada ou executada de forma independente. Isto quere dicir que o resto de activities que non teñen marcada esta opción van necesitar ser invocadas dende outra activity. Ao crear unha activity e marcar esta opción, levará consigo dúas consecuencias:


  • A outra opción é a de Backwards Compatibility: Esta opción está colocada para facer uso das bibliotecas de compatibilidade de Android, xa vistas nesta wiki anteriormente.
Ao marcar esta opción teremos dúas consecuencias:


  • Indicar que nas opcións de configuración de execución do proxecto, podemos indicar, podemos indicar cal é a activity por defecto a lanzar (se non se especifica será a primeira que sexa de tipo launcher) e o emulador por defecto que vai lanzar:


  • Crea un novo paquete de nome 'tiposactivities' e move as activities creadas anteriormente a ese paquete.
Deixa a lo menos unha activity no paquete inicial, xa que se non a nivel gráfico o Android Studio o fai desaparecer.
Nota: Lembra, como sucede en Java, cada paquete se traduce nun cartafol a nivel de S.O.



Ciclo de vida das Activities


  • Cando se lanza unha activity esta pasa por unha serie de estados e eses estados chaman a unha serie de métodos.
00 basic-lifecycle.png

Nota: O estado Resumed: ven ser o estado de running.



  • Estes son os diferentes métodos e o que se debería facer en cada un deles:
  • Método onCreate:
  • Definir / instanciar variables – clases
  • Definir a interface do usuario.
Unha vez chamado o método onCreate chama os métodos onStart e onResume de forma consecutiva.


  • Método onDestroy: Chamado cando remata a aplicación e se libera da memoria do dispositivo. Tamén pode ser provocado polo S.O. para liberar espazo de memoria. Normalmente non se fai nada neste método, xa que a liberación de recursos se fai nos métodos onPause e onStop, pero se a aplicación usa background Threads ou outro recurso que poida consumir memoria, debe ser destruído neste evento.
Nota: Só hai un caso no que non pasa polos métodos de onPause e onStop, é cando destruímos a aplicación chamando o método finish() dende onCreate.


  • Método onPause: Cando unha aplicación, ocupa parte da pantalla, pero deixa visible parte de aplicación en execución, esta pasa a un estado de PAUSE (por exemplo unha caixa de diálogo aberta por unha aplicación). En caso contrario, se queda totalmente tapada pasa a o estado de STOP.
Ó volver do estado de Pause, se chama o método onResume.
Normalmente cando se chama o proc. onPause, é que a aplicación vai deixar de se usada por o usuario. Neste caso se aproveita este estado para facer:
  • Parar animacións ou outras actividades que consuman CPU.
  • Gardar a información que o usuario espera atopar se volve a cargar a aplicación (redacción dun correo sen rematar,…).
  • Liberar recursos do sistema, como transferencias, sensores (GPS), ou calquera recurso que poida afectar á batería (como a cámara).
Non se debe sobrecargar este método con ‘traballo’ pesado de liberación, xa que podemos enlentecer o paso ó seguinte estado. Para iso temos o método onStop.


  • Método onResume: Úsase este método para volver a crear aqueles recursos que liberamos no método onPause.
Hai que ter en conta que entramos neste método cando vimos de inicializar a aplicación e cando paramos a aplicación, polo que pode ser necesario verificar se xa estaban creados os recursos antes de volver a crealos.
Vexamos un suposto exemplo no que facemos uso da cámara. Como vemos comprobamos se o obxecto que vai facer uso da cámara está xa inicializado.
1     @Override
2     protected  void onResume(){
3         super.onResume();
4 
5         if (mCamara==null){
6             inicializarCamara();
7         }
8     }


  • Método onStop.
Existen uns poucos casos no que isto sucede:
  • Usuario abre outra aplicación ou vai as aplicación recentes e escolle outra. Ata que non volva á nosa aplicación, esta pasa a un estado de stop e se queda en segundo plano.
  • Usuario provoca a aparición doutra activity. A primeira activity é parada e comeza a segunda. Se o usuario preme o botón de ‘Volver’ a primeira actividade é reiniciada.
  • Usuario recibe unha chamada de teléfono.
Temos por tanto os métodos onStop e onRestart para dar soporte a estes eventos.
No método onStop é onde debemos facer as operación que máis leven de liberación de recursos coma poidan ser gardar datos nunha base de datos.
Nota: O sistema garda o estado das View, polo que os contidos de caixas de texto e outros recursos gráficos se manteñen ó reiniciar a aplicación. Soamente se perden se o S.O. necesita espazo en memoria e quita a aplicación do Stack, destruíndo todo. Nese caso se o usuario volve, os elementos gráficos estarían inicializados.


  • Método onRestart e método onStart:
Cando o sistema chama o método reiniciar tamén chama despois o método onStart (cada vez que aplicación se pon visible).
Debido a isto, se debe de inicializar os compoñentes que foron liberados no método onStop e tamén se debe aproveitar ese mesmo código cando se crea por primeira vez a aplicación.
Por exemplo, no método onStart se poden poñer as condicións necesarias para que poida funcionar a aplicación (coma por exemplo recursos que necesitemos, coma GPS, unha cámara,....).
No método onRestart se poden recuperar cursores de acceso a datos que foran pechados previamente no método onStop. Máis información neste enlace.




Recreando unha Activity

  • Existen varias casos que poden provocar a eliminación da nosa aplicación en segundo plano, coma son que non se usa en bastante tempo (e permaneza en background) ou que o sistema necesite memoria e teña que liberar recursos coma son os procesos en background.
  • Nestes casos, se o usuario quere volver á nosa aplicación, o sistema operativo garda anteriormente o ‘estado’ en que quedou a nosa aplicación, no que se coñece coma ‘instance state’ ou estado de instancia. Dito estado está gardado nun obxecto da clase Bundle que garda pares de clave-valor.
Por iso cando volvemos os elementos gráficos están tal como os deixamos (caixas de texto con datos, elementos de lista escollidos,...)
Soamente se se destrúe a aplicación (por necesidades de memoria, por exemplo) estes datos se perden.


Nota: cando un usuario move a pantalla e a reorienta noutra dirección, a aplicación se destrúe e se volve a crear.


  • Seguramente a aplicación ten outra información aparte do estado das View´s que é necesario recuperar, como as variables usadas para gardar o progreso do usuario ou calquera outra información que nos como programadores queiramos gardar.
Para iso existe o método onSaveInstanceState que chama o sistema cando a aplicación pasa a segundo plano ou se destrúe.
PDM Activity 16.jpg


A este método lle pasa o obxecto da clase Bundle onde está gardada toda a información (view´s) da aplicación, polo que o programador pode engadir máis información para ser recuperada posteriormente se o sistema volta a chamar a aplicación, xa que lle volve a pasar o mesmo obxecto da clase Bundle.
O obxecto da clase Bundle funciona en base a pares CLAVE-VALOR. A clave e o identificar do valor que se vai pasar. Ven ser como o nome dunha variable en programación.
Así teremos:
  • método putXXXXX(CLAVE,VALOR) sendo XXXXX un tipo de dato, por exemplo, putInt(), para engadir datos ao obxecto Bundle.
  • método getXXXXX(CLAVE)' sendo XXXXX un tipo de dato, por exemplo, getInt(), par recuperar o valor dun elemento clave gardado.
Por exemplo, se quero gardar unha cadea nunha 'clave' de nome 'LOGIN', poñería:
obxectoBundle.putString("LOGIN","CADEA A GARDAR");
Se quere recuperar dito valor, no mesmo obxecto bundle:
String login = obxectoBundle.getString("LOGIN");


Loxicamente o nome da clave ten que ser a mesma cando gardamos o dato e cando o introducimos.


  • Cando a aplicación se re-inicializa (isto é, cando se rota o dispositivo ou volvemos a aplicación unha vez que o S.O. liberou a súa memoria por necesidade) se chama ao método onRestoreInstanceState, onde se recuperan os datos gardados.
Nota: Antes de chegar o estado Resumed pasa polo estado Started.


  • Exemplo:
1 	@Override
2 	public void onSaveInstanceState(Bundle datosgardados){
3 		
4 		datosgardados.putInt(POSICION,reproductor.getPosicionActualCancion());
5 		datosgardados.putString(CANCION,reproductor.cancionactual);
6 
7 		// SEMPRE O CODIGO POSTO POR NOS ANTES DA CHAMADA A SUPER.
8 		super.onSaveInstanceState(datosgardados);
9 }


Para restaurar o sistema usaremos o método onRestoreInstanceState.
 1 	@Override
 2 	public void onRestoreInstanceState(Bundle datosgardados){
 3 		
 4 			super.onRestoreInstanceState(datosgardados);
 5 
 6 			// CODIGO POSTO POR NOS PARA RECUPERAR OS DATOS, SEMPRE DESPOIS 
 7 			// DA CHAMADA A SUPER	
 8 			reproductor.cancionactual=datosgardados.getString(C_DATOCANCION_PECHAR);
 9 			reproductor.posicioncancion=datosgardados.getInt(C_DATOPOSCANCION_PECHAR);
10 	
11 }
Nota: É importante chamar os métodos super.XXXXX na orde indicada no exemplo anterior.


  • Imos ver un exemplo práctico disto.
Crea un novo paquete de nome gardandoestado.
Dentro do paquete crea unha nova clase de tipo Launcher Activity de nome UD2_01_gardando_estado.
Cambia o contido do arquivo do Layout XML por este:


 1 <?xml version="1.0" encoding="utf-8"?>
 2 <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:app="http://schemas.android.com/apk/res-auto"
 4     xmlns:tools="http://schemas.android.com/tools"
 5     android:layout_width="match_parent"
 6     android:layout_height="match_parent"
 7     tools:context=".gardandoestado.UD2_01_gardando_estado">
 8 
 9 
10     <EditText
11         android:id="@+id/editText"
12         android:layout_width="wrap_content"
13         android:layout_height="wrap_content"
14         android:layout_marginBottom="8dp"
15         android:layout_marginEnd="8dp"
16         android:layout_marginStart="8dp"
17         android:layout_marginTop="8dp"
18         android:ems="10"
19         android:inputType="textPersonName"
20         android:text="Name"
21         app:layout_constraintBottom_toBottomOf="parent"
22         app:layout_constraintEnd_toEndOf="parent"
23         app:layout_constraintStart_toStartOf="parent"
24         app:layout_constraintTop_toTopOf="parent"
25         app:layout_constraintVertical_bias="0.073" />
26 
27     <Button
28         android:id="@+id/button1"
29         android:layout_width="wrap_content"
30         android:layout_height="wrap_content"
31         android:layout_marginEnd="8dp"
32         android:layout_marginStart="8dp"
33         android:layout_marginTop="84dp"
34         android:text="Dar Valor"
35         app:layout_constraintEnd_toEndOf="parent"
36         app:layout_constraintStart_toStartOf="parent"
37         app:layout_constraintTop_toBottomOf="@+id/editText" />
38 
39     <Button
40         android:id="@+id/button2"
41         android:layout_width="wrap_content"
42         android:layout_height="wrap_content"
43         android:layout_marginEnd="8dp"
44         android:layout_marginStart="8dp"
45         android:layout_marginTop="48dp"
46         android:text="Ver valor"
47         app:layout_constraintEnd_toEndOf="parent"
48         app:layout_constraintStart_toStartOf="parent"
49         app:layout_constraintTop_toBottomOf="@+id/button1" />
50 
51 </android.support.constraint.ConstraintLayout>


  • Cambio o contido da activity por este:
 1 package es.cursoandroid.cifprodolfoucha.aprendiendo.gardandoestado;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.view.View;
 6 import android.widget.Button;
 7 import android.widget.Toast;
 8 
 9 import es.cursoandroid.cifprodolfoucha.aprendiendo.R;
10 
11 
12 public class UD2_01_gardando_estado extends Activity {
13 
14     private int valor = 0;
15 
16     @Override
17     protected void onCreate(Bundle savedInstanceState) {
18         super.onCreate(savedInstanceState);
19         setContentView(R.layout.activity_ud2_01_gardando_estado);
20 
21         Button btnBoton1 = findViewById(R.id.button1);
22         btnBoton1.setOnClickListener(new View.OnClickListener() {
23             @Override
24             public void onClick(View v) {
25                 valor = 5;
26                 Toast.makeText(getApplicationContext(), "Valor: " + valor, Toast.LENGTH_LONG).show();
27             }
28         });
29 
30         Button btnBoton2 = findViewById(R.id.button2);
31         btnBoton2.setOnClickListener(new View.OnClickListener() {
32             @Override
33             public void onClick(View v) {
34                 Toast.makeText(getApplicationContext(), "Valor: " + String.valueOf(valor), Toast.LENGTH_LONG).show();
35             }
36         });
37 
38 
39     }
40 }


  • Se executamos esta aplicación podemos comprobar como cando se inicia o valor da variable vale 0.
Modificaremos o contido da caixa de texto e premeremos no botón.
Nese intre a nivel de programación a variable vale 5.
PDM Activity 20.jpg


Se marchamos da aplicación e volvemos, podemos comprobar como o contido da caixa de texto permanece e se prememos sobre o botón 'Ver Valor' tamén gardou o dato.
Neste caso non teríamos que gardar o estado de nada para que a aplicación continuase (noutro caso, por exemplo, nun reprodutor de música poderíamos gardar a posición da canción que está sendo reproducida).
Pero que pasa se o S.O. necesita memoria e elimina dita aplicación do Stack ?
Tamén pasa o mesmo cando rotamos o dispositivos. A activity se 'recrea' novamente.
PDM Activity 21.jpg
Os datos perdéronse.
  • Imos modificar o código para que se garden os datos introducidos:
 1 package es.cursoandroid.cifprodolfoucha.aprendiendo.gardandoestado;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.view.View;
 6 import android.widget.Button;
 7 import android.widget.Toast;
 8 
 9 import es.cursoandroid.cifprodolfoucha.aprendiendo.R;
10 
11 
12 public class UD2_01_gardando_estado extends Activity {
13 
14     private int valor = 0;
15 
16     @Override
17     public void onSaveInstanceState(Bundle datosgardados){
18 
19         datosgardados.putInt("VALOR",valor);
20 
21         // SEMPRE O CODIGO POSTO POR NOS ANTES DA CHAMADA A SUPER.
22         super.onSaveInstanceState(datosgardados);
23     }
24 
25     @Override
26     public void onRestoreInstanceState(Bundle datosgardados){
27         super.onRestoreInstanceState(datosgardados);
28 
29         // CODIGO POSTO POR NOS PARA RECUPERAR OS DATOS, SEMPRE DESPOIS
30         // DA CHAMADA A SUPER
31         valor   = datosgardados.getInt("VALOR");
32 
33     }
34 
35 
36     @Override
37     protected void onCreate(Bundle savedInstanceState) {
38         super.onCreate(savedInstanceState);
39         setContentView(R.layout.activity_ud2_01_gardando_estado);
40 
41         Button btnBoton1 = findViewById(R.id.button1);
42         btnBoton1.setOnClickListener(new View.OnClickListener() {
43             @Override
44             public void onClick(View v) {
45                 valor = 5;
46                 Toast.makeText(getApplicationContext(), "Valor: " + valor, Toast.LENGTH_LONG).show();
47             }
48         });
49 
50         Button btnBoton2 = findViewById(R.id.button2);
51         btnBoton2.setOnClickListener(new View.OnClickListener() {
52             @Override
53             public void onClick(View v) {
54                 Toast.makeText(getApplicationContext(), "Valor: " + String.valueOf(valor), Toast.LENGTH_LONG).show();
55             }
56         });
57 
58 
59     }
60 }



  • Podemos comprobar como agora ao rotar a pantalla os datos permanecen.
PDM Activity 22.jpg



  • Neste caso o view é gardado polo propio android, xa que todos os view´s cun id posto gardan o seu estado.
De todas formas pode ser necesario gardar o estado dalgún view, xa que pode ser inicializado no método onStart.
Por exemplo, cargar unha ListBox cun conxunto de datos da base de datos, que o usuario elixa un deses datos.
Se nese momento a actividade se recrea, ao iniciarse, se volverían a cargar os datos da ListBox, pero a elección do usuario se perdería.




Intent en Activities

  • Para lanzar outra activity se fai uso dos Intent.
  • Nota Importante: En Android cando lanzamos unha nova activity, a anterior queda en memoria formando unha cola LIFO. O pechar a nova activity aparecerá a anterior. SE QUEREMOS PECHAR UNHA ACTIVITY PARA ABRIR UNHA NOVA DEBEMOS DE ABRIR A NOVA ACTIVITY E CHAMAR Ó MÉTODO finish() da activity que chama.



Construíndo un Intent


  • A efectos prácticos, unha activity vense a identificar cunha pantalla. Os intent´s vannos servir para chamar a ditas pantallas entre outras cousas.
Tamén van servir para chamar a outras aplicacións ANDROID e esperar unha resposta (ou non).
  • Un intent prové un enlace entre diferentes compoñentes coma poden ser dúas activity´s. Se pode traducir coma a intención da aplicación de facer algo.
Cando chama, o pode facer indicando a Activity que quere lanzar (Intent Explícitos) ou simplemente indica a acción que quere realizar e é o S.O. quen decide en base a acción e o tipo de información, que aplicación debe lanzar (Intent Implícitos).


  • Para chamar a unha activity dende outra temos o seguinte código:
1 Intent intent = new Intent(this, DisplayMessageActivity.class);


  • O primeiro parámetro é unha referencia ó contexto (a clase Activity é unha subclase de Context, por iso poñemos this).
O segundo parámetro é a clase que o Sistema Operativo ‘intentará’ cargar (no noso caso a activity a cargar).


  • Nota: O context é unha interface que nos permite acceder os recursos da aplicación, clases e outras operacións, como acceso as activities…


  • Imos velo cun exemplo.
Indicar que no exemplo aparece código que aínda non vimos.
Deberedes centrarvos no uso do Intent. Volveremos posteriormente a este código cando avancemos nas explicacións.




  • Faremos unha pantalla cun botón e ao premelo, lanzaramos a segunda activity.
Esta segunda activity terá un botón para pecharse.
Crea unha 'Empty Activity' de nome UD02_01_A1_activities (UD2, Exercicio01, A1, sección Activities), sen compatibilidade y de tipo 'launcher'.
O código XML do layout:
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:tools="http://schemas.android.com/tools"
 4     android:layout_width="match_parent"
 5     android:layout_height="match_parent" >
 6 
 7 
 8     <Button
 9         android:id="@+id/button"
10         android:layout_width="wrap_content"
11         android:layout_height="wrap_content"
12         android:layout_alignParentStart="true"
13         android:layout_alignParentTop="true"
14         android:text="Lanzar"
15         android:onClick="lanzar_activity"
16         />
17 </RelativeLayout>



Crea unha 'Empty Activity' de nome UD02_01_A2_activities (UD2, Exercicio01, Acivity 2ª, sección Activities), sen compatibilidade y non 'launcher'.
O código XML do layout:
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:app="http://schemas.android.com/apk/res-auto"
 4     xmlns:tools="http://schemas.android.com/tools"
 5     android:layout_width="match_parent"
 6     android:layout_height="match_parent"
 7     tools:context=".activities.UD02_01_A2_activities">
 8 
 9     <TextView
10         android:id="@+id/textView"
11         android:layout_width="135dp"
12         android:layout_height="24dp"
13         android:layout_marginStart="8dp"
14         android:layout_marginTop="8dp"
15         android:text="Segunda Activity"
16         app:layout_constraintStart_toStartOf="parent"
17         app:layout_constraintTop_toTopOf="parent" />
18 
19     <Button
20         android:id="@+id/button3"
21         android:layout_width="wrap_content"
22         android:layout_height="wrap_content"
23         android:layout_marginStart="28dp"
24         android:layout_marginTop="24dp"
25         android:text="Pechar"
26         app:layout_constraintStart_toStartOf="parent"
27         android:onClick="pecharActivity"
28         />
29 </android.support.constraint.ConstraintLayout>



  • O código da activity UD02_01_A1_activities:
 1 package es.cursoandroid.cifprodolfoucha.aprendiendo.activities;
 2 
 3 import android.app.Activity;
 4 import android.content.Intent;
 5 import android.os.Bundle;
 6 import android.view.View;
 7 
 8 import es.cursoandroid.cifprodolfoucha.aprendiendo.R;
 9 
10 public class UD02_01_A1_activities extends Activity {
11 
12     protected void lanzar_activity(View v){
13         Intent intent = new Intent(getApplicationContext(),UD02_01_A2_activities.class);    // INTENT EXPLICITO
14         startActivity(intent);
15     }
16 
17     @Override
18     protected void onCreate(Bundle savedInstanceState) {
19         super.onCreate(savedInstanceState);
20         setContentView(R.layout.activity_ud02_01__a1_activities);
21     }
22 }


  • O código da segunda activity UD02_01_A2_activities:
 1 package es.cursoandroid.cifprodolfoucha.aprendiendo.activities;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.view.View;
 6 
 7 import es.cursoandroid.cifprodolfoucha.aprendiendo.R;
 8 
 9 public class UD02_01_A2_activities extends Activity {
10 
11     protected void pecharActivity(View v){
12         finish();
13     }
14 
15 
16     @Override
17     protected void onCreate(Bundle savedInstanceState) {
18         super.onCreate(savedInstanceState);
19         setContentView(R.layout.activity_ud02_01__a2_activities);
20     }
21 }


  • Se executamos a primeira activity podemos comprobar como ao premer no botón aparece a segunda activity a cal pode ser pechada ao premer no botón 'Pechar'.



Etiqueta Action

  • Como vimos anteriormente, cada vez que se crea unha activity se engade no AndroidManifiest.xml.
Dita activity ten asociado un filtro de intento (<intent-filter>) ou podemos engadirllo en caso de non ser un tipo 'launcher'.
Dentro deste temos a etiqueta <action....> no que se define o nome do filtro para a activity.
Desta forma podemos chamar a outra activity polo seu nome:
  • startActivity(new Intent(this,NomeClase.class); :Esta é a opción vista ata o de agora.
  • startActivity(new Intent(“nome.definido.etiqueta.action”)); :Chamamos co nome definido na etiqueta action.
Neste segundo caso teremos que definir unha categoría por defecto, para poder chamar a activity polo seu nome (<category android:name="android.intent.category.DEFAULT" />)



Vexamos un exemplo:
 1         <activity
 2             android:name="com.example.variasactiviy.MainActivity1"
 3             android:label="@string/app_name1" >
 4             <intent-filter>
 5                 <action android:name="android.intent.action.MAIN" />
 6                 <category android:name="android.intent.category.LAUNCHER" />
 7             </intent-filter>
 8         </activity>
 9         <activity
10             android:name="com.example.variasactiviy.MainActivity2"
11             android:label="@string/app_name2" >
12             <intent-filter>
13                 <action android:name="com.example.variasactiviy.ActionMainActivity2" />
14    	        <category android:name="android.intent.category.DEFAULT" />
15             </intent-filter>
16         </activity>
Para chamar a segunda activity:
1 startActivity(new Intent("com.example.variasactiviy.ActionMainActivity2"));
  • Nome dos action:
  • Aínda que o action pode ter calquera nome, por convención se usa este formato nos action definidos por Android: .intent.action.nome_acción.
Por exemplo, 'android.intent.action.MAIN' é o action que define Android para unha activity de tipo 'Launcher'.
  • No caso das activities definidas por nos que non teñen un action 'predefinido' de Android, o name terá o formato: nome_paquete.nome_accion.
No exemplo anterior: com.example.variasactiviy.ActionMainActivity2
Unha activity pode levar varias accións asociadas.
Se existen varias activities co mesmo nome o S.O. amosará unha mensaxe para que escollamos cal delas debe abrir.


  • Os intent´s vainos servir para chamar a outras aplicacións que estean instaladas no sistema operativo Android. A idea é chamar a unha aplicación cun tipo de dato, e que sexa o S.O. en base os 'filter' das aplicacións instaladas, o que chame á aplicación correspondente.

Dentro do Intent irán os datos necesarios para que a aplicación que reciba a petición poida dar o servizo. Así, se abro o navegador, podo enviarlle a url que quero que abra (é opcional mandalo). Para mandar os datos faremos uso do método putExtra da clase Intent (o veremos despois noutro punto).

Así, grazas a esta forma de traballar, podemos usar Intent´s:
  • Para chamar a un teléfono
  • Para enviar un sms/correo
  • Para abrir o navegador
  • Para abrir unha localización dentro dun mapa
  • Ou para chamar a Activities doutras aplicacións.


Por exemplo:
  • Un intent para enviar un correo electrónico:
1 Intent intent = new Intent(Intent.ACTION_SEND);
2 intent.setType("application/octet-stream");
3 intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
4 intent.putExtra(Intent.EXTRA_TEXT, "Texto do Mail");
5 intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"android@cursoandroid.es"});
6 startActivity(intent);
  • Un intent para amosar o dial de teléfono:
1 Intent intent = new Intent(Intent.ACTION_DIAL);
2 startActivity(intent);
  • Un intent para lanzar unha busca do navegador web:
1 Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
2 intent.putExtra(SearchManager.QUERY, "Android");
3 startActivity(intent);



  • A un Intent podemos asociarlle unha acción, uns datos e unha categoría.
As activities poden declarar o tipo de accións que poden levar a cabo e os tipos de datos que poden xestionar.
As accións son cadeas de texto estándar que describen o que unha activity pode facer.
Por exemplo android.intent.action.VIEW é unha acción que indica que a actividade pode amosar datos ó usuario.
Máis información en:
Cando definimos unha activity normalmente aparece isto no AndroidManifiest,xml:
1         <activity
2             android:name=".MainActivity"
3             android:label="@string/title_activity_main" >
4             <intent-filter>
5                 <action android:name="android.intent.action.MAIN" />
6                 <category android:name="android.intent.category.LAUNCHER" />
7             </intent-filter>
8         </activity>
Como vemos temos:
  • <action android:name="android.intent.action.MAIN" />: indica que é unha activity inicial que non se lle vai a enviar datos nin devolver datos.
  • <category android:name="android.intent.category.LAUNCHER" />: indica que a activity pode ser a actividade inicial dunha tarefa.


Outro exemplo sería o seguinte:
1    <intent-filter >
2 		<action android:name="android.intent.action.VIEW" />
3 		<category android:name="android.intent.category.DEFAULT" />
4 		<category android:name="android.intent.category.BROWSABLE" />
5 		<data android:scheme="http" android:pathPattern=".*mp3" android:mimeType="audio/*" />
6   </intent-filter>
Neste caso cando esteamos navegando, ó premer sobre unha canción mp3 abrirase a posibilidade de reproducila coa nosa activity. Xa dentro da nosa activity, o dato que podemos obter é a URL da canción a reproducir os poderíamos obter da seguinte forma:
1 	Intent intent = getIntent();
2         // Por se voltamos do navegador web.
3         if (intent != null && intent.getData() != null) {	
4 	        TextView txturl = (TextView)findViewById(R.id.txtURL);
5 	        txturl.setText(intent.getData().toString());
6         }



  • No caso da ACTION_VIEW é unha acción moi xenérica e Android ten que descubrir que activity pode chamar facendo uso da composición da URI.
Para iso mira o esquema que posúe a URI (neste caso http) e pregunta a todas as actividades cal delas entende dito esquema.
Poderíamos ter rexistrados varios esquemas:
1 <activity ...>
2    <intent -filter>
3       <action android:name="android.intent.action.VIEW"/>
4       <data android:scheme="http" />
5       <data android:scheme="https" />
6    </intent>
7 </activity>
Máis información sobre a etiqueta en http://developer.android.com/guide/topics/manifest/data-element.html



Etiqueta category

  • No que se refire a etiqueta <category> esta se utiliza para categorizar as activities e que se podan atopar máis facilmente.


  • Anteriormente vimos un exemplo no que tiñamos: <category android:name="android.intent.category.BROWSABLE" />
Se ides o enlace anterior e buscades dita categoría, vos informa que dita categoría é necesaria para que unha activity sexa chamada dende o navegador.
Por exemplo, mentres que o sistema se está iniciando busca as activities que teñan a category de launcher: <category android:name="android.intent.category.LAUNCHER" />


Por exemplo, poderíamos lanzar unha activity en base a súa categoría:
1 		Intent intento = new Intent(Intent.ACTION_MAIN, null);
2 		intento.addCategory(Intent.CATEGORY_LAUNCHER);
3 		startActivity(i);

Dará como resultado:

PDM Activity 25.jpg




Pasando datos entre activities


-- Ángel D. Fernández González -- (2018).