Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... ·...

136
Android Cristobal Raya Giner Programació de Dispositius Mòbils (PDMO)

Transcript of Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... ·...

Page 1: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Android

Cristobal Raya Giner

Programació de Dispositius Mòbils (PDMO)

Page 2: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Carpetes

Un projecte Android està format pelfitxer AndroidManifest.xml que és undescriptor de l’aplicació, el codi Font enJava i uns fitxers de recursos. Cadaelement es troba en una carpetaespecífica.

Page 3: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Carpetes

• src: Carpeta que conté el codi font de l’aplicació. Els fitxers s’emmagatzemen en un espai de noms o paquet.

• gen: Carpeta que conté el codi generat de forma automàtica pel SDK. MAI s’han de modificar de forma manual aquests fitxers. – BuildConfig.java: Defineix la constant DEBUG per que des de Java

puguis saber si l’aplicació està en fase de desenvolupament.– R.java: Defineix una classe que associa els recursos de l’aplicació amb

identificadors. Així es podrà accedir als recursos des de Java.

Page 4: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Carpetes• Android x.x: Codi JAR, l’API d’Android segons la versió seleccionada.• Android Dependencies: Llibreries associades al projecte.• assets: Carpeta que pot contenir fitxers o carpetes que podran ser

utilitzats per l’aplicació (fitxers de dades, fonts,…). A diferencia de lacarpeta res, mai es modifica el contingut dels fitxers d’aquesta carpeta nise les associarà un identificador.

• bin: En aquesta carpeta es compila el codi i es genera el .apk, fitxercomprimit que conté l’aplicació final llista per instal·lar.

• libs: Codi JAR amb les llibreries que es vulguin utilitzar al projecte. S’haafegit una llibreria android-support que afegeix noves funcionalitats queno apareixien en el nivell de API 4 i que van aparèixer en versions mésnoves del SDK.

Page 5: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Carpetes• res: Aquesta carpeta conté els recursos utilitzats per l’aplicació. Les subcarpetes

poden tenir un sufix si es vol que el recurs es carregui només en funció d’una. Per exemple –ldpi significa que només ha de utilitzar els recursos de la carpeta quan el dispositiu on s’instal·la l’aplicació té una densitat gràfica baixa (~120dpi); -v14 significa que el recurs només solo ha de carregar en un dispositiu amb nivell de API 14 (v4.0).

– drawable: En aquesta carpeta s'emmagatzemen els fitxers d’ imatges (JPG o PNG) i descriptors d’imatges en XML.

– layout: Conté fitxers XML amb les vistes (views) de l’aplicació. Les vistes ens permetran configurar les diferents pantalles que componen la interfície d’usuari de l’aplicació.

– menu: Fitxers XML amb els menús de cada activitat.– values: Utilitza fitxers XML per a indicar valors del tipus string, color o estil. Així podrem canviar els

valors sense necessitat de modificar el codi font. Per exemple, canviar d’idioma.– anim, animator: Conté fitxers XML amb animacions.– xml: Altres fitxers XML requerit per l’aplicació.– raw: Fitxers addicionals que no és troben en format XML.

Page 6: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Carpetes• AndroidManifest.xml: Aquest fitxer descriu l’aplicació Android. S’indiquen

les activitats, intents, serveis i proveïdors de contingut de l’aplicació. Es declaren els permisos que requerirà l’aplicació. S’indica les versions d’Android per a executar-la, el paquet Java, etc.

• ic_launcher-web.png: Icona gran de l’aplicació per a utilitzar-se en pàgines Web. El nombre pot variar en el procés de creació del projecte. Ha de tenir una resolució de 512x512.

• proguard-project.txt: Fitxer de configuració de l’eina ProGuard, que permet optimitzar i amagar el codi generat, i s’obté un .apk més petit per a dificultar d’enginyeria inversa.

• default.properties: Fitxer generat automàticament per el SDK. No s’ha de modificar. S’utilitza per a comprovar la versió del API i altres característiques quan s’instal·la l’aplicació al terminal.

Page 7: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Activitats (Activities)Una Activitat és un component de l’aplicació que proporciona una pantalla amb la queels usuaris poden interactuar per a fer alguna activitat com veure una pàgina web, feruna foto, trucar, etc... Cada activitat té una interfície d’usuari en una finestra quenormalment omple la pantalla, o que pot ser menor que la pantalla i encabir-se enaltres finestres, i un codi en java amb el programa associat a la activitat.Una aplicació consisteix generalment en múltiples activitats unides entre sí.Normalment hi ha una activitat principal (MainActivity) que es presenta a l’iniciarl’aplicació. Cada activitat es pot iniciar des de una altra activitat per tal de realitzardiferents accions.Les activitats es creen com a subclasses de la classe Activity:

public class MainActivity extends Activity { }

Aquest és l’arbre de parentesc de la classe Activity:java.lang.Object↳ android.content.Context↳android.content.ContextWrapper↳ android.view.ContextThemeWrapper↳ android.app.Activity

Page 8: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Clase ViewLa classe View (vista) representa el bloc de construcció bàsic per als components de lainterfície d’usuari de les activitats. És un objecte que ocupa un àrea rectangular a lapantalla, es pot dibuixar i és la classe base per al components interactius de lainterfície d’usuari o “widgets” (botons, imatges, text,...). Per exemple la classe per amostrar text s’anomena TextView, i és una subclasse de la classe View.java.lang.Object↳ android.view.View↳ android.widget.TextView

Android facilita la creació de les pantalles associades a les activitats mitjançant Layoutsen format XML. Una vegada creat fitxer amb el layout de l’activitat, aquest s’had’associa a la vista de l’activitat en el codi java. Per exemple per a associar un layoutanomenat “activity_main” s’afegeix el codi:

setContentView(R.layout.activity_main);

Page 9: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

LAYOUTS

Cristobal Raya Giner

Programació de Dispositius Mòbils (PRDM)

Page 10: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Layouts Bàsics

• LinearLayout: Disposa elements en una fila o columna

• TableLayout: Distribueix en forma de taula• RelativeLayout: Disposa en relació a altre o al

pare• AbsoluteLayout: Posiciona de forma absoluta• FrameLayout: Permet el canvi dinàmic el

elements.

Page 11: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Paràmetres del Layout

• Gravity, indica l’alineació de l’element en el contenidor: Esquerra, dreta, centrat, a dalt, a baix, ….

• Width / Height: Ajusta l’ample / alt de l’element– Match_parent (Fill_parent): L’element s’ajusta a la mida del

contenidor pare– Wrap_content: L’element s’ajusta al contingut

• Margins: Indica els marges de l’element respecte al contenidor en forma numèrica (px, mm, in, pt, dp, dip, sp)

Page 12: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Botó Hora Actual – activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context=".MainActivity" >

<Button

android:id="@+id/button"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:layout_centerHorizontal="true"

android:layout_centerVertical="true"

android:text="@string/boton" />

</RelativeLayout>

Crearem un botó que al polsar actualitzarà l’hora.Primer creem un Layout am un botó que ocupi tota la pantalla dins d’un RelativeLayout (o altre Layout):

Page 13: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Botó Hora Actual – MainActivity.javaimport android.os.Bundle;import android.app.Activity;import android.view.Menu;import android .view.View;import android.widget.Button;import java.util.Date;public class MainActivity extends Activity {Button btn;

@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);

btn=(Button)findViewById(R.id.button);

actualitzaTemps();

btn.setOnClickListener(new View.OnClickListener() {public void onClick(View view) {

actualitzaTemps();

};

});

}

private void actualitzaTemps() {btn.setText(new Date().toString());

}

Afegim el codi corresponent al fitxer .java principal de l’activitat:

http://developer.android.com/reference/java/util/Date.html

Page 14: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Format de l’hora

import java.text.SimpleDateFormat;import java.util.Date;

private void actualitzaTemps() {SimpleDateFormat sdf = new SimpleDateFormat("EEEE dd/MM/yyyy, HH:mm:ss");String DataFormatada = sdf.format(new Date());btn.setText(DataFormatada);

}

Per a modificar el format de la data i hora, podem canviar el format. Amb el següent codi el formatem per a que es vegi com:

Dimecres 11/Setembre/2013, 17:14:00

http://developer.android.com/reference/java/text/SimpleDateFormat.html

Page 15: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Dos botons

public class MainActivity extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);

final TextView Texte=(TextView)findViewById(R.id.vistatext);Button btn1=(Button)findViewById(R.id.button1);

Button btn2=(Button)findViewById(R.id.button2);

btn1.setOnClickListener(new View.OnClickListener() {public void onClick(View view) {

Texte.setText("Has polsat el primer botó");

};

});

btn2.setOnClickListener(new View.OnClickListener() {public void onClick(View view) {Texte.setText("Has polsat el segon botó");

};

});

}

Primer crea un Layout vertical amb un text i 2 botons:

Page 16: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Dos Botons Alternatiu 1public class MainActivity extends Activity{Button btn1,btn2;

TextView Texte;

@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);

Texte=(TextView)findViewById(R.id.vistatext);

btn1=(Button)findViewById(R.id.button1);

btn1.setOnClickListener(Escoltador);

btn2=(Button)findViewById(R.id.button2);

btn2.setOnClickListener(Escoltador);

}

View.OnClickListener Escoltador = new View.OnClickListener() {public void onClick(View v) {

if(((Button)v).getId()== btn1.getId() ){

Texte.setText("Has polsat el primer botó");

}

else if(v.getId()==findViewById(R.id.button2).getId()) {

Texte.setText("Has polsat el segon botó");

}

}

};

Amb el mateix layout, utilitzem només un mètode OnClickListener :

Page 17: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Dos Botons Alternatiu 2public class MainActivity extends Activity implements OnClickListener {Button btn1,btn2;

TextView Texte;

@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);

Texte=(TextView)findViewById(R.id.vistatext);

View btn1=findViewById(R.id.button1);

btn1.setOnClickListener(this);View btn2=findViewById(R.id.button2);

btn2.setOnClickListener(this);}

@Override

public void onClick(View v) {if(v.getId()==findViewById(R.id.button1).getId())

{

Texte.setText("Has polsat el primer botó");

}

else if(v.getId()==findViewById(R.id.button2).getId()) {

Texte.setText("Has polsat el segon botó");

}

}

Amb el mateix layout, ara s’implementa OnClickListener en la mateixa activitat:

Page 18: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Alternativa Botons

import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.TextView;

public class MainActivity extends Activity {TextView texte;

@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);

texte=(TextView)findViewById(R.id.textView1);

}

public void boto_pulsat(View v){texte.setText("Botó polsat");

}

}

Hi ha una altre alternativa a la pulsació dels botons, cridant a un mètode per a unobjecte View, mitjançant la propietat On Click del botó :

Page 19: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Demanar Text

http://developer.android.com/reference/android/widget/EditText.html

Crearem un layout amb almenys 3 camps de entrada de text del tipus EditText, un de tipus TextView, i un botó. L’activitat ens permetrà introduir per separat el nom i els dos cognoms, i al polsar el botó mostrarà el nom complert.

Page 20: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Demanar Textimport android.widget.Button;import android.widget.EditText;import android.widget.TextView;import android.view.View;public class MainActivity extends Activity {Button btn;TextView nomcomplert;EditText nom, cognom1,cognom2;

@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);nom=(EditText) findViewById(R.id.editnom);cognom1=(EditText) findViewById(R.id.editcognom1);cognom2=(EditText) findViewById(R.id.editcognom2);nomcomplert=(TextView) findViewById(R.id.nomcomplert);btn=(Button) findViewById(R.id.button1);btn.setOnClickListener(new View.OnClickListener() {

@Overridepublic void onClick(View arg0) {String nomjunt=nom.getText().toString()+" "+cognom1.getText().toString()+“ “ +

cognom2.getText().toString();nomcomplert.setText(nomjunt);

}});

}

Proveu canviar el paràmetre InputType de algún EditText, per exemple a textPassword

Page 21: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

CheckBoxpublic class CheckBoxDemo extends Activity implements CompoundButton.OnCheckedChangeListener {CheckBox cb;

@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_check_box_demo);

cb=(CheckBox)findViewById(R.id.check);cb.setOnCheckedChangeListener(this);

}

@Overridepublic void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {// TODO Auto-generated method stubif (isChecked) {

cb.setText(“El checkbox està: Activat");}else {cb.setText(" El checkbox està: Desactivat ");}

}}

Creem un layout només amb un widget Checkbox.

Page 22: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

RadioButtonimport android.widget.RadioButton;import android.widget.CompoundButton;import android.widget.CompoundButton.OnCheckedChangeListener;

public class MainActivity extends Activity {RadioButton rb;

@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);

rb=(RadioButton) findViewById(R.id.RadioButton1);

rb.setOnCheckedChangeListener(new OnCheckedChangeListener(){public void onCheckedChanged(CompoundButton arg0, boolean arg1) {

if (arg1) {rb.setText("Está activado");

}

else{rb.setText("Está desactivado");

}

}

});

}

Creem un layout només amb un widget RadioButton

Page 23: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Radio Group (1)

import android.widget.RadioButton;import android.widget.RadioGroup;import android.widget.TextView;

public class MainActivity extends Activity {

RadioButton radio0,radio1,radio2,radio3;

TextView textpolsat;

@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);

radio0=(RadioButton)findViewById(R.id.radio0);

radio1=(RadioButton)findViewById(R.id.radio1);

radio2=(RadioButton)findViewById(R.id.radio2);

radio3=(RadioButton)findViewById(R.id.radio3);

textpolsat = (TextView)findViewById(R.id.textView);

radio1.setChecked(true);textpolsat.setText("Inicialment polsat el segon");

final RadioGroup radioGroup = (RadioGroup) findViewById(R.id.radioGroup1);………………………

Creem un LinearLayout vertical només amb un widget RadioGroup amb 4 RadioButtons, i un TextView.

Page 24: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Radio Group (2)………………………final RadioGroup radioGroup = (RadioGroup) findViewById(R.id.radioGroup1);radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener(){

@Override

public void onCheckedChanged(RadioGroup group, int checkedId) {int id = radioGroup.getCheckedRadioButtonId();switch (id){case -1: case R.id.radio0:

textpolsat.setText("Polsat primer");

break;case R.id.radio1:

textpolsat.setText("Polsat segon");

break;case R.id.radio2:

textpolsat.setText("Polsat tercer");

break;case R.id.radio3:

textpolsat.setText("Polsat quart");

break;}

}

});

}

Page 25: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Radio Group (3)

