Android - Parte 7

274 visualizações

Publicada em

Parte 7 de um grupo de materiais elaborados pelo Prof. Manuel Fernández Paradela Ledón para as aulas de Programação para Dispositivos Móveis (programação na plataforma Android).

Publicada em: Tecnologia
0 comentários
0 gostaram
Estatísticas
Notas
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

Sem downloads
Visualizações
Visualizações totais
274
No SlideShare
0
A partir de incorporações
0
Número de incorporações
41
Ações
Compartilhamentos
0
Downloads
6
Comentários
0
Gostaram
0
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

Android - Parte 7

  1. 1. Android Programação para Dispositivos Móveis Parte 7 – Gráficos e outros recursos Prof. Manuel F. Paradela Ledón, 2011. Universidade Cruzeiro do Sul
  2. 2. Gráficos e outros recursos Neste material introduziremos, com exemplos, a utilização de alguns recursos interessantes do Android.  Elaborar gráficos, desenhar, mostrar figuras. Uma tela de um programa Android poderá mostrar simultaneamente textos, figuras, botões, desenhos etc. (também, poderíamos utilizar uma tela gráfica única). Por exemplo, uma tela poderia ter dois botões para ações, duas caixas para entrada de texto e uma área para mostrar um gráfico.  Sensores. Talvez uma das características que diferenciam PCs e notebooks tradicionais de um smartphone atual seja a utilização de sensores (de orientação, de giro, de aceleração, temperatura, luz, humidade etc.). Programas Android que utilizem estes recursos poderão ser mais interativos e motivadores.  Outras mídias. Android permite mostrar vídeos ou tocar sons. Efeitos sonoros e músicas de fundo são também elementos importantes.
  3. 3. Telas gráficas. Desenhar e mostrar figuras.
  4. 4. Exemplo 1  Neste primeiro exemplo mostramos um programa com uma única tela gráfica (classe derivada de View).  Como não existirão outros elementos na tela, não precisaremos utilizar um arquivo .xml de layout.  Não carregaremos figuras prontas, apenas desenharemos na tela.  Atenderemos os eventos onClick e onLongClick.
  5. 5. A classe ActGraficos, derivada de Activity package com.testegraficosimples; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.*; public class ActGraficos extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final MinhaView mv = new MinhaView(this); //classe derivada de View setContentView(mv); mv.setOnClickListener (new View.OnClickListener() { public void onClick(View v) { Toast.makeText(ActGraficos.this, "nLegal! Evento click normal atendido...n", Toast.LENGTH_LONG).show(); mv.setTipoPaint(1); } }); } } Observe que o visual estará definido por uma View (ver nos próximos slides).
  6. 6. A classe MinhaView, derivada de View - parte 1 package com.testegraficosimples; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.drawable.shapes.OvalShape; import android.graphics.drawable.shapes.RectShape; import android.view.View; import android.widget.Toast; class MinhaView extends View { private int tipopaint=1; public MinhaView(Context cx) { super(cx); final Context viewContext = cx; setOnLongClickListener (new View.OnLongClickListener() { public boolean onLongClick(View v) { Toast.makeText(viewContext, "nnVamos limpar a tela, sem pintar nada.nn", Toast.LENGTH_LONG).show(); setTipoPaint(2); return true; } }); } public void setTipoPaint(int i) { tipopaint = i; invalidate(); //Importante: este método invalida a tela e provoca uma chamada ao método onDraw }
  7. 7. Alguns métodos da classe Canvas (“tela para pintar”) Fonte: Classe Canvas (em: http://developer.android.com/reference/android/graphics/Canvas.html) int getHeight() Returns the height of the current drawing layer int getWidth() Returns the width of the current drawing layer void drawRect(float left, float top, float right, float bottom, Paint paint) Draw the specified Rect using the specified paint. void drawText(String text, float x, float y, Paint paint) Draw the text, with origin at (x,y), using the specified paint. void drawPicture(Picture picture, Rect dst) Draw the picture, stretched to fit into the dst rectangle. void drawPoint(float x, float y, Paint paint) Helper for drawPoints() for drawing a single point. void drawPoints(float[] pts, int offset, int count, Paint paint) Draw a series of points. void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) Draw a line segment with the specified start and stop x,y coordinates, using the specified paint. void drawLines(float[] pts, Paint paint) void drawCircle(float cx, float cy, float radius, Paint paint) Draw the specified circle using the specified paint. void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint) Draw the specified arc, which will be scaled to fit inside the specified oval.
  8. 8. A classe MinhaView, derivada de View - parte 2 @Override protected void onDraw(Canvas c) { Paint p = new Paint(); p.setAntiAlias(true); //para suavizar as bordas (não o interior) do que será pintado switch (tipopaint) { case 1: //Pintamos uma figura em forma de retângulo ShapeDrawable fig1 = new ShapeDrawable(new RectShape()); fig1.getPaint().setColor(0xFFFFFF00); //retângulo amarelo //Obs.: setBounds(int left, int top, int right, int bottom) //setColor: os primeiros dois números são o componente //alpha (a opacidade). FF será 100% opaco. Resumindo: 0xAARRGGBB fig1.setBounds(0,0,35,70); fig1.draw(c); p.setColor(0xFFFFFFFF); //retângulo branco c.drawRect(35,75,c.getWidth()-30, c.getHeight()-110,p); p.setColor(0xFF0000FF); //círculo azul c.drawCircle(c.getWidth()/2, c.getHeight()/2, c.getHeight()/4, p); p.setColor(0xFF00FF00); //círculo verde c.drawCircle(c.getWidth()/2, c.getHeight()/2, c.getHeight()/8, p); p.setColor(0xFFFFFFFF); //linha branca c.drawLine(0,0, getWidth()()/2, c.getHeight()/2,p);
  9. 9. A classe MinhaView, derivada de View - parte 3 //Pintamos uma figura em forma de oval OvalShape ov; ov = new OvalShape(); ShapeDrawable fig2 = new ShapeDrawable(ov); //Ou resumindo seria: ShapeDrawable fig2 = new ShapeDrawable(new OvalShape()); fig2.getPaint().setColor(0x88FF0000); //certa transparência com 88 fig2.setBounds(10,10,getWidth()/2,getHeight()/2 + 20); //getWidth() e getHeight() são valores relativos à área da View gráfica fig2.draw(c); p.setColor(0xFFFFFFFF); //para textos brancos c.drawText("Observe a transparência do oval vermelho.", 2, getHeight()-25, p); c.drawText("Experimente touch e touch longo na tela.", 2, getHeight()-10, p); break; case 2: c.drawText("Experimente agora touch simples na tela.", 2, getHeight()-10, p); break; //não pintamos nada neste caso }//switch }//método onDraw }//classe MinhaView
  10. 10. Exemplo 2  Neste segundo exemplo mostramos um programa Android com uma tela com diferentes elementos, incluindo um objeto de uma classe derivada de View (veja na parte superior da figura).  Utilizaremos um arquivo main.xml para definir este layout.  Observe que na tela temos dois objetos TextView, dois Button, um EditText e uma View.  Atenderemos os eventos onClick e onLongClick.
  11. 11. O layout da tela no arquivo main.xml 1/2 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center_horizontal" > <exemplos.exemplograficos2.MinhaView android:id="@+id/minha_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin ="3dp" android:layout_weight="5" /> peso => quanto espaço ocupará esta view na tela <TextView android:id="@+id/digite_text" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="Digite um valor de 1 a 5:" /> <EditText android:id="@+id/edita_text" android:layout_width="58dp" android:layout_height="40dp" android:gravity="center_horizontal" android:inputType="number" android:textSize="16sp" />
  12. 12. O layout da tela no arquivo main.xml 2/2 <Button android:id="@+id/graf_botao" android:layout_width="115dp" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:text="Gráfico" /> <TextView android:id="@+id/info_text" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="Experimente click e click longo nna área do gráfico..." /> <Button android:id="@+id/outro_botao" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:text="Outro botão" /> </LinearLayout>
  13. 13. A classe ActGraficos (extends Activity) - parte 1 package com.testegraficos; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.*; public class ActGraficos extends Activity { private MinhaView mView; private EditText editatipo; private Button botao,outrobotao; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); try { setContentView(R.layout.main); mView = (MinhaView) findViewById(R.id.minha_view); mView.setFocusable(true); //para que a View receba o foco em modo touch editatipo = (EditText) findViewById(R.id.edita_text); grafbotao = (Button) findViewById(R.id.graf_botao); outrobotao = (Button) findViewById(R.id.outro_botao); } catch(Exception e){ Toast.makeText(ActGraficos.this, "nErro.n" + e.getMessage() + "n" , Toast.LENGTH_LONG).show(); }
  14. 14. A classe ActGraficos (extends Activity) - parte 2 ... grafbotao.setOnClickListener (new View.OnClickListener() { public void onClick(View v) { int tipo = 1; try { tipo = Integer.parseInt(editatipo.getText().toString()); } catch(Exception ew1){} mView.setTipoPaint(tipo); mView.invalidate(); } }); outrobotao.setOnClickListener (new View.OnClickListener() { public void onClick(View v) { Toast.makeText(ActGraficos.this, "nLegal! Evento click normal atendido...n", Toast.LENGTH_LONG).show(); } }); } }
  15. 15. A classe MinhaView (extends View) - parte 1 package com.testegraficos; import android.content.Context; class MinhaView extends View { private int tipopaint=3; public MinhaView(Context cx, AttributeSet attrs) { super(cx, attrs); requestFocus(); final Context viewContext = cx; setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Toast.makeText(viewContext, "nnVamos invalidar a tela, estado inicial.nn", Toast.LENGTH_LONG).show(); tipopaint = 1; invalidate(); } }); setOnLongClickListener (new View.OnLongClickListener() { public boolean onLongClick(View v) { Toast.makeText(viewContext, "nnVamos limpar a tela, sem pintar nada.nn", Toast.LENGTH_LONG).show(); tipopaint = 2; invalidate(); return true; } }); }
  16. 16. A classe MinhaView (extends View) - parte 2 public void setTipoPaintv02(int i) { tipopaint=i; } @Override protected void onDraw(Canvas c) { Paint p = new Paint(); p.setAntiAlias(true); //para suavizar as bordas switch (tipopaint) { case 1: ShapeDrawable fig1 = new ShapeDrawable(new RectShape()); fig1.getPaint().setColor(0xFFDDFF00); //Obs.: setBounds(int left, int top, int right, int bottom) fig1.setBounds(0,0,30,50); OvalShape ov; ov = new OvalShape(); ShapeDrawable fig2 = new ShapeDrawable(ov); fig2.getPaint().setColor(0x44DD44FF); //Obs.: getWidth() e getHeight() são valores relativos à área da View gráfica fig2.setBounds(0,60,getWidth(),getHeight()); fig1.draw(c); fig2.draw(c); break;
  17. 17. A classe MinhaView (extends View) - parte 3 case 2: p.setColor(0xFFCCCCCC); //cinza c.drawRect(3,3,getWidth()-6, getWidth(), p); p.setColor(0xFF0000FF); //azul c.drawCircle(getWidth()/2, getHeight()/2, getWidth()/2.6f-getWidth()/10, p); p.setColor(0xFFFF0000); //vermelho c.drawCircle(getWidth()/2, getHeight()/2, getWidth()/2.6f-getWidth()/8, p); p.setColor(0xFF00FF00); //verde c.drawCircle(getWidth()/2, getHeight()/2, getWidth()/2.6f-getWidth()/6, p); p.setColor(0xFFFFFF00); //amarelo c.drawCircle(getWidth()/2, getHeight()/2, getWidth()/2.6f-getWidth()/4, p); break; case 3: ... break; case 4: ... break; case 5: ... break; } //switch } }
  18. 18. Exemplo 3  Neste terceiro exemplo mostramos um programa com dois elementos na tela: um objeto de uma classe derivada de View e um TextView (texto na parte superior da tela).  Utilizaremos um arquivo main.xml para definir este layout.  Neste programa quase não desenharemos, porque utilizaremos figuras prontas em arquivos .png.  Atenderemos os eventos onKeyDown e onTouchEvent, para permitir o movimento do avião como resposta à ação do usuário.
  19. 19. O layout da tela no arquivo main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Viajando en avión por el mundo..." android:height="40px" android:gravity="center" /> <com.pckaviao.AviaoView android:id="@+id/idaviao" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> A classe AviaoView é derivada de View, para trabalhar em modo gráfico.
  20. 20. Os arquivos utilizados neste exemplo
  21. 21. A classe Aviao (extends Activity) package com.pckaviao; import android.app.Activity; import android.os.Bundle; public class Aviao extends Activity { @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.main); } } Observe que esta classe só define o layout da tela (descrito em main.xml).
  22. 22. A classe AviaoView (extends View) - Construtor package com.pckaviao; +import android.content.Context; public class AviaoView extends View { private Drawable imgAviao; private Drawable bandeira; private float x, y, xband, yband; //x,y:centro do avião; xband,yband: pos. da bandeira private int passo = 20; private int larg, alt, largband, altband; //larg,alt do avião; larband,altband da band. private boolean pressionado = false; private Context ctx; public AviaoView(Context context, AttributeSet atts) { super(context, atts); ctx = context; // Colocamos a imagem de fundo da view: setBackgroundResource(R.drawable.mundo); // Pegamos uma referência à imagem do avião e de uma bandeira: imgAviao = context.getResources().getDrawable(R.drawable.aviao); bandeira = context.getResources().getDrawable(R.drawable.italia); // Recuperamos a largura e altura das imagens (avião e bandeiras): larg = imgAviao.getIntrinsicWidth(); alt = imgAviao.getIntrinsicHeight(); largband = bandeira.getIntrinsicWidth(); altband = bandeira.getIntrinsicHeight(); x = 15; y = 120; xband = -100; yband = -100; //posição inicial // Permitimos que esta View receba o foco e trate eventos de teclado: setFocusable(true); }
  23. 23. A classe AviaoView - O método onDraw (ver a lógica no próximo slide!) public void onDraw(Canvas canvas) { super.onDraw(canvas); Paint p = new Paint(); canvas.drawCircle(xband, yband, 8, p); p.setColor(0xFF00FF00); //usar p.setStyle(Style.STROKE); para apenas pintar a borda canvas.drawCircle(xband, yband, 10, p); //círculo verde if(Math.abs(xband/this.getWidth()-0.366)<=0.09 && Math.abs(yband/this.getHeight()-0.861)<=0.09) { //Brasil bandeira = getResources().getDrawable(R.drawable.brasil); } if(Math.abs(xband/this.getWidth()-0.742)<=0.03 && Math.abs(yband/this.getHeight()-0.414)<=0.03) { //Itália bandeira = getResources().getDrawable(R.drawable.italia); } if(Math.abs(xband/this.getWidth()-0.1598)<=0.03 && Math.abs(yband/this.getHeight()-0.506)<=0.03) { //Cuba bandeira = getResources().getDrawable(R.drawable.cuba); } if(Math.abs(xband/this.getWidth()-0.667)<=0.03 && Math.abs(yband/this.getHeight()-0.434)<=0.03) { //Espanha bandeira = getResources().getDrawable(R.drawable.espana); } if(Math.abs(xband/this.getWidth()-0.188)<=0.09 && Math.abs(yband/this.getHeight()-0.406)<=0.09) { //USA bandeira = getResources().getDrawable(R.drawable.usa); } //colocamos a bandeira na posição xband,yband e o avião na posição x,y: bandeira.setBounds((int)(xband + largband/2), (int)(yband-altband),(int)(xband + largband + largband/2), (int)yband); bandeira.draw(canvas); imgAviao.setBounds((int)x, (int)(y - alt), (int)(x + larg), (int)y ); imgAviao.draw(canvas); }
  24. 24. Identificando coordenadas (pontos) na tela, independente da resolução do aparelho @Override public boolean onTouchEvent(MotionEvent event) { // Para mover o avião por operação de tipo drag and drop float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Toast.makeText(ctx, "x/this.getWidth(): " + x/this.getWidth() + ", y/this.getHeight(): " + y/this.getHeight() + "nnn", Toast.LENGTH_LONG).show(); ... Por exemplo, se as coordenadas, divididas pela largura ou altura da tela, ao clicar no centro aproximado do Brasil são 0.366 e 0.861 (sendo 0.09 uma folga com relação a esses pontos), então no método onDraw: if(Math.abs(xband/this.getWidth()- 0.366)<= 0.09 && Math.abs(yband/this.getHeight()- 0.861)<= 0.09) { //pintar a bandeira do Brasil }
  25. 25. A classe AviaoView - O método onKeyDown @Override public boolean onKeyDown(int codigoTecla, KeyEvent evento) { //Para mover o avião por teclas de cursor, caso exista um teclado físico ou virtual boolean repintar = true; switch (codigoTecla) { case KeyEvent.KEYCODE_DPAD_UP: y -= passo; break; case KeyEvent.KEYCODE_DPAD_DOWN: y += passo; break; case KeyEvent.KEYCODE_DPAD_LEFT: x -= passo; break; case KeyEvent.KEYCODE_DPAD_RIGHT: x += passo; break; default: repintar = false; } if (repintar) { invalidate(); return true; } return super.onKeyDown(codigoTecla, evento); }
  26. 26. A classe AviaoView - O método onTouchEvent– Parte 1 @Override public boolean onTouchEvent(MotionEvent event) { // Para mover o avião por operação de tipo drag and drop float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // Inicia o movimento se pressionou a imagem: pressionado = imgAviao.copyBounds().contains((int) x, (int) y); /* Para identificar pontos no mapa, saber suas posições relativas, independente das resoluções e tamanhos de telas dos diferentes aparelhos: Toast.makeText(ctx, "x/this.getWidth(): " + x/this.getWidth() + ", y/this.getHeight(): " + y/this.getHeight() + "nnn", Toast.LENGTH_LONG).show(); */ break;
  27. 27. A classe AviaoView - O método onTouchEvent – Parte 2 case MotionEvent.ACTION_MOVE: // Arrastamos o avião: if (pressionado) { this.x = (int) x - (larg / 2); this.y = (int) y - (alt / 4); this.xband = (int) x - largband/2; this.yband = (int) y - 2*altband; } break; case MotionEvent.ACTION_UP: // Terminamos o movimento: if(pressionado) { Context ctx = getContext(); AudioManager som = (AudioManager)ctx.getSystemService(Context.AUDIO_SERVICE); som.playSoundEffect(SoundEffectConstants.CLICK); } pressionado = false; break; } invalidate(); //lembre que chamar este método provocará executar onDraw return true; } }
  28. 28. Sensores em Android Constants int TYPE_ACCELEROMETER A constant describing an accelerometer sensor type. int TYPE_ALL A constant describing all sensor types. int TYPE_GRAVITY A constant describing a gravity sensor type. int TYPE_GYROSCOPE A constant describing a gyroscope sensor type int TYPE_LIGHT A constant describing an light sensor type. int TYPE_LINEAR_ACCELERATION A constant describing a linear acceleration sensor type. int TYPE_MAGNETIC_FIELD A constant describing a magnetic field sensor type. int TYPE_ORIENTATION This constant is deprecated. use SensorManager.getOrientation() instead. int TYPE_PRESSURE A constant describing a pressure sensor type int TYPE_PROXIMITY A constant describing an proximity sensor type. int TYPE_ROTATION_VECTOR A constant describing a rotation vector sensor type. int TYPE_TEMPERATURE A constant describing a temperature sensor type Fonte: Classe Sensor (em http://developer.android.com/reference/android/hardware/Sensor.html) http://developer.android.com/reference/android/hardware/SensorEvent.html#values Obs.: Consulte com o fabricante do aparelho os sensores disponíveis.
  29. 29. Exemplo 4 Obs.: o simulador não permite testar sensores...  Neste quarto exemplo mostramos um programa com um elemento na tela: um objeto da classe ImageView.  Utilizaremos um arquivo main.xml para definir este layout.  Neste programa não desenharemos, porque utilizaremos figuras prontas em arquivos .png. Também, utilizaremos sons preparados em arquivos .wav.  Atenderemos os eventos onResume, onPause e onSensorChanged, para trocar a figura e tocar um som como resposta à inclinação do aparelho.
  30. 30. O layout da tela no arquivo main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:id="@+id/foto1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" /> </LinearLayout>
  31. 31. Os arquivos utilizados neste exemplo Sugestão: Consulte os detalhes da classe MediaPlayer em http://developer.android.com/reference/android/media/MediaPlayer.html e os tipos de mídia permitidos por Android em: http://developer.android.com/guide/appendix/media-formats.html.
  32. 32. A classe SensoresPerro (extends Activity) - Parte 1 package com.pcksensoresperro; import android.app.Activity; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.media.MediaPlayer; import android.os.Bundle; import android.widget.ImageView; import android.widget.Toast; public class SensoresPerro extends Activity implements SensorEventListener { private SensorManager sensorManager; //manipulador de sensores private Sensor sensor1,sensor2,sensor3; //sensores private float magnetic_values[] = null, accelerometer_values [] = null; private boolean deitado=false,empe=false; private MediaPlayer late=null, dorme = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); try { late = MediaPlayer.create(this, R.raw.latindo); dorme = MediaPlayer.create(this, R.raw.dormindo); } catch (Exception e) { Toast.makeText(SensoresPerro.this, "nErro:n" + e.getMessage() + "n", Toast.LENGTH_LONG).show(); } // Para manipular os sensores: sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); sensor1 = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); sensor2 = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); sensor3 = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); } Dois objetos da classe MediaPlayer (late e dorme) são criados, utilizando os arquivos de áudio latindo.wav e dormindo.wav, que se encontram na pasta raw. Foram preparados sensores de orientação, de acelerómetro e de campo magnético.
  33. 33. A classe SensoresPerro (extends Activity) - Parte 2 // Ativamos a atualização dos sensores quando a Activity é retomada @Override protected void onResume() { super.onResume(); sensorManager.registerListener(this , sensor1, SensorManager.SENSOR_DELAY_NORMAL); sensorManager.registerListener(this , sensor2, SensorManager.SENSOR_DELAY_NORMAL); sensorManager.registerListener(this , sensor3, SensorManager.SENSOR_DELAY_NORMAL); } // Paramos a atualização dos sensores quando a Activity fique em pausa @Override protected void onPause() { super.onPause(); sensorManager.unregisterListener(this, sensor1); sensorManager.unregisterListener(this, sensor2); sensorManager.unregisterListener(this, sensor3); } public void onAccuracyChanged(Sensor sensor, int accuracy) { }
  34. 34. A classe SensoresPerro (extends Activity) - Parte 3 @Override public void onSensorChanged(SensorEvent event) { switch (event.sensor.getType()) { case Sensor.TYPE_MAGNETIC_FIELD: this.magnetic_values = event.values.clone(); //preencher vetor break; case Sensor.TYPE_ACCELEROMETER: this.accelerometer_values = event.values.clone(); //preencher vetor break; case Sensor.TYPE_ORIENTATION: if (this.magnitude_values != null && this.accelerometer_values != null) { float[] Rm = new float[9]; float[] In = new float[9]; SensorManager.getRotationMatrix(Rm, In, this.accelerometer_values, this.magnetic_values); //gera Rm float[] actual_orientation = new float[3]; SensorManager.getOrientation(Rm, actual_orientation); //gera actual_orientation //actual_orientation[0]: azimuth, rotation around the Z axis. //actual_orientation[1]: // pitch, rotation around the X axis  posição “vertical” //actual_orientation[2]: roll, rotation around the Y axis. Obs.: o método getRotationMatrix necessita dos valores dos vetores do acelerómetro e do sensor magnético para gerar a matriz de rotação. O método getOrientation necessita a matriz de rotação para poder gerar os valores do vetor de orientação.
  35. 35. Sistema de coordenadas utilizado Fonte: http://developer.android.com/reference/android/hardware/SensorManager.html
  36. 36. A classe SensoresPerro (extends Activity) - Parte 4 Continuação do evento onSensorChanged e do caso case Sensor.TYPE_ORIENTATION: ImageView foto1 = (ImageView) findViewById(R.id.foto1); if( Math.abs(Math.abs(actual_orientation[1])-1.57)<=0.35 || Math.abs(Math.abs(actual_orientation[2])-1.57)<=0.40 ) { foto1.setImageResource(R.drawable.dog1); if(!empe) { empe = true; deitado = false; try{ late.start(); } catch (Exception e) {} } } else { foto1.setImageResource(R.drawable.dog2); if(!deitado) { deitado = true; empe = false; try{ dorme.start(); } catch (Exception e) {} } } } //fim do if (this.magnitude_values != null && this.accelerometer_values != null) break; }//switch } //método onSensorChanged } // classe SensoresPerro Comparamos com π/2 (1.57, que são 90º). Se estiver próximo do ângulo 1.57, então o cachorro deverá ser mostrado em pé, figura dog1.png. Caso contrário, mostraremos o cachorro deitado, figura dog2.png. Um som específico será tocado em cada caso, com o método start().
  37. 37. Exemplo 5 - Rotação de figuras  Neste quinto exemplo modificamos o Exemplo 4. Agora sem áudio, o cachorro dará voltas na tela com a ativação dos sensores de orientação.  Utilizaremos um arquivo main.xml para definir este layout.  Neste programa não desenharemos, porque utilizaremos figuras prontas em arquivos .png.  Atenderemos os eventos onResume, onPause e onSensorChanged.
  38. 38. O método onSensorChanged modificado @Override public void onSensorChanged(SensorEvent event) { switch (event.sensor.getType()) { case Sensor.TYPE_MAGNETIC_FIELD: this.magnitude_values = event.values.clone(); break; case Sensor.TYPE_ACCELEROMETER: this.accelerometer_values = event.values.clone(); break; case Sensor.TYPE_ORIENTATION: if (this.magnitude_values != null && this.accelerometer_values != null) { ... //aqui os comandos para obter a matriz de rotação etc., igual que no método anterior if( Math.abs(Math.abs(actual_orientation[1])-1.57)<=0.35 || Math.abs(Math.abs(actual_orientation[2])-1.57)<=0.40 ) { if(!empe) { empe = true; //empe e deitado são variáveis globais deitado = false; } } else { if(!deitado) { deitado = true; empe = false; } } } rodarCachorro(); break; //fim do case Sensor.TYPE_ORIENTATION: }//switch }
  39. 39. O método rodarCachorro public void rodarCachorro () { Bitmap bitmap = null; ImageView foto1 = (ImageView) findViewById(R.id.foto1); //Criamos um bitmap utilizando a figura em dog1.png ou dog2.png: if (empe) //se o cachoro estiver em pé: bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.dog1); else //se o cachoro estiver durmindo: bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.dog2); int largura = bitmap.getWidth(); int altura = bitmap.getHeight(); int novaLargura = 150; int novaAltura = 150; //Calculamos a escala: float escalaLargura = ((float) novaLargura) / largura; float escalaAltura = ((float) novaAltura) / altura; //Criamos uma matriz de transformação para manipulação da figura, //com a escala e o ângulo de rotação (em graus) desejados: Matrix matrix = new Matrix(); matrix.postScale(escalaLargura, escalaAltura); //redimensionará a figura angulo += 10; //incremento de 10º no ângulo do cachorro que será mostrado (variável global) matrix.postRotate(angulo); //para rotar a figura //Criamos um novoBitmap usando o bitmap inicial e a matriz de transformação antes preparada: Bitmap novoBitmap = Bitmap.createBitmap(bitmap, 0, 0, largura, altura, matrix, true); //Finalmente, criamos um bitmap "desenhável", que será utilizado para alterar a imagem na tela: BitmapDrawable bitmapPintavel = new BitmapDrawable(novoBitmap); foto1.setImageDrawable(bitmapPintavel); }
  40. 40. Aplicativos para testes de sensores Para verificar os sensores do seu aparelho você poderá instalar, por exemplo, o app Android Sensor Box, Sensors ou AndroSensor, todos disponíveis gratuitamente na Google Play (fonte: https://play.google.com/store/apps).
  41. 41. Mostrando um vídeo com a classe VideoView A seguir um exemplo muito simples, uma Activity que demonstra como utilizar a classe VideoView para mostrar um vídeo m.3gp, armazenado no cartão de memória, na pasta dcim. import android.widget.MediaController; import android.widget.VideoView; ... public class ExemploVideoView extends Activity { @Override public void onCreate(Bundle b) { super.onCreate(b); VideoView v = new VideoView(this); setContentView(v); v.setVideoPath("/sdcard/dcim/m.3gp"); v.setMediaController(new MediaController(this)); v.requestFocus(); } }
  42. 42. Bibliografia sugerida Bibliografia sugerida sobre Android ANDROID. Android Developers. Disponível em http://developer.android.com. LECHETA, RICARDO R. Google Android, Aprenda a criar aplicações para dispositivos móveis com o Android SDK. São Paulo: Novatec, 2010. MEDNIEKS, Z. et. al. Desenvolvimento de Aplicações Android. São Paulo: Novatec, 2009.

×