public void onCheckedChanged(RadioGroup group, int checkedId) {int id = radioGroup.getCheckedRadioButtonId();

switch (id){case -1: case R.id.radio0:

textpolsat.setText("Canvi a orientació horitzontal");

radioGroup.setOrientation(LinearLayout.HORIZONTAL);

break;case R.id.radio1:

textpolsat.setText("Canvi a orientació vertical");

radioGroup.setOrientation(LinearLayout.VERTICAL);

break;case R.id.radio2:

textpolsat.setText("Canvi a gravetat centrat horitzontal");

radioGroup.setGravity(Gravity.CENTER_HORIZONTAL);

break;case R.id.radio3:

textpolsat.setText("Canvi a gravetat dreta");

radioGroup.setGravity(Gravity.RIGHT);

break;}

}

Modifica les accions del switch per a modificar paràmetres de col·locació del RadioGroup

Page 26: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Llista de selecció amb ListActivity (1)<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:id="@+id/LinearLayout1"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

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=".MainActivity" >

<TextView

android:id="@+id/seleccio"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="@string/hello_world" />

<ListView

android:id="@android:id/list"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:choiceMode="singleChoice" >

</ListView>

Important!!! El id ha de ser list que ja està definit a android

Creem un Layout amb un TextView i un ListView

Per a que quedi marcada la selecció s’ha d’indicar singleChoice al choicemode

Page 27: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Llista de selecció amb ListActivity (2)import android.app.ListActivity;import android.view.View;import android.widget.ArrayAdapter;import android.widget.ListView;import android.widget.TextView;

public class MainActivity extends ListActivity { String[] llista={"SIOP","SIAC","DIAP","MCME","XACO","PRDM","SINS","ROVI","ECUS"};

TextView seleccio;

@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);

seleccio=(TextView)findViewById(R.id.seleccio);

setListAdapter(new ArrayAdapter <String> (this,android.R.layout.simple_list_item_single_choice,llista));

}

public void onListItemClick(ListView parent, View v, int position,long id){seleccio.setText(llista[position]);

};

}

Ampliació de ListActivity

Codi Java:

Page 28: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Llista de selecció en Activity (1)<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:id="@+id/LinearLayout1"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

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=".MainActivity" >

<TextView

android:id="@+id/seleccio"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="@string/hello_world" />

<ListView

android:id="@+id/llistat"

android:layout_width="match_parent"

android:layout_height="wrap_content" >

</ListView>

</LinearLayout>

Ara el id pot ser lliure

Creem un Layout amb un TextView i un ListView

Page 29: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Llista de selecció en Activity (2)import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.ArrayAdapter;import android.widget.ListView;import android.widget.TextView;public class MainActivity extends Activity {

String[] llista={"SIOP","SIAC","DIAP","MCME","XACO","PRDM","SINS","ROVI","ECUS"};

TextView seleccio;

ListView vistallistat;

@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);

vistallistat=(ListView)findViewById(R.id.llistat);

vistallistat.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

seleccio=(TextView)findViewById(R.id.seleccio);

vistallistat.setAdapter(new ArrayAdapter <String> (this,android.R.layout.simple_list_item_single_choice,llista));

vistallistat.setOnItemClickListener(new OnItemClickListener(){@Override

public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {seleccio.setText("Has seleccionat: "+llista[arg2]+" pos:"+arg2);

}

});

}

}

Codi Java:

Forma alternativa d’indicar singleChoice al choicemode en el codi

Page 30: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Llista de selecció en recursos (1)Com a alternativa a la definició de la llista, podem crear-la als recursos en lloc del codi. Aprofitant el programa anterior, primer obrim el fitxer strings.xml de la carpeta /res/values, i afegim un String Array i li posem el nom:

<string-array name="assignatures"><item >SIOP</item><item >SIAC</item><item >DIAP</item><item >MCME</item><item >XACO</item><item name="PRD Mobils">PRDM</item><item >SINS</item><item >ROVI</item><item >ECUS</item>

</string-array>

Seleccionat el Array, afegim Items:

Afegits tots els elements, podem afegir alguns paràmetres com un nom de referència:

*

Page 31: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Llista de selecció en recursos (1)En el codi, creem el array d’String i utilitzem getResources().getStringArray per a assignar les dades de l’array:public class MainActivity extends Activity {//String[] llista={"SIOP","SIAC","DIAP","MCME","XACO","PRDM","SINS","ROVI","ECUS"};String[] llista;TextView seleccio;ListView vistallistat;@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);llista=getResources().getStringArray(R.array.assignatures);vistallistat=(ListView)findViewById(R.id.llistat);vistallistat.setChoiceMode(ListView.CHOICE_MODE_SINGLE);seleccio=(TextView)findViewById(R.id.seleccio);vistallistat.setAdapter(new ArrayAdapter <String>

(this,android.R.layout.simple_list_item_single_choice,llista));vistallistat.setOnItemClickListener(new OnItemClickListener(){@Overridepublic void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {

seleccio.setText("Has seleccionat: "+llista[arg2]+" pos:"+arg2);}

});}}

S’assigna dins del mètode onCreate, ja que no es pot fer una crida a cap mètode (getResources()) en la definició de la classe, sinó dins d’un mètode.

Page 32: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Lista desplegable – Spinner (1)<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"android:id="@+id/LinearLayout1"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"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=".MainActivity" >

<TextViewandroid:id="@+id/textView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/hello_world" />

<Spinnerandroid:id="@+id/spinner1"android:layout_width="match_parent"android:layout_height="wrap_content" />

</LinearLayout>

Creem un Layout amb un TextView i un Spinner

Page 33: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Lista desplegable – Spinner (2)import android.widget.AdapterView;import android.widget.AdapterView.OnItemSelectedListener;import android.widget.ArrayAdapter;import android.widget.Spinner;import android.widget.TextView;public class MainActivity extends Activity {String[] llista={"SIOP","SIAC","DIAP","MCME","XACO","PRDM","SINS","ROVI","ECUS"};

TextView seleccio;@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);seleccio=(TextView)findViewById(R.id.textView1);Spinner spin=(Spinner)findViewById(R.id.spinner1);ArrayAdapter<String> adaptallista=new

ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,llista);//adaptallista.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);spin.setAdapter(adaptallista); spin.setOnItemSelectedListener(new OnItemSelectedListener(){

@Overridepublic void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {

seleccio.setText(llista[arg2]);}

@Overridepublic void onNothingSelected(AdapterView<?> arg0) {

seleccio.setText("Res seleccionat");}

});}

Codi Java:

Després de provar el codi, afegeix aquesta línia i prova l’efecte

Page 34: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

TableLayoutUn TableLayout, ens permet crear un Layout en forma de Taula, afegint files amb TableRow, i en cada fila afegint els widgets que volguem, creant les columnes de la taula. S’ha de tenir en compte que si no s’indiquen mides, les files i columnes s’ajusten a la mida del widget més gran de la fila o columna.

Page 35: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

TableLayout

<?xml version="1.0" encoding="utf-8"?>

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent" android:layout_height="match_parent"

android:stretchColumns="*" android:background="#000000">

<TableRow android:layout_margin="2dp" android:background="#ffffff">

<TextView android:text="Cel·la 1.1" />

<TextView android:text="Cel·la 1.2" />

<TextView android:text="Cel·la 1.3" />

</TableRow>

<TableRow android:layout_margin="2dp" >

<TextView android:background="#ffffff" android:layout_margin="2dp" android:text="Cel·la 2.1" />

<TextView android:background="#ffffff" android:layout_margin="2dp" android:text="Cel·la 2.2" />

<TextView android:background="#ffffff" android:layout_margin="2dp" android:text="Cel·la 2.3" />

</TableRow>

<TableRow >

<TextView

android:layout_margin="2dp"

android:layout_span="2"

android:background="#ffffff"

android:gravity="center_horizontal"

android:text="Cel·la 3.1" />

<TextView android:layout_margin="2dp" android:background="#ffffff" android:text="Cel·la 3.2" />

</TableRow>

</TableLayout>

Un TableLayout serveix per a crear taules amb files i columnes. Permet crearcel·les que ocupin més d’una columna o fila.

Page 36: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

FrameLayout

public class MainActivity extends Activity {Button boto;TextView text;

@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);boto = (Button) findViewById (R.id.button1);text = (TextView) findViewById (R.id.textView1);boto.setOnClickListener(new View.OnClickListener() {

@Overridepublic void onClick(View arg0) {text.setVisibility(View.VISIBLE);boto.setVisibility(View.INVISIBLE);}

});text.setOnClickListener(new View.OnClickListener() {

@Overridepublic void onClick(View v) {text.setVisibility(View.INVISIBLE);boto.setVisibility(View.VISIBLE);}

});}

}

Un FrameLayout apila tots els controls o widgets al vèrtex superior esquerra delcontenidor FrameLayout, un a sobre de l’altre. En l’exemple posem un botó i untext en un FrameLayout, i fem que al polsar el botó aparegui el text i a l’inrevés.

Page 37: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

ImatgesPer a poder utilitzar imatges, aquestes han d’estar a la carpeta /res/drawable delprojecte d’Android. Si no existís la carpeta, es crea la carpeta polsant el botó dret a lacarpeta /res, i seleccionant New Folder.Per a afegir la imatge, polsem el botó dret sobre la carpeta /drawable, i seleccionemimport General File SystemLes imatges han d’estar en format PNG, JPG o GIF, i només poden contenir caràcters dea-z, 0-9 i _.No podem tenir dos imatges amb el mateix nom, encara que siguin diferent format.Això es degut a que una vegada estan les imatges a la carpeta del projecte, s’assignaautomàticament el recurs @drawable/nom_imatge per a accedir a elles, i no es té encompte l’extensió del fitxer.

Page 38: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

ImageViewCreem una aplicació amb dos botons que al polsar canviï la imatge de un ImageView.Inseriu dos imatges a la carpeta drawable, i afegiu al layout una vista ImageView. Alafegir el ImageView, us apareixerà una pantalla per a que seleccioneu la imatge amostrar.

<ImageViewandroid:id="@+id/imageView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentTop="true"android:layout_centerHorizontal="true"android:src="@drawable/llunatics" />

La imatge seleccionada els mostra:

ImageView imatge=(ImageView)findViewById(R.id.imageView1);imatge.setImageResource(R.drawable.llunatics);

Per a modificar la imatge en el codi, utilitzem el mètode.setImageResource:

Page 39: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

ImageViewCreem un layout amb un TextView, els dos Buttons, i un ImageView. El podem posar en un TableLayout per a facilitar la organització.

Page 40: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

import android.widget.Button;import android.widget.ImageView;import android.widget.TextView;public class MainActivity extends Activity {TextView nom;ImageView imatge;

@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);imatge=(ImageView)findViewById(R.id.imageView1);nom=(TextView)findViewById(R.id.textView1);Button btn1=(Button)findViewById(R.id.button1);Button btn2=(Button)findViewById(R.id.button2);btn1.setOnClickListener(new View.OnClickListener() {public void onClick(View view) {

imatge.setImageResource(R.drawable.llunatics);nom.setText("Imatge Llunatics");};

});btn2.setOnClickListener(new View.OnClickListener() {public void onClick(View view) {

imatge.setImageResource(R.drawable.logos);nom.setText("Imatge Logos");};

});}

El codi:

ImageView

Page 41: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Pestanyes: TabHostEl TabHost és l’element principal del layout i porta l’identificador @android:id/tabhost. El TabHost ésun contenidor de dos elements principals i configurables: el TabWidget que correspon a la part onapareixeran les pestanyes i porta l’identificador @android:id/tabs, i un segon element de tipusFrameLayout amb l’identificador @android:id/tabcontent, que és on es trobarà el contingut decadascuna de les pestanyes. Per a facilitar l’organització, el TabWidget i el FrameLayout poden estarcontinguts en un LinearLayout.

TabHost Id:@android:id/tabhostLinearLayout

TabWidget Id:@android:id/tabs

tab1 tab2 tab3 Tab1tab4

FrameLayout Id:@android:id/tabcontent

LinearLayout Id:@android:id/tab1

LinearLayout Id:@android:id/tab2

LinearLayout Id:@android:id/tab3

LinearLayout Id:@android:id/tab4

Page 42: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Pestanyes: TabHostCrearem un primer exemple simple, amb quatre pestanyes on el contingut de la pestanya serà un textque es troba al propi Layout.Configurem el següent Layout per a l’activitat principal:

Page 43: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Pestanyes: TabHostpublic class MainActivity extends Activity {

@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);TabHost tabs=(TabHost)findViewById(android.R.id.tabhost);tabs.setup();TabHost.TabSpec spec;spec=tabs.newTabSpec("eltab1");spec.setContent(R.id.tab1);spec.setIndicator("Primer");tabs.addTab(spec);

spec=tabs.newTabSpec("eltab2");spec.setContent(R.id.tab2);spec.setIndicator("Segon");tabs.addTab(spec);

spec=tabs.newTabSpec("eltab3");spec.setContent(R.id.tab3);spec.setIndicator("Tercer");tabs.addTab(spec);

spec=tabs.newTabSpec("eltab4");spec.setContent(R.id.tab4);spec.setIndicator("Quart");tabs.addTab(spec); tabs.setCurrentTab(0);

……………… segueix pàgina següent ……….

En el codi s’enllaça un objete TabHost amb el Layout, i es configuren les diferents pestanyes amb elmètode setup() i un objecte TabHost.TabSpec. En aquest cas indiquem el text a mostrar:

Page 44: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Pestanyes: TabHost

........ ve de pàgina anterior ....spec=tabs.newTabSpec("eltab4");spec.setContent(R.id.tab4);spec.setIndicator("Quart");tabs.addTab(spec); tabs.setCurrentTab(0);

tabs.setOnTabChangedListener(new OnTabChangeListener() {@Overridepublic void onTabChanged(String tabId) {missatge(tabId);}

});}

public void missatge(String tabId){Toast toastsimple= Toast.makeText(this, "S'ha polsat: "+tabId, Toast.LENGTH_SHORT);

toastsimple.show();};

}

Podem aprofitar els events del TabHost com OnTabChanged d’un TabHost, com per a exemple mostrarun missatge:

Page 45: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Pestanyes: TabHost amb icones

TabHost tabs=(TabHost)findViewById(android.R.id.tabhost);tabs.setup();TabHost.TabSpec spec;spec=tabs.newTabSpec("eltab1");spec.setContent(R.id.tab1);

// spec.setIndicator("EPSEVG",getResources().getDrawable(R.drawable.logo_epsevg));spec.setIndicator("",getResources().getDrawable(R.drawable.logo_epsevg));tabs.addTab(spec);

spec=tabs.newTabSpec("eltab2");spec.setContent(R.id.tab2);

// spec.setIndicator("UPC",getResources().getDrawable(R.drawable.logo_upc));spec.setIndicator("",getResources().getDrawable(R.drawable.logo_upc));tabs.addTab(spec);

spec=tabs.newTabSpec("eltab3");spec.setContent(R.id.tab3);

// spec.setIndicator("GREC",getResources().getDrawable(R.drawable.logogrec));spec.setIndicator("",getResources().getDrawable(R.drawable.logogrec));tabs.addTab(spec);

spec=tabs.newTabSpec("eltab4");spec.setContent(R.id.tab4);

// spec.setIndicator("VNG",getResources().getDrawable(R.drawable.logo_ajvilanova));

spec.setIndicator("",getResources().getDrawable(R.drawable.logo_ajvilanova));tabs.addTab(spec); tabs.setCurrentTab(0);

Si en lloc de text volem que apareguin imatges, aquestes han d’estar a la carpeta /res/drawable, i esreferencien amb setIndicator. Es pot indicar el text i la imatge, però segons la versió de la API, nomésapareix el text i per a que aparegui la imatge s’ha de deixar en blanc el text. Modifica el codi anteriorper aquest:

Page 46: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Pestanyes: TabHost amb TabactivitySi volem mostrar una activitat externa al polsar la pestanya, s’utilitza una subclasse de Activity que es diu TabActivity. Actualment està en desús a favor de ActionBar des de la API 11, però segueix essent una forma molt senzilla de cridar activitats.Creem un TabHost amb dos Tabs:

També creem dues activitats més amb el seu Layout corresponent:

Ens assegurem que s’han afegit les noves activitats en l’apartat Application del fitxer AndroidManifest.xml:

Page 47: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Pestanyes: TabHost amb Tabactivity

public class MainActivity extends TabActivity {@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);

TabHost tabs=(TabHost)findViewById(android.R.id.tabhost);

tabs.setup();

TabHost.TabSpec spec;

spec=tabs.newTabSpec("eltab1");

spec.setContent(new Intent(MainActivity.this,Activitat_tabhost.class));spec.setIndicator("Primer");

tabs.addTab(spec);

Intent i = new Intent();i.setClass(MainActivity.this,Segona_activitat.class);spec=tabs.newTabSpec("eltab2");

spec.setContent(i);

spec.setIndicator("Segon");

tabs.addTab(spec);

tabs.setCurrentTab(0);

}

}

En el codi de l’activitat principal, canviem Activity per TabActivity. Per a cridarles activitats corresponents a les pestanyes, es creen els Intentscorresponents, i s’associen amb el mètode TabHost.TabSpec.setContent()

Page 48: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

• http://www.androidcurso.com/• http://www.sgoliver.net• http://yoandroido.blogspot.com.es/• http://www.javaya.com.ar/androidya/index.p

hp?inicio=• http://elbauldelprogramador.com/curso-

programacion-android/

Page 49: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

INTENTSCrida a altres activitats o

aplicacionsCristobal Raya Giner

Programació de Dispositius Mòbils (PRDM)

Elements principalsHi ha varis elements importants a tenir en compte al desenvolupar aplicacions en Android• Activity (Activitats): Són els blocs bàsics d’una aplicació, que

solen representar les pantalles d’interfície d’usuari (UI)• Intent (Intents): Representa la intenció de cridar a una altra

aplicació, de la qual es pot rebre una resposta. Per exemple, visualitzar una pàgina web amb el navegador.

• Service (Serveis): És un procés que s’executa en segon pla, sense necessitat de cap interacció amb l’usuari. Ex: servidor Web

• Content Providers (Proveïdors de Contingut): Proveeixen l’accés per a la compartició de dades per les aplicacions. Ex: Agenda de Contactes

• Broadcast Receiver: Detecta i reacciona a missatges o eventsglobals del sistema. Ex. Bateria baixa

Page 50: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Crida a nova activitat (1)Creem un nou projecte amb una activitat, i afegim una novaactivitat. En la carpeta Layout premem el botó dret i seleccionemNew Android XML File.

Afegim un LinearLayout al nou layout, i acceptem les següents finestres fins finalitzar la creació del Layout.

Apareixen els dos Layouts a la carpeta, i araafegim un botó en cada Layout.

Crida a nova activitat (2)

Page 51: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Crida a nova activitat (3)Per a crear el codi de la segona activitat, premem el botó dret en la carpeta del package del projecte en /src, i creem una nova classe:

Posem el nom, i li indiquem quehereta la classe Activity, del paquetd’android a l’apartat Superclass:Android.app.Activity

També podem crear nova Activitat i ens crea també el Layout imodifica el fitxer AndroidManifest.xml, i realitza els passos de lessegüents diapositives automàticament.

Crida a nova activitat (4)

Falta sobreescriure el mètode onCreate al codi. Podem escriure-ho directament, o bé ajudar-nos amb l’apartat de Override/Implement Methods… del menu Source.

Page 52: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Crida a nova activitat (5)

Per a acabar d’enllaçar el codi amb el corresponent layout, afegim el mètode setContentView:

package edu.example.crida_novaactivitat;import android.app.Activity;import android.os.Bundle;public class Segona_activitat extends Activity {@Override

protected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.segona_activitat);}

}

Crida a nova activitat (6)Només falta registrar la nova activitat al fitxer AndroidManifest.xml afegint-la a l’apartat Application

Per acabar, afegim el nom del fitxer .java amb el codi de l’activitat

Page 53: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Crida a nova activitat (7)public class MainActivity extends Activity {@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button boto1=(Button)findViewById(R.id.button);boto1.setOnClickListener(new View.OnClickListener() {public void onClick(View view) {

obrir(view);

};

});

}

public void obrir(View view) {Intent i = new Intent(this, Segona_activitat.class );startActivity(i);

}

}

Creem el codi de l’activitat principal, creant un nou Intent

Podem obviar el paràmetre View de obrir: obrir()

Crida a nova activitat (7bis)

public void obrir() {Intent i = new Intent();i.setClass(MainActivity.this, Segona_activitat.class);startActivity(i);

}

Com a alternativa creem un Intent, i després li indiquem perseparat la classe origen, indicant que correspon a la que estem(***.this) i la clase destí (***.class):

Page 54: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Crida a nova activitat (8)

public class Segona_activitat extends Activity {@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.segona_activitat);Button boto2=(Button)findViewById(R.id.button);boto2.setOnClickListener(new View.OnClickListener() {public void onClick(View view) {

tancar(view);

};

});

}

public void tancar(View view) {finish();

}

}

Creem el codi de la segona activitat, fent que es tanqui al polsar el botó

Podem obviar el paràmetre View de tancar: tancar()

Crida a activitat amb paràmetres (1)Crearem dos activitats entre les que es passaran paràmetres. En el primerlayout afegim un botó i un EditText on escribirem un text que passarem a lasegona activitat, i en el segon layout afegim un botó i un TextView on esmostrarà el text enviat des de la primera activitatp

<TextViewandroid:id="@+id/textprimer"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Primera activitat" />

<EditTextandroid:id="@+id/entradatext1"android:layout_width="match_parent"android:layout_height="wrap_content"android:ems="10" >

<requestFocus /></EditText>

<Buttonandroid:id="@+id/boto1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Prem per la segona" />

<TextViewandroid:id="@+id/text2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Segona Activitat" />

<Buttonandroid:id="@+id/boto2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Torna a primera" />

<TextViewandroid:id="@+id/dadesrebudes"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Dades Rebudes"

android:textAppearance="?android:attr/textAppearanceLarge" />

Page 55: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Crida a activitat amb paràmetres (2)En el codi de la primera activitat afegim el mètode putExtra() al Intent abans de cridar a la segona activitat per a afegir el text a compartir.

public class MainActivity extends Activity {EditText textdades;@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button boto1=(Button)findViewById(R.id.boto1);textdades=(EditText) findViewById(R.id.entradatext1);boto1.setOnClickListener(new View.OnClickListener() {public void onClick(View view) {

obrir();};

});}

public void obrir() {Intent i = new Intent();i.setClass(MainActivity.this, Segona_activitat.class );i.putExtra("escrit", textdades.getText().toString());startActivity(i);}

}

Crida a activitat amb paràmetres (3)En el codi de la segona activitat afegim el mètode getIntent().getExtras()per a llegir el text enviat per la primera activitatpublic class Segona_activitat extends Activity {TextView rebut;String dades;@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.segona_activitat);Button boto2=(Button)findViewById(R.id.boto2);rebut=(TextView)findViewById(R.id.dadesrebudes);Bundle bundle = getIntent().getExtras();dades=bundle.getString("escrit");rebut.setText(dades);boto2.setOnClickListener(new View.OnClickListener() {

public void onClick(View view) {tancar();};

});}

public void tancar() {finish();}

}

Page 56: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Crida a activitat amb paràmetres (4)Ara passarem una adreça web des de la primera activitat, i en la segona es visualitzarà. La primera activitat és similar a l’exemple anterior.

public class MainActivity extends Activity {EditText adreca;@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button boto1=(Button)findViewById(R.id.boto1);adreca=(EditText) findViewById(R.id.entradatext1);boto1.setOnClickListener(new View.OnClickListener() {public void onClick(View view) {

obrir();};

});}

public void obrir() {Intent i = new Intent();i.setClass(MainActivity.this, Segona_activitat.class );i.putExtra("pagina", adreca.getText().toString());startActivity(i);}

}

Crida a activitat amb paràmetres (5)En la segona activitat afegim una vista WebView, i li pasem el paràmetre de la pàgina al mètode loadUrl().public class Segona_activitat extends Activity {WebView navegador;String pag;@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.segona_activitat);Button boto2=(Button)findViewById(R.id.boto2);navegador=(WebView)findViewById(R.id.webView1);Bundle bundle = getIntent().getExtras();pag=bundle.getString("pagina");navegador.loadUrl("http://" + pag);boto2.setOnClickListener(new View.OnClickListener() {

public void onClick(View view) {tancar();};

});}

public void tancar() {finish();}

}

Page 57: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Crida a activitat amb paràmetres (6)Per a que funcioni, només falta donar permís a l’aplicació quepugui accedir a Internet. Per a això s’ha de obrir el fitxerAndroidManifest.xml, i en la pestanya Permissions afegirl’element Uses Permission, i indicar el permísandroid.permission.INTERNET.

Crida a activitat amb resultat (1)Crearem una activitat en que escriurem dos números i al polsar un botó, passaràels valors a una nova activitat, en aquesta escriurem un nom, i al polsar un botóens retornarà el nom i la suma dels dos números a la primera activitat.

Activitat principal Segona Activitat

Page 58: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Crida a activitat amb resultat (2)

public class Activitat_principal extends Activity {TextView dadesretorn;EditText envianum1,envianum2;Button boto;int calculrebut;String nomrebut;int REQUEST_CODE=1;@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_activitat_principal);dadesretorn=(TextView)findViewById(R.id.textrebut);envianum1=(EditText)findViewById(R.id.numero);envianum2=(EditText)findViewById(R.id.numero2);boto=(Button)findViewById(R.id.boto);boto.setOnClickListener(new View.OnClickListener() {

@Overridepublic void onClick(View v) {

envia_dades();}

});}

………… segueix després………

En l’activitat principal, creem un listener de la polsació del botó i al polsarenviem les dades

Crida a activitat amb resultat (3)

………… segueix abans ………

public void envia_dades(){if(envianum1.getText().toString().equals("")||envianum2.getText().toString().equals(""))

{dadesretorn.setText("Falta algún número");}

else {Intent segona=new Intent (this, Segona_activitat.class);segona.putExtra("numero1", Integer.valueOf(envianum1.getText().toString()));segona.putExtra("numero2", Integer.valueOf(envianum2.getText().toString()));startActivityForResult(segona,REQUEST_CODE);}

};@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data){

if (resultCode==RESULT_OK && requestCode == REQUEST_CODE){if (data.hasExtra("calcul")&& data.hasExtra("nom")){

calculrebut=data.getExtras().getInt("calcul");nomrebut=data.getExtras().getString("nom");dadesretorn.setText("En/Na "+nomrebut+" diu que la suma és: "+calculrebut);

};}

};}

Si s’han escrit els números s’envien a la segona activitat i es aquesta es cridaamb un codi de control. El mètode onActivityResult, retorna un codi d’error, elcodi de control enviat per la primera, i les dades de resposta.

Page 59: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Crida a activitat amb resultat (4)

public class Segona_activitat extends Activity {TextView dadesrep;

EditText dadesnom;Button boto2;Bundle dadesrebudes;int numerorebut1,numerorebut2;

@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_segona_activitat);TextView dadesrep=(TextView)findViewById(R.id.dadaactivitat1);final EditText dadesnom=(EditText)findViewById(R.id.entranom);dadesrebudes=getIntent().getExtras();if (dadesrebudes==null) {

return;}

numerorebut1=dadesrebudes.getInt("numero1");numerorebut2=dadesrebudes.getInt("numero2");dadesrep.setText("He rebut els nombres: " +

Integer.toString(numerorebut1)+" i "+ Integer.toString(numerorebut2));Button boto2=(Button)findViewById(R.id.boto2);boto2.setOnClickListener(new View.OnClickListener() {………… segueix després………

En la segona activitat comprovem si s’han rebut dades, i si s’han rebuts’extreuen i es mostren. S’espera que es polsi el botó per a retornar el resultat.

Crida a activitat amb resultat (5)

………… segueix abans ………

Button boto2=(Button)findViewById(R.id.boto2);boto2.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {

Intent j=new Intent();j.putExtra("calcul", numerorebut1+numerorebut2);j.putExtra("nom", dadesnom.getText().toString());setResult(RESULT_OK,j);surt();}

});}public void surt(){

super.finish();};}

Al polsar el botó, es crea un intent per a retornar el resultat, i es retornen la sumadels dos números enviats per la primera activitat, el nom escrit, i el codi d’error(amb setResult) a la primera activitat. Finalment es tanca l’activitat.

Page 60: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Intents explicits / implicitsEls Intents s’utilitzen per a iniciar activitats i enviar events a varis destinataris.Un Intent queda descrit per: l’acció a realitzar (MAIN, EDIT, VIEW,…), la dadaque actua sobre l’acció (Universal Resource Indicator - URI) i els extres (int,String, …) i el component al que va dirigit (ex: edu.pdrm.HolaMon)

Hi ha dues formes de cridar un Intent:

Invocació explícita: S’especifica explícitament en codi quin component és l’encarregat de gestionar el Intent.

Intent intent = new Intent(Context, Activitat.class);startActivity(intent);

Invocació implícita: És la plataforma qui determina, mitjançant un procés de resolució de Intents, quin és el component més adient per a gestionar el intent.

Intent intent = new Intent(Intent.ACTION_DIAL, URI.parse(tel:928-76-34-26));

startActivity(intent);

Intents – Intent Filter

<activity

android:name="edu.example.nomactivitat.MainActivity"android:label="@string/app_name" ><intent-filter>

<action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

<intent-filter>

<action android:name="android.intent.action.INSERT" /><category android:name="android.intent.category.DEFAULT" /><data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />

</intent-filter>

</activity>

http://developer.android.com/reference/android/content/Intent.html

Un component declara la capacitat per a atendre un Intent mitjançant el tag<intent-filter> en l’arxiu AndroidManifest.xml.

Per a nombrar una acció normalment s’utilitza la forma .intent.action.ACCIO.Per exemple, per al navegador web, l’acció VIEW obre el navegador en unaURL especificada; o per al marcador, l’acció CALL realitza una trucada a unnúmero especificat.

Page 61: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Intents - Exemples

public static void invokeWebBrowser(Activity activity){Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("http://www.google.com"));activity.startActivity(intent);

}

public static void invokeWebSearch(Activity activity){Intent intent = new

Intent(Intent.ACTION_WEB_SEARCH);intent.setData(Uri.parse("http://www.google.com"));activity.startActivity(intent);

}

public static void dial(Activity activity){Intent intent = new Intent(Intent.ACTION_DIAL);activity.startActivity(intent);

} http://developer.android.com/guide/appendix/g-app-intents.html

Un intent està format per una acció, dades (representades mitjançant URIs), dades extra en parells clau/valor i un nom de classe explícit, anomenat nom del component.

public static void call(Activity activity){Intent intent = new Intent(Intent.ACTION_CALL);intent.setData(Uri.parse("tel:555-555-555"));activity.startActivity(intent);

}

public static void showMapAtLatLong(Activity activity){Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("geo:0,0?z=4&q=restaurantes"));activity.startActivity(intent);

}

Crida a un navegador extern

public class MainActivity extends Activity {EditText adreca;String URL;@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button boto=(Button)findViewById(R.id.boto);adreca=(EditText)findViewById(R.id.editURL);boto.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View arg0) {

URL=adreca.getText().toString();obrenavegador(URL);}

}) ;}public void obrenavegador(String url){

Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("http://"+url));startActivity(intent);

};}

Ara utilitzarem una invocació implícita a un Intent que cridarà al navegador extern. Creem un layout amb un EditText i un botó.

Alternativa a la invocació de l’Intent:Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("http://"+url));

Page 62: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Crida a Maps (1)

public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button boto=(Button)findViewById(R.id.boto);boto.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View arg0) {

obremaps();}

}) ;}public void obremaps(){

Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("geo:41.22164,1.72990?z=20"));startActivity(intent);

};}

intent.setData(Uri.parse("geo:0,0?q=41.22164,1.72990 (AI109)"));

Cridarem a l’aplicació Maps, indicant una coordenada. Creem un botó al Layout. Al codi, cridarem les coordenades del laboratori, amb un zoom de 20.

Podem fer la crida indicant que etiqueti les coordenades:

Crida a Maps (2)

public class MainActivity extends Activity {EditText longitut,latitut;String coordenades;TextView uril;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button boto=(Button)findViewById(R.id.boto);latitut=(EditText)findViewById(R.id.editlat);longitut=(EditText)findViewById(R.id.editlong);uril=(TextView)findViewById(R.id.textView1);boto.setOnClickListener(new View.OnClickListener() {

@Overridepublic void onClick(View arg0) {coordenades="geo:"+latitut.getText().toString()+","+longitut.getText().toString()+"?z=20";uril.setText(coordenades);obremaps(coordenades);}

}) ;}public void obremaps(String dades){

Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse(dades));startActivity(intent);

};}

Cridarem a l’aplicació Maps, editant coordenades.

Page 63: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Crida a Maps (3) - SeekBarAfegim un SeekBar al Layout per a modificar el valor del zoomamb una barra. I afegim el codi corresponent…

TextView uril,valzoom;SeekBar zoom;…uril=(TextView)findViewById(R.id.textView1);valzoom=(TextView)findViewById(R.id.valorzoom);zoom=(SeekBar)findViewById(R.id.seekBar1);zoom.setOnSeekBarChangeListener(new OnSeekBarChangeListener(){@Override

public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {

valzoom.setText(String.valueOf(new Integer(progress)));}

@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStopTrackingTouch(SeekBar seekBar){}

});boto.setOnClickListener(new View.OnClickListener() {

@Overridepublic void onClick(View arg0) {

coordenades="geo:"+latitut.getText().toString()+","+longitut.getText().toString()+"?z="+valzoom.getText().toString();

uril.setText(coordenades);obremaps(coordenades);}

}) ;…

Alert Dialog

<Buttonandroid:id="@+id/button1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:text="Alert Dialog Simple" />

<Buttonandroid:id="@+id/button2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:text="Alert Dialog amb opció" />

<TextViewandroid:id="@+id/textView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="TextView" />

Per a mostrar missatges de notificacions, no és necessari crear una aplicació i cridar-la. Una de les possibilitats és utilitzar els Alert Dialogs. Creem una aplicació amb un Layout amb dos botons i un TextView.

Page 64: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Alert Dialogpublic class MainActivity extends Activity {Button simple, ambretorn;TextView text;AlertDialog.Builder dialogsimple,dialogretorn;

@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);simple=(Button)findViewById(R.id.button1);ambretorn=(Button)findViewById(R.id.button2);text=(TextView)findViewById(R.id.textView1);simple.setOnClickListener(guaita);ambretorn.setOnClickListener(guaita);dialogsimple = new AlertDialog.Builder(this);dialogsimple.setTitle("Alerta Simple");dialogsimple.setMessage("Aquest és un Alert Dialog només amb un botó d'acceptar");dialogsimple.setPositiveButton("Vale",null);dialogretorn = new AlertDialog.Builder(this); dialogretorn.setTitle("Alerta amb opcions"); dialogretorn.setMessage("Vols acceptar o vols cancel·lar?"); dialogretorn.setCancelable(false); dialogretorn.setPositiveButton("Confirmar", new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialogretorn, int id) { text.setText("Has polsat confirmar a l'alerta amb opcions");}

}); dialogretorn.setNegativeButton("Cancel·lar", new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialogretorn, int id) { text.setText("Has Cancel·lat l'alerta amb opcions");}

}); } ………… segueix després………

Polsant un botó apareix un missatge amb un botó de sortir, i polsant l’altre apareix un missatge i dues opcions.

Alert Dialog………… segueix s’abans………

dialogretorn.setNegativeButton("Cancel·lar", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialogretorn, int id) {

text.setText("Has Cancel·lat l'alerta amb opcions");}

}); }

View.OnClickListener guaita=new OnClickListener(){

@Overridepublic void onClick(View v) {

if(((Button)v).getId()== simple.getId() ) {//dialogsimple.create();dialogsimple.show();text.setText("Has provat l'alerta simple");}

else if(((Button)v).getId()== ambretorn.getId()) {dialogretorn.show(); }

}}; }

Finalment executem l’acció en funció del botó polsat.

Page 65: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

ToastUna altre alternativa per a mostrar missatges ràpida de curta durada és utilitzar la classe Toast. Podem tenir varies alternatives.Creem el layout principal de l’aplicació amb tres botons, i afegim un nou layout secundari que servirà per a mostrar un missatge a mida.

Layout principal Layout secundari

Toastpublic class MainActivity extends Activity {TextView vtexte;Button simple,reubicat,amida;@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);vtexte=(TextView)findViewById(R.id.textView1);simple=(Button)findViewById(R.id.buttonsimple);reubicat=(Button)findViewById(R.id.buttonubica);amida=(Button)findViewById(R.id.buttonmida);simple.setOnClickListener(Escoltador);reubicat.setOnClickListener(Escoltador);amida.setOnClickListener(Escoltador);

}View.OnClickListener Escoltador=new View.OnClickListener() {

@Overridepublic void onClick(View v) {

if(((Button)v).getId()== simple.getId() ){missatge_simple();}

else if(((Button)v).getId()== reubicat.getId() ){missatge_reubicat();}

else if(((Button)v).getId()== amida.getId() ){missatge_amida();}}

};private void missatge_simple(){

Toast toastsimple= Toast.makeText(this, "Toast normal (curta durada)", Toast.LENGTH_SHORT);………… segueix després………

Polsant un botó apareix un missatge en un lloc per defecte, amb altre apareix centrat verticalment, i amb el darrer botó es mostra el layout secundari.

Page 66: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Toast………… segueix s’abans………

else if(((Button)v).getId()== amida.getId() ){missatge_amida();}}

};private void missatge_simple(){

Toast toastsimple= Toast.makeText(this, "Toast normal (curta durada)", Toast.LENGTH_SHORT);vtexte.setText("Toast Simple polsat");toastsimple.show();

}private void missatge_reubicat(){

Toast toastreubicat = Toast.makeText(this, "Toast reubicat (llarga durada)", Toast.LENGTH_LONG);toastreubicat.setGravity(Gravity.CENTER_VERTICAL, 0, 0);toastreubicat.show();vtexte.setText("Toast Reubicat polsat");

}private void missatge_amida(){

LayoutInflater inflater = getLayoutInflater();View layoutmida = inflater.inflate(R.layout.toast_a_mida,null);Toast toastamida = new Toast(getApplicationContext());toastamida.setGravity(Gravity.CENTER_VERTICAL, 0, 0);toastamida.setDuration(Toast.LENGTH_LONG);toastamida.setView(layoutmida);toastamida.show();vtexte.setText("Toast a mida polsat");

}}

Per a crear i mostrar els missatges amb Toast creem uns mètodes a part.

• http://www.androidcurso.com/• http://www.sgoliver.net• http://yoandroido.blogspot.com.es/• http://www.javaya.com.ar/androidya/index.p

hp?inicio• http://elbauldelprogramador.com/curso-

programacion-android/

Page 67: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

AndroidMENUS

Cristobal Raya Giner

Programació de Dispositius Mòbils (PRDM)

Tipus de MenúsEn Android podem trobar 3 tipus diferents de menús:

Menús Principals. Apareixen en la zona inferior de la pantalla al polsar el botó ‘menu’ del dispositiu.Submenús. Son menús secundaris que es poden mostrar al polsar sobre una opció d’un menú

principal.Menús Contextuals. Apareixen al realitzar una pulsació llarga sobre algun element de la pantalla.

Per a definir els menús principals i els seus submenús, es crea un fitxer .xml a la carpeta /res/menu,amb el següent format:

public boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true; }

Una vegada creat el fitxer xml, relaciona en el codi en el mètode de creació de menúper defecte. (main.xml R.menu.main)

Page 68: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Menús principals i submenús

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

<itemandroid:id="@+id/item0"android:title="Primera opció"><menu>

<item android:id="@+id/item0_1" android:title="Primera sub primer"/><item android:id="@+id/item0_2" android:title="Primera sub segon"/>

</menu></item><item android:id="@+id/item1" android:title="Segona opció"></item><item android:id="@+id/item2" android:title="Tercera Opció"></item>

</menu>

Creem un projecte Android per defecte del tipus HelloWorld, i modifiquem el fitxer main.xml de lacarpeta /res/menu, afegint 3 items, i un submenú amb dos items en un d’ells:

public class MainActivity extends Activity {TextView texte;@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);texte=(TextView)findViewById(R.id.texte);}

@Overridepublic boolean onCreateOptionsMenu(Menu menu) {

getMenuInflater().inflate(R.menu.main, menu);return true;}

@Overridepublic boolean onOptionsItemSelected(MenuItem item) {switch (item.getItemId()) {

case R.id.item0:texte.setText("Opció 1 polsada");return true;

case R.id.item1:texte.setText("Opció 2 polsada");;

return true;case R.id.item2:texte.setText("Opció 3 polsada");;

return true;case R.id.item0_1:texte.setText("Opció 1 SubOpció 1 polsada");;

return true;case R.id.item0_2:texte.setText("Opció 1 SubOpció 2 polsada");;

return true;default:

return super.onOptionsItemSelected(item);}

}}

En el fitxer de codi .java afegim el mètode onOptionsItemSelected, per especificar les accionsassociades a cada item del menú, que en aquest cas modifiquen el text del TextView:

Menús principals i submenús

Page 69: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Menús ContextualsCreem un nou projecte Android per defecte del tipus HelloWorld i creem unnou fitxer xml per al menú, polsant el botó dret sobre el la carpeta menú, iseleccionant New Android XML File. Indiquem que es tracta de un tipusMenu a l’apartat Resource Type:(menucontext.xml)

<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android" >

<item android:id="@+id/item1" android:title="Primera Opció"></item><item android:id="@+id/item2" android:title="Segona Opció"></item><item android:id="@+id/item3" android:title="Tercera Opció"></item>

</menu>

Afegim tres items:

Menús ContextualsEnllacem la etiqueta del text al seu View corresponent, i indiquem que laetiqueta estarà associada a un menú contextual amb el mètoderegisterForContextMenu(). Afegim un nou mètode onCreateContextMenu()per a la creació del menú contextual:

public class MainActivity extends Activity {TextView texte;@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);texte=(TextView)findViewById(R.id.textview1);registerForContextMenu(texte);}

@Overridepublic void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo){

super.onCreateContextMenu(menu, v, menuInfo);MenuInflater inflater = getMenuInflater();inflater.inflate(R.menu.menucontext, menu);}

}

Page 70: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Menús ContextualsFinalment afegim el mètode onContextItemSelected() per a per especificar lesaccions associades a cada item del menú, que en aquest cas modifiquen eltext:

@Overridepublic boolean onContextItemSelected(MenuItem item) {

switch (item.getItemId()) {case R.id.item1:

texte.setText("Primera opció polsada");return true;

case R.id.item2:texte.setText("Segona opció polsada");return true;

case R.id.item3:texte.setText("Tercera opció polsada");return true;

default:return super.onContextItemSelected(item);

}}

Menús Contextuals amb llistesAl projecte anterior, afegirem un nou menú contextual basat en una llista.Afegim un ListView al Layout.

Al fitxer .java afegim la llista i li indiquem que s’associarà a unmenú contextual:public class MainActivity extends Activity {

TextView texte;ListView llista;@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);texte=(TextView)findViewById(R.id.textview1);llista=(ListView)findViewById(R.id.listView1);String[] llistat=new String[]{"Primer","Segon","Tercer","Quart","Cinqué"};ArrayAdapter<String> adaptador =new ArrayAdapter<String>(this,

android.R.layout.simple_list_item_1, llistat);llista.setAdapter(adaptador);registerForContextMenu(texte);registerForContextMenu(llista);

}

Page 71: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Menús Contextuals amb llistes

Modifiquem el mètode onCreateContextMenu() afegint la llista, i indicantquin menú contextual ha d’obrir en funció del item clicat.public void onCreateContextMenu(ContextMenu menu, View v,

ContextMenuInfo menuInfo){

super.onCreateContextMenu(menu, v, menuInfo);MenuInflater inflater = getMenuInflater();

if(v.getId() == R.id.textview1)inflater.inflate(R.menu.menucontext, menu);

else if(v.getId() == R.id.listView1){

AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo;

menu.setHeaderTitle(llista.getAdapter().getItem(info.position).toString());inflater.inflate(R.menu.menu_llista, menu);

}

<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android" >

<item android:id="@+id/itemllista1" android:title="Opcio llista 1"></item><item android:id="@+id/itemllista2" android:title="Opcio llista 2"></item><item android:id="@+id/itemllista3" android:title="Opcio llista 3"></item>

</menu>

Creem un nou fitxer XML de menú, amb varis items. (menu_llista.xml)

Menús Contextuals amb llistes

public boolean onContextItemSelected(MenuItem item) {AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();

switch (item.getItemId()) {case R.id.item1:

texte.setText("Primera opció polsada del text");return true;

case R.id.item2:texte.setText("Segona opció polsada del text");return true;

case R.id.item3:texte.setText("Tercera opció polsada del text");return true;

case R.id.itemllista1:texte.setText("Posició " + info.position + " de la llista: Opcio 1 polsada");return true;

case R.id.itemllista2:texte.setText("Posició " + info.position + " de la llista: Opcio 2 polsada");return true;

case R.id.itemllista3:texte.setText("Posició " + info.position + " de la llista: Opcio 3 polsada");return true;

default:return super.onContextItemSelected(item);

}

Finalment modifiquem el mètode onContextItemSelected() per a perespecificar les accions associades a cada item del menú.

Page 72: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

• http://www.androidcurso.com/• http://www.sgoliver.net• http://yoandroido.blogspot.com.es/• http://www.javaya.com.ar/androidya/index.p

hp?inicio=• http://elbauldelprogramador.com/curso

programacion android/

Page 73: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

AndroidSensors i altres serveis del

sistema

Cristobal Raya Giner

Programació de Dispositius Mòbils (PRDM)

Page 74: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

<TextViewandroid:id="@+id/llistat"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/hello_world" />

public class MainActivity extends Activity {private TextView llistat;

@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);llistat = (TextView) findViewById(R.id.llistat);llistat.setText("Llista sensors: \n");SensorManager sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);List<Sensor> llistaSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);for(Sensor sensor: llistaSensors) { //Versió del for loop que extreu un element de la llista a cada iteració

llista(sensor.getName()+", Rang: "+ Float.toString(sensor.getMaximumRange())); }

}private void llista(String string) {

llistat.append(string + "\n");}

}

Una forma senzilla de llistar tots els sensors que incorpora el dispositiu, es extreure la llista amb elmètode getSensorList() del sensorManager.Creem un TextView, al qual anirem afegint els diferents sensors amb el mètode append(), i ensmostrarà el nom del sensor i el valor màxim que pot tenir.

Codi .java:

Llista sensors

http://developer.android.com/reference/android/hardware/Sensor.html

Page 75: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Acceleròmetre

<TextViewandroid:id="@+id/textViewX"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text=“ax" />

<TextViewandroid:id="@+id/textViewY"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text=“ay" />

<TextViewandroid:id="@+id/textViewZ"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text=“az" />

Per a fer la lectura dels tres eixos de l’acceleròmetre, primer crearem un layout amb 3TextView:

Provarem dos mètodes: Implementant a la definició de l’activitat el SensorEventListener(1), i creant el SensorEventListener dins de l’activitat (2).

Page 76: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

public class MainActivity extends Activity implements SensorEventListener{private SensorManager sensorManager;double ax,ay,az;TextView sx,sy,sz;

@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);sx=(TextView)findViewById(R.id.textViewX);sy=(TextView)findViewById(R.id.textViewY);sz=(TextView)findViewById(R.id.textViewZ);sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_NORMAL);

}@Overridepublic void onAccuracyChanged(Sensor arg0, int arg1) {}@Overridepublic void onSensorChanged(SensorEvent arg0) {

if (arg0.sensor.getType()==Sensor.TYPE_ACCELEROMETER){ax=arg0.values[0];ay=arg0.values[1];az=arg0.values[2];sx.setText(«Acel X: "+Double.toString(ax));sy.setText("Acel Y: "+Double.toString(ay));sz.setText("Acel Z: "+Double.toString(az));}

}

}

Al codi implementarem el SensorEvenListener a la definició de la classe, per a que controli els canvisde valor dels sensors, i un SensorManager que gestionarà la lectura dels sensors.

Acceleròmetre (1)

Page 77: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

public class MainActivity extends Activity {double ax,ay,az;TextView sx,sy,sz;SensorManager mSensorManager;SensorEventListener mEventListenerAccelerometer;

@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);sx=(TextView)findViewById(R.id.textViewX);sy=(TextView)findViewById(R.id.textViewY);sz=(TextView)findViewById(R.id.textViewZ);mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);mEventListenerAccelerometer = new SensorEventListener() {

@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}@Overridepublic void onSensorChanged(SensorEvent event) {

ax=event.values[0];ay=event.values[1];az=event.values[2];sx.setText("Mira X: "+Double.toString(ax));sy.setText("Mira Y: "+Double.toString(ay));sz.setText("Mira Z: "+Double.toString(az));

}};}public void onResume(){super.onResume();mSensorManager.registerListener(mEventListenerAccelerometer,

mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_NORMAL);

}protected void onStop() {

mSensorManager.unregisterListener(mEventListenerAccelerometer);super.onStop();

}}

Al codi crearem un SensorManager que gestionarà la lectura dels sensors, i un SensorEvenListener pera que controli els canvis de valor dels sensors.

Acceleròmetre (2)

Page 78: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Estats d’una activitatUna activitat pot estar en varis estats com creant-se, iniciant-se, en pausa,etc..., i per a canviar d’una a altre hi ha els mètodes corresponents.

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// Codi ....}

public void onResume(){super.onResume();// Codi ....}

En passar d’un estat a altre es pot executar algun codi, en el mètodecorresponent, però sempre s’ha de cridar primer al mètode de la classe pare.

Page 79: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Acceleròmetre i Bruixolapublic class MainActivity extends Activity implements SensorEventListener{private SensorManager sensorManager;double ax,ay,az,bx,by,bz;TextView acx,acy,acz,brujulax,brujulay,brujulaz;

@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);

acx=(TextView)findViewById(R.id.ax);

acy=(TextView)findViewById(R.id.ay);

acz=(TextView)findViewById(R.id.az);

brujulax=(TextView)findViewById(R.id.brx);

brujulay=(TextView)findViewById(R.id.bry);

brujulaz=(TextView)findViewById(R.id.brz);

sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);

sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),

SensorManager.SENSOR_DELAY_NORMAL);

sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),SensorManager.SENSOR_DELAY_NORMAL);

}

@Override

public void onAccuracyChanged(Sensor arg0, int arg1) {}@Override

public void onSensorChanged(SensorEvent arg0) {synchronized (this) { //La paraula reservada synchronized impedeix l'accés concurrent a una secció del codi

……………… segueix pàgina següent ……….

Llegirem dos sensors: el sensor acceleròmetre és una lectura directa del hardware i la bruixola és uncàlcul a partir dels acceleròmetres i els magnetòmetres. Creem primer 6 TextView.

Page 80: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Acceleròmetre i Bruixola…………… ve de pàgina anterior ................

@Override

public void onAccuracyChanged(Sensor arg0, int arg1) {}@Override

public void onSensorChanged(SensorEvent arg0) {synchronized (this) { //La paraula reservada synchronized impedeix l'accés concurrent a una secció del codi

if (arg0.sensor.getType()==Sensor.TYPE_ACCELEROMETER){

ax=arg0.values[0];

ay=arg0.values[1];

az=arg0.values[2];

acx.setText("Acel X: "+Double.toString(ax));

acy.setText("Acel Y: "+Double.toString(ay));

acz.setText("Acel Z: "+Double.toString(az));

}

if (arg0.sensor.getType()==Sensor.TYPE_ORIENTATION){bx=arg0.values[0];

by=arg0.values[1];

bz=arg0.values[2];

brujulax.setText("Acel X: "+Double.toString(bx));

brujulay.setText("Acel Y: "+Double.toString(by));

brujulaz.setText("Acel Z: "+Double.toString(bz));

}

}

}

}

Page 81: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Brúixola / Orientació

public class MainActivity extends Activity implements SensorEventListener{private SensorManager sensorManager;float acceleracio[]=new float[3];float magnetisme[]=new float[3];TextView acceleracions, magnetismes, bruixola;float rotationMatrix[] = new float[16];float orientation[] = new float[3];

@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);acceleracions=(TextView)findViewById(R.id.acceleracions);magnetismes=(TextView)findViewById(R.id.magnetisme);bruixola=(TextView)findViewById(R.id.orientacio);sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_NORMAL);sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),SensorManager.SENSOR_DELAY_NORMAL);

}@Overridepublic void onAccuracyChanged(Sensor arg0, int arg1) {}@Overridepublic void onSensorChanged(SensorEvent arg0) {synchronized (this) {……………… segueix pàgina següent ……….

Utilitzarem una nova versió de la brúixola, ja que segons diuen que el tipus TYPE_ORIENTATION ja estàdesfasat i s’ha d’utilitzar el SensorManager.getOrientation() que calcula la orientació del dispositiuutilitzant dades dels acceleròmetres i del camps magnetics. Utilitzarem 3 TextView.

Page 82: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Brúixola / Orientació

…………… ve de pàgina anterior ................

@Overridepublic void onAccuracyChanged(Sensor arg0, int arg1) {}@Overridepublic void onSensorChanged(SensorEvent arg0) {synchronized (this) {if (arg0.sensor.getType()==Sensor.TYPE_ACCELEROMETER){

acceleracio=arg0.values;acceleracions.setText("Acceleració X: "+Double.toString(acceleracio[0])+"\nAcceleració Y: "+

Double.toString(acceleracio[1])+"\nAcceleració Z: "+Double.toString(acceleracio[2]));}

if (arg0.sensor.getType()==Sensor.TYPE_MAGNETIC_FIELD){magnetisme=arg0.values;magnetismes.setText("Magnetic X: "+Double.toString(magnetisme[0])+"\nMagnetic Y: "+

Double.toString(magnetisme[1])+"\nMagnetic Z: "+Double.toString(magnetisme[2]));}

if (null != magnetisme && null != acceleracions){//Important que per als càlculs hi hagi valors inicialsSensorManager.getRotationMatrix(rotationMatrix, null, acceleracio, magnetisme);SensorManager.getOrientation(rotationMatrix, orientation);bruixola.setText("Bruixola Yaw: " + Math.toDegrees(orientation[0]) + "\nPitch: " +

Math.toDegrees(orientation[1]) +"\nRoll: " + Math.toDegrees(orientation[2]) );}

}}

}

Page 83: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Varis Sensors, un Listenerpublic class MainActivity extends Activity {TextView accelerometres,proximitats,magnetics;float [] acceleracio, magnetic, proximitat;SensorManager mSensorManager;SensorEventListener ListenerSensors;

@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);accelerometres=(TextView)findViewById(R.id.accelerometres);proximitats=(TextView)findViewById(R.id.proximitat);magnetics=(TextView)findViewById(R.id.magnetics);mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);ListenerSensors = new SensorEventListener() {

@Overridepublic void onAccuracyChanged(Sensor arg0, int arg1) {}@Overridepublic void onSensorChanged(SensorEvent arg0) {if (arg0.sensor.getType()==Sensor.TYPE_ACCELEROMETER){

acceleracio=arg0.values;accelerometres.setText("Acceleració X: "+Double.toString(acceleracio[0])+"\nAcceleració Y: "+

Double.toString(acceleracio[1])+ "\nAcceleració Z: "+Double.toString(acceleracio[2])); }; if (arg0.sensor.getType()==Sensor.TYPE_PROXIMITY){

proximitat=arg0.values;proximitats.setText("Proximitat: "+Double.toString(proximitat[0])); };

if (arg0.sensor.getType()==Sensor.TYPE_MAGNETIC_FIELD){magnetic=arg0.values;magnetics.setText("Magnetic X: "+Double.toString(magnetic[0])+"\nMagnetic Y: "+

Double.toString(magnetic[1])+"\nMagnetic Z: "+Double.toString(magnetic[2])); };}};

}public void onResume(){ ……………… segueix pàgina següent ……….

Utilitzarem 3 TextView per a mostrar el valor dels sensors d’acceleració, magnètics i de proximitat,però només utilitzarem un sol SensorEventListener extern a l’activitat.

Page 84: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Varis Sensors, un Listener

…………… ve de pàgina anterior ................

if (arg0.sensor.getType()==Sensor.TYPE_MAGNETIC_FIELD){magnetic=arg0.values;magnetics.setText("Magnetic X: "+Double.toString(magnetic[0])+"\nMagnetic Y: "+

Double.toString(magnetic[1])+"\nMagnetic Z: "+Double.toString(magnetic[2])); };}};

}public void onResume(){

super.onResume();mSensorManager.registerListener(ListenerSensors,

mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_NORMAL);

mSensorManager.registerListener(ListenerSensors,mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY),SensorManager.SENSOR_DELAY_NORMAL);

mSensorManager.registerListener(ListenerSensors,mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),SensorManager.SENSOR_DELAY_NORMAL);

}@Overrideprotected void onStop() {

mSensorManager.unregisterListener(ListenerSensors);super.onStop();

}}

Page 85: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Localització GPS/aGPS

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="edu.example.coordenades_gps"android:versionCode="1"android:versionName="1.0" ><uses-sdk

android:minSdkVersion="8"android:targetSdkVersion="15" />

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/><application

android:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activity

android:name="edu.example.coordenades_gps.MainActivity"android:label="@string/app_name" ><intent-filter>

<action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" />

</intent-filter></activity>

</application></manifest>

Per a accedir a les dades de localització del GPS, necessitem habilitar els permisos per a l’ús de lalocalització en el fitxer AndroidManifest.xml. En el codi, utilitzarem la classe LocationManager per acrear un objecte que ens permeti accedir a les dades del GPS, i la classe LocationListener, per a quecada vegada que canviï la localització, actualitzi les dades rebudes del GPS.Al polsar el botó Activar s’activa la localització per GPS, i al polsarel botó Desactivar, deixa d’actualitzar-se la posició.

Page 86: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Localització GPS/aGPSpublic class MainActivity extends Activity {private Button btnActualizar;private Button btnDesactivar;private TextView lblLatitud; private TextView lblLongitud;private TextView lblPrecision;private TextView lblEstado;private TextView lblHora;private LocationManager locManager;private LocationListener locListener;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);

btnActualizar = (Button)findViewById(R.id.BtnActualizar);btnDesactivar = (Button)findViewById(R.id.BtnDesactivar);lblLatitud = (TextView)findViewById(R.id.LblPosLatitud);lblLongitud = (TextView)findViewById(R.id.LblPosLongitud);lblPrecision = (TextView)findViewById(R.id.LblPosPrecision);lblEstado = (TextView)findViewById(R.id.LblEstado);lblHora = (TextView)findViewById(R.id.LblHora);btnActualizar.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

comenzarLocalizacion();}});

btnDesactivar.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {

locManager.removeUpdates(locListener);}});

} ……………… segueix pàgina següent ……….

En el codi, utilitzarem el GPS_PROVIDER per a adquirir les dades del GPS, però es podria utilitzar elNETWORK_PROVIDER per a utilitzar el A-GPS com a localitzador.

Page 87: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Localització GPS/aGPS…………… ve de pàgina anterior ................

public void onClick(View v) {locManager.removeUpdates(locListener);

}});}private void comenzarLocalizacion() {

locManager =(LocationManager)getSystemService(Context.LOCATION_SERVICE);Location loc =locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);mostrarPosicion(loc);locListener = new LocationListener() {

public void onLocationChanged(Location location) {mostrarPosicion(location);}

public void onProviderDisabled(String provider){lblEstado.setText("Provider OFF");}

public void onProviderEnabled(String provider){lblEstado.setText("Provider ON ");}public void onStatusChanged(String provider, int status, Bundle extras){lblEstado.setText("Provider Status: " + status);}

};locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30000, 0, locListener);

}private void mostrarPosicion(Location loc) {

if(loc != null) { lblLatitud.setText("Latitud: " + String.valueOf(loc.getLatitude()));

……………… segueix pàgina següent ……….

Page 88: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Localització GPS/aGPS…………… ve de pàgina anterior ................

locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30000, 0, locListener);}private void mostrarPosicion(Location loc) {

if(loc != null) { lblLatitud.setText("Latitud: " + String.valueOf(loc.getLatitude()));lblLongitud.setText("Longitud: " + String.valueOf(loc.getLongitude()));lblPrecision.setText("Precision: " + String.valueOf(loc.getAccuracy()));lblHora.setText("Hora GPS: "+ new Date(loc.getTime()).toString());}

else {lblLatitud.setText("Latitud: (sin_datos)");lblLongitud.setText("Longitud: (sin_datos)");lblPrecision.setText("Precision: (sin_datos)");}

}}

http://www.sgoliver.net/blog/?p=1887

if (!locManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {Pgps.setText("GPS desactivat");

} else {Pgps.setText("GPS activat");}

if (!locManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {PAgps.setText("A-GPS desactivat");

} else {PAgps.setText("A-GPS activat");}

Afegiu dos TextView i el següent codi per a comprovar quin dels sistemes de localització del dispositiuestà activat.

Page 89: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

• http://www.androidcurso.com/• http://www.sgoliver.net• http://yoandroido.blogspot.com.es/• http://www.javaya.com.ar/androidya/index.p

hp?inicio=• http://elbauldelprogramador.com/curso-

programacion-android/• http://www.androidadb.com

Page 90: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

AndroidDades

Cristobal Raya Giner

Programació de Dispositius Mòbils (PRDM)

Page 91: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Internacionalització

<TextViewandroid:id="@+id/textView0"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/hello_world" />

<TextViewandroid:id="@+id/textView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/imtrying" />

<TextViewandroid:id="@+id/textView2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/language" />

Normalment cada usuari té configurat el seu dispositiu Android amb el seu idioma, que espot canviar en el menú d’ajustos del dispositiu Android. Per a realitzar una aplicacióadaptada a l’idioma de l’usuari, es treballa amb les etiquetes de Strings del fitxerstring.xml. Creem un Layout amb varis TextView, amb el text assignat mitjançant etiquetes.

Page 92: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

<?xml version="1.0" encoding="utf-8"?><resources>

<string name="app_name">Canvi_idioma</string><string name="action_settings">Ajustes</string><string name="hello_world">Hola Mundo!</string><string name="imtrying">Estoy probando</string><string name="language">Idioma Castellano</string>

</resources>

<?xml version="1.0" encoding="utf-8"?><resources>

<string name="hello_world">Hola mon!</string><string name="imtrying">Estic provant</string><string name="language">Idioma Català</string>

</resources>

<?xml version="1.0" encoding="utf-8"?><resources>

<string name="app_name">Change Language</string><string name="action_settings">Settings</string><string name="hello_world">Hello world!</string><string name="imtrying">I\'m trying</string><string name="language">English Language</string>

</resources>

Creem una carpeta per a cada idioma amb el format values-XX on XX és l’abreviatura de l’idiomasegons el codi ISO 639-1. Dins de cada carpeta hi ha un fitxer string.xlm on hi ha la mateixa etiquetaper a cada idioma, però amb el text corresponent a l’idioma. Per a les etiquetes que no existeixin enels idiomes, s’utilitzen les etiquetes del fitxer d’Strings de la carpeta per defecte values.Per a especificar l’idioma segons la localització, diferenciant l'anglès de Gran Bretanya (GB) de l'anglèsd’Australia (AU), les carpetes utilitzen el format values-XX-rYY on YY utilitza el codi ISO 3166-1:

values-en-rGB.xml , values-en-rAU.xml

Internacionalització

ISO 639-1

ca Català

es Castellà

en Anglés

eu Eusquera

fr Francés

de Alemany

ga Irlandés

gl Gallec

Page 93: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Emmagatzemament de dadesAndroid ens facilita varies possibilitats per a emmagatzemar dadespermanentment per a que no s’esborrin quan s’apagui l’aplicació.

Els principals mètodes proporcionats són:

• Classe SharedPreferences: Per a una quantitat limitada dedades com configuracions de les aplicacions, punts o nivellsd’un joc, etc...

• Arxius de Text: Per a una més gran quantitat de dades, que esguardarà en una arxiu en l’emmagatzemament intern deldispositiu o la tarja SD

• Bases de dades: Per a emmagatzemar dades en formaorganitzada utilitzant bases de dades basades en SQL Lite.

Page 94: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

SharedPreferencesAmb la classe SharedPreferences, es poden guardar conjunts de dades en la memòriainterna del dispositiu. Les dades queden emmagatzemades inclús reiniciant el dispositiu,com a dades de l’aplicació. Hi ha varis modes de compartició de les dades:• MODE_PRIVATE només l’aplicació pot accedir a les dades.• MODE_WORLD_READABLE altres aplicacions poden accedir i llegir les dades. (<API17)• MODE_WORLD_WRITEABLE altres aplicacions poden accedir a les dades per a llegir-

les i modificar-les. (<API17)• MODE_MULTI_PROCESS varis processos poden accedir. (> API9)

Crearem una aplicació que ens permet llegir i guardar un String (nom), un Integer (edat) iun Float (alçada), mitjançant dos botons.

Page 95: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

SharedPreferencesGuardem les tres dades en el grup “dades” en el MODE_PRIVATE per a quenomés l’aplicació pugui tenir accés.public class MainActivity extends Activity {EditText Nom, Edat, Alcada;Button btllegeix, btguarda;

@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Nom = (EditText) findViewById(R.id.nom);Edat = (EditText) findViewById(R.id.edat);Alcada = (EditText) findViewById(R.id.alcada);btllegeix = (Button)findViewById(R.id.llegeix);btguarda = (Button)findViewById(R.id.guarda);btllegeix.setOnClickListener (new View.OnClickListener() {

@Overridepublic void onClick(View v) {

SharedPreferences llegeixprefe=getSharedPreferences("dades",Context.MODE_PRIVATE);Nom.setText(llegeixprefe.getString("nomguarda",""));Edat.setText(String.valueOf(llegeixprefe.getInt("edatguarda",0)));Alcada.setText(String.valueOf(llegeixprefe.getFloat("alcadaguarda",0f)));

}});btguarda.setOnClickListener (new View.OnClickListener() {

............ segueix després ................

Page 96: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

SharedPreferences

............ segueix abans ................

Edat.setText(String.valueOf(llegeixprefe.getInt("edatguarda",0)));Alcada.setText(String.valueOf(llegeixprefe.getFloat("alcadaguarda",0f)));

}});btguarda.setOnClickListener (new View.OnClickListener() {

@Overridepublic void onClick(View v) {

SharedPreferences escriuprefe=getSharedPreferences("dades",Context.MODE_PRIVATE);Editor editor=escriuprefe.edit();editor.putString("nomguarda", Nom.getText().toString());editor.putInt("edatguarda", Integer.parseInt(Edat.getText().toString()));editor.putFloat("alcadaguarda", Float.parseFloat(Alcada.getText().toString()));editor.commit();

}});

}}

Page 97: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Preference Activity

Primer crear la carpeta /res/xml si no existeix.Crear un nou fitxer .xml de tipus Resource Type: Preferences, icom a element principal, elegim un PreferenceScreen.

Dins de l’element principal, podem separar les preferències encategories, i afegir diferents elements.Entre d’altres, podem tenir:• CheckBoxPreference: Selecció de verdader o fals• EditTextPreference: Text simple (poden ser números)• ListPreference: Selecció d’un valor d’una llista

En el nostre exemple, afegim dos categories. En la primera unCheckBoxPreference i un EditTextPreference, i en la segona unListPreference i un CheckBoxPreference.

Com a alternativa a introduir dades SharedPreferences, podemutilitzar una PrefenceActivity per a una mostrar una pantalla per ala introducció de les dades. (En les noves APIs comença a estar en desús)

Page 98: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Preference Activity

<?xml version="1.0" encoding="utf-8"?><resources>

<string-array name="acronim"><item >PRDM</item><item >ECUS</item><item >SIOP</item><item >SIAC</item>

</string-array><string-array name="assignatura">

<item >Programació de Dispositius Mòbils</item><item >Enginyeria Centrada en l\'Usuari</item><item >Simulació i Optimització</item><item >Sistemes Avançats de Control</item>

</string-array>

</resources>

Per als valors de la llista, crearem un nou fitxer xml de valors.

Afegim 2 Strings Arrays i els diferents elements de la llista

Page 99: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Preference Activity

<?xml version="1.0" encoding="utf-8"?><PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

<PreferenceCategory android:title="Categoria 1"><CheckBoxPreference

android:summary="Descripció del primer check" android:key="check1" android:title="Titol check 1"/>

<EditTextPreference android:summary="Escriu alguna cosa" android:title="Titol del Edit Text 1" android:key="texte1"/>

</PreferenceCategory><PreferenceCategory android:title="Segona categoría">

<ListPreference android:title="Llistat de valors" android:summary="Selecciona una opció de la llista" android:key="llista" android:entries="@array/assignatura" android:entryValues="@array/acronim"/>

<CheckBoxPreference android:summary="Clica per canviar" android:key="check2" android:title="Segon check"/>

</PreferenceCategory></PreferenceScreen>

Ara podem introduir tots els paràmetres i etiquetes al fitxer de preferències. L’etiqueta “key” indica lavariable o propietat on es guardarà el valor de la preferència. L’etiqueta “title” indica text del títol de lapreferència. L’etiqueta “summary” indica la descripció de la preferència. En la llista les etiquetes“entries” indica la llista de valors, dels quals el seleccionat es guardarà, i “entryValues” la descripció.

Page 100: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Preference Activity

package edu.example.dades_pref_activity;

import android.os.Bundle;import android.preference.PreferenceActivity;

public class PantallaOpcions extends PreferenceActivity {

@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

addPreferencesFromResource(R.xml.opcions);

}

}

Per a mostrar la pantalla de preferències, creem una novaclasse en el projecte (NewClass) sigui una extensió de laclasse PreferenceActivity. En ella enllacem el fitxer depreferències amb el mètode addPreferencesFromResource().

Hem de afegir la nova Activitat (classe) al fitxerAndroidManifest.xml

<activity android:name="PantallaOpcions"></activity>

Page 101: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Preference Activity

public class MainActivity extends Activity {TextView dades;Button llegir, escriure;

@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);dades = (TextView) findViewById (R.id.textView1);llegir = (Button) findViewById (R.id.button1);escriure = (Button) findViewById (R.id.button2);escriure.setOnClickListener(new View.OnClickListener() {

@Overridepublic void onClick(View v) {Intent i = new Intent(MainActivity.this,PantallaOpcions.class);startActivity(i);}

});llegir.setOnClickListener(new View.OnClickListener() {

@Overridepublic void onClick(View v) {SharedPreferences preferencies =PreferenceManager.getDefaultSharedPreferences(MainActivity.this);dades.setText("Opció check1 = "+preferencies.getBoolean("check1",false)

+"\nOpció texte1 = "+ preferencies.getString("texte1", "")+"\nOpció llista = "+ preferencies.getString("llista", "")+"\nOpció check2 = "+ preferencies.getBoolean("check2", false));

}});

}}

Ja tenim configurat la part de les preferències. Ara configurem l’activitat principal de l’exemple creantun Layout amb dos botons (per a llegir i escriure les preferències) i un text (per a mostrar lespreferències).Per a que aparegui la pantalla de preferències creem un Intent a la Activitatcreada, i per a llegir les preferències, utilitzem l’objecte SharedPreferences

Page 102: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Arxius de text internsAltre alternativa a emmagatzemar dades, és mitjançant fitxers de text enl’emmagatzemament intern del dispositiu. Solen ser fitxers privats a l’aplicació ques’emmagatzemen a la carpeta privada /data/data/nom.projecte.aplicacio/files.

Crearem una aplicació que ens permet llegir i guardar un fitxer de text. Creem unTextView, un EditText i un botó. El EditText el configurem multilínia amb barra vertical.

<EditTextandroid:id="@+id/textev"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentLeft="true"android:layout_below="@+id/textView1"android:ems="10"android:inputType="textMultiLine"android:lines="6"android:scrollbars="vertical" >

<requestFocus /></EditText>

Page 103: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Arxius de text internsEn el codi es verifica si existeix el fitxer, si existeix el llegeix i mostra elcontingut per a modificar-lo. Al polsar el botó, es grava el text al fitxer.public class MainActivity extends Activity {EditText texte;Button grava;@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);texte = (EditText)findViewById(R.id.textev);grava = (Button) findViewById(R.id.grava);TextView carpeta = (TextView) findViewById(R.id.textView1);grava.setOnClickListener(new View.OnClickListener() {

@Overridepublic void onClick(View v) {gravafitxer(v);}});

String[] archivos = fileList();carpeta.setText(String.valueOf(getFilesDir()));if (existeixfitxer(archivos, "notas.txt"))

try { InputStreamReader archivo = new InputStreamReader(openFileInput("notas.txt"));BufferedReader br = new BufferedReader(archivo);String linea = br.readLine();String todo = "";while (linea != null) {

todo = todo + linea + "\n";linea = br.readLine(); }

br.close();archivo.close();texte.setText(todo);

} catch (IOException e) {// No gestionem errors } } ............ segueix després ................

Page 104: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Arxius de text interns

............ segueix abans ................} catch (IOException e) {// No gestionem errors}}

private boolean existeixfitxer(String[] archivos, String archbusca) {for (int f = 0; f < archivos.length; f++)

if (archbusca.equals(archivos[f]))return true;

return false;}public void gravafitxer(View v) {

try {OutputStreamWriter archivo = new OutputStreamWriter(openFileOutput("notas.txt", Activity.MODE_PRIVATE));archivo.write(texte.getText().toString());archivo.flush();archivo.close();

} catch (IOException e) {}Toast t = Toast.makeText(this, “Les dades s’han gravat", Toast.LENGTH_SHORT);t.show();

}}

Page 105: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Arxius de text en SDTambé es poden emmagatzemar fitxers de text en la memòria SD del dispositiu, que nonecessàriament ha de ser una tarja SD. Els fitxer son accessibles des de qualsevolaplicació.Crearem una aplicació que ens permet llegir i guardar un fitxer de text a la SD. Creem unTextView, dos EditText i dos botons.

Modifiquem els permisos al fitxer AndroidManifest.xml per a poder escriure a la SD:

Page 106: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Arxius de text en SDEn el codi, al polsar gravar llegeix la carpeta per defecte (/mnt/sdcard) i gravales dades.public class MainActivity extends Activity {EditText nomfitxer,dades;Button gravar,llegir;

@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);nomfitxer = (EditText)findViewById (R.id.nomf);dades = (EditText)findViewById (R.id.textev);gravar = (Button)findViewById (R.id.grava);llegir = (Button)findViewById (R.id.llegeix);gravar.setOnClickListener(new View.OnClickListener() {

@Overridepublic void onClick(View v) {String nomarxiu = nomfitxer.getText().toString();

String dadesfitxer = dades.getText().toString();try {

File targeta = Environment.getExternalStorageDirectory();File file = new File(targeta.getAbsolutePath(), nomarxiu);OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(file));osw.write(dadesfitxer);osw.flush();osw.close();Toast.makeText(MainActivity.this, “Dades gravades", Toast.LENGTH_SHORT).show();nomfitxer.setText("");dades.setText("");

} catch (IOException ioe) { }} });

llegir.setOnClickListener(new View.OnClickListener() {............ segueix després ................

Page 107: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Arxius de text en SDAl polsar el botó de llegir, llegeix la carpeta per defecte i llegeix línia a línia.

............ segueix abans ................dades.setText("");

} catch (IOException ioe) { }}});llegir.setOnClickListener(new View.OnClickListener() {

@Overridepublic void onClick(View v) {String nomarxiu = nomfitxer.getText().toString();File targeta = Environment.getExternalStorageDirectory();File file = new File(targeta.getAbsolutePath(), nomarxiu);try {

FileInputStream fIn = new FileInputStream(file);InputStreamReader archivo = new InputStreamReader(fIn);BufferedReader br = new BufferedReader(archivo);String linea = br.readLine();String todo = "";while (linea != null) {

todo = todo + linea + "";linea = br.readLine();

}br.close();archivo.close();dades.setText(todo);} catch (IOException e) {

}}

});}

}

Page 108: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Arxius de text en SDCom a alternatives a gravar el fitxer en una carpeta diferent, podem tenir(entre d’altres) aquestes:La carpeta d’emmagatzemament per defecte: /mnt/sdcard

Directament indicar una carpeta: /mnt/sdcard/Download

Indicar la carpeta a partir del camí per defecte: /mnt/sdcard/Download

Indicar la carpeta per defecte per a un determinat tipus: /mnt/sdcard/Download

En cas d’utilitzar una tarja externa tipus microSD, el camí canvia a/mnt/extSdCard. Es pot comprovar l’estat (o existència) de les carpetes amb elmètode Environment.getExternalStorageState()

File targeta = Environment.getExternalStorageDirectory(); File file = new File(targeta.getAbsolutePath(), nomarxiu);

File file = new File("/mnt/sdcard/Download", nomarxiu);

File targeta = Environment.getExternalStorageDirectory(); File file = new File(targeta.getAbsolutePath()+"/Download", nomarxiu);

File targeta = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);File file = new File(targeta.getAbsolutePath(), nomarxiu);

Page 109: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Bases de dades amb SQL LiteUna altre opció per a emmagatzemar dades, és utilitzar bases de dadesmitjançant comandes SQL.Crearem una activitat que ens permeti emmagatzemar telèfons de contactes.La base de dades l’anomenarem “ DadesContacte “ amb una taula anomenada“contactes”, i tindrà els camps nom, telefon, mail i categoria.

Page 110: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Bases de dades amb SQL LiteAbans de escriure el codi java necessitem crear una classe hereva deSQLiteOnenHelper, per a que permeti crear i modificar l’estructura de la Basede dades.

import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper;

public class GestorSQLiteOpenHelper extends SQLiteOpenHelper{

public GestorSQLiteOpenHelper(Context context, String name,CursorFactory factory, int version) {super(context, name, factory, version);// Aquest és el constructor de la classe pare}

@Override //onCreate s'executa al crear la base de dades.public void onCreate(SQLiteDatabase db) {

db.execSQL("CREATE TABLE contactes (nom TEXT, telefon INTEGER, mail TEXT, categoria TEXT)");}

// onUpgrade s'executa al actualitzar l'estructura de la base de dades. En l'exemple s'esborra// i es torna a crear nova@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

db.execSQL("DROP TABLE IF EXISTS contactes");db.execSQL("CREATE TABLE contactes (nom TEXT, telefon INTEGER PRIMARY KEY, mail TEXT,

categoria TEXT)");}

}

Page 111: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Bases de dades amb SQL LiteEn el codi primer realitzem els enllaços entre el Layout i els objectes, iassignem les accions corresponents als botons.public class MainActivity extends Activity {

EditText nom, telefon, email, categoria;Button balta, bbaixa, bmodifica, bconsulta;@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);nom = (EditText) findViewById(R.id.editnom);telefon = (EditText) findViewById(R.id.editelefon);email = (EditText) findViewById(R.id.editmail);categoria = (EditText) findViewById(R.id.editcateg);balta = (Button) findViewById (R.id.buttonalta);bbaixa = (Button) findViewById (R.id.buttonbaixa);bmodifica = (Button) findViewById (R.id.buttonmod);bconsulta = (Button) findViewById (R.id.buttoncons);balta.setOnClickListener(new View.OnClickListener() {

@Overridepublic void onClick(View v) { alta(); }});

bconsulta.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) { consulta(); }});

bmodifica.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) { modifica(); }});

bbaixa.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) { baixa(); }});

}

............ segueix després ................

Page 112: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Bases de dades amb SQL LiteContinuem amb les diferents funcions. La funció alta() guarda tots els camps ala taula “contactes” de la base de dades “DadesContacte”:............ segueix abans ................

bbaixa.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) { baixa(); }});

}

public void alta(){GestorSQLiteOpenHelper gestor = new GestorSQLiteOpenHelper(this,"DadesContacte",null,1);SQLiteDatabase bd=gestor.getWritableDatabase();String bdnom = enom.getText().toString();Integer bdtelefon = Integer.valueOf(etelefon.getText().toString());String bdmail = email.getText().toString();String bdcategoria = ecategoria.getText().toString();ContentValues registre = new ContentValues();registre.put("nom", bdnom);registre.put("telefon", bdtelefon);registre.put("mail",bdmail);registre.put("categoria", bdcategoria);bd.insert("contactes", null, registre);bd.close();enom.setText("");etelefon.setText("");email.setText("");ecategoria.setText("");Toast.makeText(this, "Dades guardades", Toast.LENGTH_SHORT).show();

};

public void consulta(){ //Consulta per telefon............ segueix després ................

Page 113: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Bases de dades amb SQL LiteContinuem amb les diferents funcions. La funció consulta() busca el contacteque tingui el número de telèfon indicat:

............ segueix abans ................Toast.makeText(this, "Dades guardades", Toast.LENGTH_SHORT).show();

};

public void consulta(){ //Consulta per telefonGestorSQLiteOpenHelper gestor = new GestorSQLiteOpenHelper(this,"DadesContacte",null,1);SQLiteDatabase bd=gestor.getWritableDatabase();Integer bdtelefon = Integer.valueOf(etelefon.getText().toString());Cursor fila=bd.rawQuery("SELECT nom, mail,categoria FROM contactes WHERE telefon="+bdtelefon,null);if (fila.moveToFirst()){

enom.setText(fila.getString(0));email.setText(fila.getString(1));ecategoria.setText(fila.getString(2));

} elseToast.makeText(this,"No existeix el telefon", Toast.LENGTH_SHORT).show();

};

public void baixa(){............ segueix després ................

Page 114: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Bases de dades amb SQL LiteContinuem amb les diferents funcions. La funció baixa() esborra el contacteamb el número de telèfon indicat:

............ segueix abans ................Toast.makeText(this,"No existeix el telefon", Toast.LENGTH_SHORT).show();

};

public void baixa(){GestorSQLiteOpenHelper gestor = new GestorSQLiteOpenHelper(this,"DadesContacte",null,1);SQLiteDatabase bd=gestor.getWritableDatabase();Integer bdtelefon = Integer.valueOf(etelefon.getText().toString());int err = bd.delete("contactes", "telefon="+bdtelefon, null);bd.close();enom.setText("");etelefon.setText("");email.setText("");ecategoria.setText("");if (err==1) Toast.makeText(this,"S'ha esborrat el contacte", Toast.LENGTH_SHORT).show();else Toast.makeText(this,"No existeix el contacte", Toast.LENGTH_SHORT).show();

};public void modifica(){

............ segueix després ................

Page 115: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Bases de dades amb SQL LiteContinuem amb les diferents funcions. La funció modifica() el contacte amb elnúmero de telèfon indicat:............ segueix abans ................

if (err==1) Toast.makeText(this,"S'ha esborrat el contacte", Toast.LENGTH_SHORT).show();else Toast.makeText(this,"No existeix el contacte", Toast.LENGTH_SHORT).show();

};public void modifica(){

GestorSQLiteOpenHelper gestor = new GestorSQLiteOpenHelper(this,"DadesContacte",null,1);SQLiteDatabase bd=gestor.getWritableDatabase();String bdnom = enom.getText().toString();Integer bdtelefon = Integer.valueOf(etelefon.getText().toString());String bdmail = email.getText().toString();String bdcategoria = ecategoria.getText().toString();ContentValues registre = new ContentValues();registre.put("nom", bdnom);registre.put("telefon", bdtelefon);registre.put("mail",bdmail);registre.put("categoria", bdcategoria);int err = bd.update("contactes", registre,"telefon="+bdtelefon, null);bd.close();if (err==1) Toast.makeText(this,"S'ha modificat el contacte", Toast.LENGTH_SHORT).show();else Toast.makeText(this,"No existeix el contacte", Toast.LENGTH_SHORT).show();

};}

Page 116: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Bases de dades amb SQL LiteEntre altres comandes, per exemple, si volguéssim aconseguir el nombre totalde registres es faria afegint una consulta SELECT count(*) FROM taula , ipodem mostrar el resultat en un TextView:

............ segueix abans ................Button balta, bbaixa, bmodifica, bconsulta;TextView totalregbd;@Overrideprotected void onCreate(Bundle savedInstanceState) {............................

registre.put("categoria", bdcategoria);bd.insert("contactes", null, registre);totalregbd.setText("Total Registres "+totalregistres(bd));bd.close();enom.setText("");

..............

..............int err = bd.delete("contactes", "telefon="+bdtelefon, null);totalregbd.setText("Total Registres "+totalregistres(bd));bd.close();enom.setText("");

..............

..............public String totalregistres(SQLiteDatabase db){

SQLiteStatement statement = db.compileStatement("SELECT count(*) FROM contactes");long contador = statement.simpleQueryForLong();return String.valueOf(contador);

}

Page 117: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

• http://www.androidcurso.com/• http://www.sgoliver.net• http://yoandroido.blogspot.com.es/• http://www.javaya.com.ar/androidya/index.p

hp?inicio• http://elbauldelprogramador.com/curso-

programacion-android/• http://www.androidadb.com

Page 118: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

AndroidVaris

Cristobal Raya Giner

Programació de Dispositius Mòbils (PRDM)

Page 119: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Log per a depuració

import android.app.Activity;import android.os.Bundle;import android.util.Log;public class MainActivity extends Activity {

@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Log.e("Tag_del_log", "Missatje d'error");Log.w("Tag_del_log", "Missatje de warning");Log.i("Tag_del_log", "Missatje d'informació");Log.d("Tag_del_log", "Missatje de depuració");Log.v("Tag_del_log", "Missatje de verbose");

}}

Els Logs, serveixen per a mostrar missatges durant la depuració de les aplicacionsen l’emulador a la finestra LogCat. Segons el tipus de Log indicat (e,w,i,d,v),apareix el missatge en un color diferent. El Tag de la instrucció Log, serveix per a

poder agrupar i filtrar els diferentsmissatges.

Page 120: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Gestió d’errors

try {// Codi normal a executar

} catch (IOException e) {// Codi en cas de IOException

} catch (MalformedURLException e) {// Codi en cas de MalformedURLException

} catch (Exception e) {// Codi en cas de Exception generica

} catch (Altretipus e) {// Codi en cas de Exception generica

.

.

.

.} finally {

// Codi a executar independentment de si hi ha o no error}

Per a gestionar els errors en temps d’execució d’una aplicació, i evitar que aparegui una finestraindicant error i finalitzi l’aplicació, podem capturar els errors amb les sentències try, catch, finally. Escomença amb la sentència try, on s’ubica el codi normal a executar on es pot produir l’error.Seguidament podem tenir una o varies sentencies catch, on en funció del tipus d’error s’executarà elcodi corresponent a la gestió de l’error. Finalment, i de forma opcional, la sentència finally permetexecutar un codi independentment de si hi ha hagut error, després de la captura de l’error.

Page 121: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Reproducció de so

public class MainActivity extends Activity {Button btn;

@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);

btn = (Button) findViewById (R.id.button1);

btn.setOnClickListener(new View.OnClickListener() {@Override

public void onClick(View v) {so_tada();

}

});

}

public void so_tada(){MediaPlayer mp = MediaPlayer.create(this, R.raw.tada);mp.start();

}

}

Android pot reproduïr per defecte fitxers de so dels tipus mp3, ogg i wav. Els fitxers de so s’han de trobar a la carpeta /res/raw, i el nom només pot contenir lletres minúscules de (a-z), números (0-9) i el guió baix (_). Per a la reproducció de un so s’utilitza la llibreria androd.media.MediaPlayer:

Page 122: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Reproducció de so. Control marxa.public class MainActivity extends Activity {

Button binici,bpara,bpausa,bcontinua;

MediaPlayer mp;

int posicio = 0;@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);

binici = (Button) findViewById (R.id.inici);

bpara = (Button) findViewById (R.id.para);

bpausa = (Button) findViewById (R.id.pausa);

bcontinua = (Button) findViewById (R.id.continua);

binici.setOnClickListener(new View.OnClickListener() {@Override

public void onClick(View v) {iniciar();

}

});

bpara.setOnClickListener(new View.OnClickListener() {@Override

public void onClick(View v) {para();

}

});

…………. Segueix després …………

Es pot controlar quan s’inicia, es para, es pausa i es continua un arxiu de so.

Page 123: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Reproducció de so. Control marxa.…………. Segueix abanss …………

binici.setOnClickListener(new View.OnClickListener() {@Override

public void onClick(View v) {iniciar();

}

});

bpara.setOnClickListener(new View.OnClickListener() {@Override

public void onClick(View v) {para();

}

});

bpausa.setOnClickListener(new View.OnClickListener() {@Override

public void onClick(View v) {pausa();

}

});

bcontinua.setOnClickListener(new View.OnClickListener() {@Override

public void onClick(View v) {continua();

}

});

}

…………. Segueix després …………

Continuem amb els listeners dels botons:

Page 124: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Reproducció de so. Control marxa.…………. Segueix abanss …………

}

public void iniciar() {if (mp != null) mp.release();mp = MediaPlayer.create(this, R.raw.balkan_brass_gummy_bear);mp.start();

mp.setLooping(false);}

public void pausa() {if (mp != null && mp.isPlaying()) {

posicio = mp.getCurrentPosition();

mp.pause();

}

}

public void continua() {if (mp != null && mp.isPlaying() == false) {

mp.seekTo(posicio);

mp.start();

}

}

public void para() {if (mp != null) {

mp.stop();

posicio = 0;

}

}

}

Acabem amb les funcions de control de l’arxiu fora del onCreate:

Page 125: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Detectar pulsació pantallapublic class MainActivity extends Activity {

LinearLayout pantalla;TextView text, textpant;@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);text = (TextView) findViewById (R.id.textv);textpant = (TextView) findViewById (R.id.textpantalla);pantalla = (LinearLayout)findViewById (R.id.Lpantalla);pantalla.setOnTouchListener(new View.OnTouchListener() {

@Overridepublic boolean onTouch(View v, MotionEvent event) {

text.setText("Pantalla Polsada");String puntX = String.valueOf((int)event.getX());String puntY = String.valueOf((int)event.getY());String pressio = String.valueOf((float) event.getPressure());String temps = String.valueOf((float) event.getEventTime());textpant.setText("Has polsar la pantalla al punt X = "+puntX+" , Y = "+puntY+"\n" +" amb una pressió = "+pressio+" al temps ="+temps);return false;

}});text.setOnTouchListener(new View.OnTouchListener() {

@Overridepublic boolean onTouch(View v, MotionEvent event) {text.setText("Text Polsat");return false;}

});}

}

Podem llegir les coordenades de pulsació en un objecte al Layout amb onTouch i MotionEvent:

Page 126: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Detectar pulsació en un Layoutpublic class MainActivity extends Activity {

TextView text;

RelativeLayout pantalla;

@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);

text = (TextView) findViewById(R.id.textv);

pantalla = (RelativeLayout) findViewById (R.id.layout_pantalla);

pantalla.setOnTouchListener(new View.OnTouchListener() {@Override

public boolean onTouch(View v, MotionEvent event) {int accio = event.getAction(); String X = String.valueOf((int)event.getX());String Y = String.valueOf((int)event.getY());switch (accio){

case MotionEvent.ACTION_DOWN:text.setText("Has polsat a les coordenades X = "+X+" , Y = "+Y);

break;case MotionEvent.ACTION_MOVE:

text.setText("Et mous per les coordenades X = "+X+" , Y = "+Y);

break;case MotionEvent.ACTION_UP:

text.setText("Has deixat de polsar a les coordenades X = "+X+" , Y = "+Y);

break; }

return true;}

});

}}

onTouch i MotionEvent també permet detectar events com quan es polsa, quan es deixa de polsar, i quan es desplaça el dit per un Layout:

Page 127: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Detectar varies pulsacions pantallapublic class MainActivity extends Activity {

TextView text;

@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);

text = (TextView) findViewById (R.id.textv);

}

@Override

public boolean onTouchEvent(MotionEvent event) {switch (event.getAction()& MotionEvent.ACTION_MASK){case (MotionEvent.ACTION_DOWN) :

break;case (MotionEvent.ACTION_MOVE) :

try{int num = event.getPointerCount();text.setText("Punts: "+num+"\n");

for (int a = 0; a < num; a++) {int x = (int) event.getX(event.getPointerId(a));int y = (int) event.getY(event.getPointerId(a));text.append("Punt " + event.getPointerId(a) + ": x = " + x + ", y = " + y +"\n");

};} catch (Exception e){};break;

case MotionEvent.ACTION_UP:text.setText("Cap punt");

break;}

return true;}

}

Per a detectar varies pulsacions simultànies de la pantalla (MultiTouch), s’utilitza el mètode onTouchEvent que proporciona la pròpia Activity

Page 128: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Animacions de ViewsLes animacions Tween, són animacions que permeten mitjançant un codi XML realitzar transformacions simples (rotació, translació, mida, transparència) en objectes de tipus View. Els diferents fitxers amb el codi XML de la animació, han d’estar guardats a la carpeta /res/anim del projecte, i el recurs es referenciarà amb l’identificador R.anim.recurs. Dins del fitxer pot haver una sola transformació, o pot haver una combinació indicant el grup amb la etiqueta <set> </set>.

Les següents etiquetes genèriques s’apliquen a totes les transformacions:• startOffset: Instant inicial de la transformació en mil·lisegons• duration: Durada de la transformació en mil·lisegons.• repeatCount: Repeticions addicionals de la animació• interpolator– S’indica el tipus d’interpolació a aplicar, en lloc de una interpolació lineal. Alguns possibles valors:

accelerate_decelerate_interpolator, accelerate_interpolator, anticipate_interpolator, anticipate_overshoot_interpolator, bounce_interpolator, cycle_interpolator, decelerate_interpolator, linear_interpolator, overshoot_interpolator

La llista de transformacions i els seus atributs específics de les transformacions són:- <translate> – Realitza un desplaçament del View• fromXDelta, toXDelta – Valor inicial i final del desplaçament en eix X• fromYDelta, toYDelta – Valor inicial i final del desplaçament en eix Y.- <rotate> – Rotació del View

• fromDegrees, toDegrees – Valor inicial i final en graus de la rotació. Sentit antihorari posar de 0 a 360, sentit horari de 360 a 0 o de 0 a -360. Per a dos girs posar de 0 a 720, etc...

• pivotX, pivotY– Punt que queda fix sobre el que es realitzarà el gir.- <scale> – Canvia mida del View

• fromXScale,toXScale – Valor inicial i final per a l’escala de l’eix X (0.5=50%, 1=100%)• fromYScale, toYScale – Valor inicial i final per a l’escala de l’eix Y• pivotX, pivotY– Punt que queda fix sobre el que es realitzarà el zoom.

- <alpha> – Canvia la opacitat del View• fromAlpha, toAlpha – Valor inicial i final de la opacitat

Page 129: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Animacions de Views

<?xml version="1.0" encoding="UTF-8"?><set xmlns:android="http://schemas.android.com/apk/res/android">

<scaleandroid:duration="2000"android:fromXScale="2.0"android:fromYScale="2.0"android:toXScale="1.0"android:toYScale="1.0" />

<rotateandroid:startOffset="2000"android:duration="2000"android:fromDegrees="0"android:toDegrees="360"android:pivotX="50%"android:pivotY="50%"/>

<translateandroid:startOffset="4000"android:duration="2000"android:fromXDelta="0"android:fromYDelta="0"android:toXDelta="50"android:toYDelta="100" />

<alphaandroid:startOffset="4000"android:duration="2000"android:fromAlpha="1"android:toAlpha="0" />

</set>

Creem la carpeta /res/anim, i afegim un nou fitxer .xml amb la definició de la animació. En l’exemple esrealitza primer un canvi de mida, després una rotació, seguidament de una combinació de translacióamb transparència.

Page 130: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Animacions de Views

public class MainActivity extends Activity {Button boto;TextView textv;

@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);boto = (Button) findViewById(R.id.button1);boto.setOnClickListener(new View.OnClickListener() {

@Overridepublic void onClick(View v) {

Animar_boto();}

});}public void Animar_boto(){Animation grup =AnimationUtils.loadAnimation(this, R.anim.grup_animacions);grup.reset();boto.startAnimation(grup);}

}

Utilitzem un sol botó al qual li assignem la animació anterior per a que s'iniciï al polsar el botó.

Page 131: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Dibuixar en Layout

public class MainActivity extends Activity {RelativeLayout pantalla;

TextView textv;

@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);

textv = (TextView) findViewById (R.id.textv);

pantalla = (RelativeLayout) findViewById(R.id.Layout_pantalla);

Dibuix dibuix = new Dibuix(this);pantalla.addView(dibuix);

}

class Dibuix extends View {public Dibuix(Context context) {super(context);}

public void onDraw(Canvas canvas) {int ample = canvas.getWidth();int alt = canvas.getHeight();textv.setText("ample: "+ample+" alt: "+alt);

Paint pinzell = new Paint();pinzell.setARGB(255, 255, 0, 0);

pinzell.setStyle(Style.STROKE);

……… segueix ……

Podem dibuixar en Layouts mitjançant el mètode onDraw(), però fent primer una extensió de la classeView. S’utilitza un objecte Canvas per a definir que dibuixar, i un objecte Paint per a definir comdibuixar.

………… ve abans …………

pinzell.setStyle(Style.STROKE);

canvas.drawCircle(ample / 2, alt / 2, 150, pinzell);

pinzell.setStrokeWidth(3);

canvas.drawRect((ample/2)-50, (alt/2)-40, (ample/2)+50,(alt/2)+40, pinzell);

canvas.drawLine((ample/2)-50, (alt/2)-40, (ample/2)+50, (alt/2)+40, pinzell);

pinzell.setStrokeWidth(20);

canvas.drawPoint(ample / 2, alt / 2, pinzell);

pinzell.setStrokeWidth(1);

pinzell.setStyle(Style.FILL_AND_STROKE);

pinzell.setTypeface(Typeface.SERIF);

pinzell.setTextSize(20);

canvas.drawText("Dibuix de text", (ample/2)-50, (alt/2)-40,pinzell);

}

}

}

Page 132: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Llistat Fitxers Carpeta

public class MainActivity extends Activity {TextView text;

File lfile;

@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);

text = (TextView) findViewById(R.id.textv);

String path = Environment.getExternalStorageDirectory().toString();

//lfile=new File("/sdcard");

lfile=new File(path);File[] list=lfile.listFiles();

text.setText("Total fitxers: "+ String.valueOf(lfile.listFiles().length) + "\n");

for (int i=0;i<lfile.listFiles().length;i++) {if (list[i].isHidden()) text.append("Fitxer ocult: ");if (list[i].isDirectory()) text.append("Carpeta: ");if (list[i].isFile()) text.append("Fitxer: ");text.append(list[i].getAbsolutePath().toString()+"\n");

}

}

}

Per a llistar els fitxers de una carpeta, creem l’objecte File:

Page 133: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Llistat i selecció de Fitxers

public class MainActivity extends Activity {TextView seleccio;ListView llistat;String[] llista;@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);seleccio=(TextView)findViewById(R.id.textv);llistat=(ListView)findViewById(R.id.listView1);//Crea llista fitxersFile lfile=new File("/sdcard");//File lfile=new File(Environment.getExternalStorageDirectory().getPath());File[] list=lfile.listFiles();llista=new String[lfile.listFiles().length];seleccio.setText(String.valueOf(lfile.listFiles().length));for (int i=0;i<lfile.listFiles().length;i++) {

if (list[i].isHidden()) llista[i]="Fitxer ocult:"+list[i].getAbsolutePath().toString();if (list[i].isDirectory()) llista[i]="Carpeta: "+list[i].getAbsolutePath().toString();if (list[i].isFile()) llista[i]="Fitxer: "+list[i].getAbsolutePath().toString();

};

//Mostra llista fitxers i selecionallistat.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

………… segueix …………

En aquest exemple llistarem els fitxers de la carpeta /sdcard, crearem un Array amb el camí complertdels diferents fitxers, i els mostrarem en un listView. Ens pot servir, per exemple, com a base d’unprograma que ens permeti sel·leccionar un fitxer de música i reproduir-ho.

Page 134: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Llistat i selecció de Fitxers

......... Ve d’abans ......................

if (list[i].isFile()) llista[i]="Fitxer: "+list[i].getAbsolutePath().toString();};

//Mostra llista fitxers i selecionallistat.setChoiceMode(ListView.CHOICE_MODE_SINGLE);llistat.setAdapter(new ArrayAdapter(this,android.R.layout.simple_list_item_single_choice,llista));llistat.setOnItemClickListener(new OnItemClickListener(){

@Overridepublic void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {

seleccio.setText("Has seleccionat: "+llista[arg2]+" pos:"+arg2);}});

}}

En aquest exemple llistarem els fitxers de la carpeta /sdcard, crearem un Array amb el camí complertdels diferents fitxers, i els mostrarem en un listView. Ens pot servir, per exemple, com a base d’unprograma que ens permeti sel·leccionar un fitxer de música i reproduir-ho.

Page 135: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

Detectar pulsació de teclespublic class MainActivity extends Activity {TextView texte;

@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);texte = (TextView) findViewById (R.id.textv);

}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {

switch (keyCode) {case KeyEvent.KEYCODE_DPAD_CENTER:{

texte.setText("Has polsat el Dpad centre");return true;

}case KeyEvent.KEYCODE_VOLUME_UP:{

texte.setText("Has polsat pujar volum");return true;

} case KeyEvent.KEYCODE_VOLUME_DOWN:{

texte.setText("Has polsat baixar volum");return true;

}case KeyEvent.KEYCODE_DPAD_DOWN:{

texte.setText("Has polsat Dpad abaix");return true;

} }return super.onKeyDown(keyCode, event);

}}

Podem detectar que s’ha polsat una tecla del dispositiu com poden ser les tecles de volum, amb elmètode onKeyDown() i l’objecte KeyEvent.

Page 136: Android - OpenCourseWareocw.upc.edu/sites/ocw.upc.edu/files/materials/340622/2012/1/54409/... · Les activitats es creen com a subclasses de la classe Activity: ... nom i els dos

• http://www.androidcurso.com/• http://www.sgoliver.net• http://yoandroido.blogspot.com.es/• http://www.javaya.com.ar/androidya/index.p

hp?inicio=• http://elbauldelprogramador.com/curso-

programacion-android/• http://www.androidadb.com