Aplicaciones moviles clase10 multimedia

29
IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA APLICACIONES MÓVILES 1 MULTIMEDIA EN ANDROID 1. UTILIZANDO MULTIMEDIA EN ANDROID (1) La integración de contenido multimedia en nuestras aplicaciones resulta muy sencilla gracias a la gran variedad de facilidades que nos proporciona el API. Concretamente podemos reproducir audio y vídeo desde orígenes distintos: Desde un fichero almacenado en el dispositivo. Desde un recurso que está incrustado en el paquete de la aplicación (fichero .apk). Desde un stream que es leído desde una conexión de red. En este punto admite dos posibles protocolos (http:// y rstp://) También resulta sencilla la grabación de audio y vídeo, siempre que el hardware del dispositivo lo permita. En la siguiente lista se muestran las clases de Android que nos permitirán acceder a los servicios Multimedia: MediaPayer: Reproducción de audio/vídeo desde ficheros o streams. MediaControler: Visualiza controles estándar para mediaPlayer (pausa, stop). VideoView: Vista que permite la reproducción de vídeo. MediaRecorder: Permite grabar audio y vídeo. AsyncPlayer: Reproduce lista de audios desde un thread secundario. AudioManager: Gestiona varias propiedades del sistema (volumen, tonos…). AudioTrack: Reproduce un búfer de audio PCM directamente por hardware. SoundPool: Maneja y reproduce una colección de recursos de audio. JetPlayer: Reprocuce audio y video interactivo creado con JetCreator. Camera: Cómo utilizar la cámara para tomar fotos y video. FaceDetector: Identifica la cara de la gente en un bitmap. La plataforma Android soporta una gran variedad de formatos, muchos de los cuales pueden ser tanto decodificados como codificados. A continuación, mostramos una tabla con los formatos multimedia soportados. No obstante algunos modelos de móviles pueden soportar formatos adicionales que no se incluyen en la tabla, como por ejemplo DivX. Cada desarrollador es libre de usar los formatos incluidos en el núcleo del sistema o aquellos que solo se incluyen en algunos dispositivos. Tipo Formato Codifica Decodifica Detalles fichero soportado Audio AAC LC/LTP X X Mono/estéreo con cualquier combinación estándar de frecuencia > 160 Kbps y ratios de muestreo de 8 a 48kHz 3GPP (.3gp) MPEG-4(.mp4) No soporta raw AAC (.aac) MPEG-TS (.ts) HE-AACv1 a partir 4.1 X HE-AACv2 X AAC ELD a partir 4.1 a partir 4.1 Mono/estéreo, 16-8kHz AMR-NB X X 4.75 a 12.2 Kbps muestreada a @ 8kHz 3GPP (.3gp) AM R-WB X X 9 ratios de 6.60 Kbps a 23.85 Kbps a @ 16kHz 3GPP (.3gp)

Transcript of Aplicaciones moviles clase10 multimedia

Page 1: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 1

MULTIMEDIA EN ANDROID

1. UTILIZANDO MULTIMEDIA EN ANDROID(1)

La integración de contenido multimedia en nuestras aplicaciones resulta muy sencilla gracias a la gran variedad de

facilidades que nos proporciona el API.

Concretamente podemos reproducir audio y vídeo desde orígenes distintos:

Desde un fichero almacenado en el dispositivo.

Desde un recurso que está incrustado en el paquete de la aplicación (fichero .apk).

Desde un stream que es leído desde una conexión de red. En este punto admite dos posibles protocolos

(http:// y rstp://)

También resulta sencilla la grabación de audio y v ídeo, siempre que el hardware del dispositivo lo

permita.

En la siguiente lista se muestran las clases de Android que nos permitirán acceder a los serv icios

Multimedia:

MediaPayer: Reproducción de audio/v ídeo desde ficheros o streams.

MediaControler: Visualiza controles estándar para mediaPlayer (pausa, stop).

VideoView: Vista que permite la reproducción de v ídeo.

MediaRecorder: Permite grabar audio y v ídeo.

AsyncPlayer: Reproduce lista de audios desde un thread secundario.

AudioManager: Gestiona varias propiedades del sistema (volumen, tonos…).

AudioTrack: Reproduce un búfer de audio PCM directamente por hardware.

SoundPool: Maneja y reproduce una colección de recursos de audio.

JetPlayer: Reprocuce audio y v ideo interactivo creado con JetCreator.

Camera: Cómo utilizar la cámara para tomar fotos y v ideo.

FaceDetector: Identifica la cara de la gente en un bitmap.

La plataforma Android soporta una gran variedad de formatos, muchos de los cuales pueden

ser tanto decodificados como codificados. A continuación, mostramos una tabla con los

formatos multimedia soportados. No obstante algunos modelos de móviles pueden soportar

formatos adicionales que no se incluyen en la tabla, como por ejemplo DivX.

Cada desarrollador es libre de usar los formatos incluidos en el núcleo del sistema o aquellos que

solo se incluyen en algunos dispositivos.

Tipo Formato Codifica Decodifica Detalles fichero soportado

Audio

AAC

LC/LTP X X

Mono/estéreo con cualquier combinación

estándar de frecuencia > 160 Kbps y ratios de

muestreo de 8 a 48kHz

3GPP (.3gp)

MPEG-4(.mp4)

No soporta raw AAC

(.aac)

MPEG-TS (.ts)

HE-AACv1 a partir 4.1 X

HE-AACv2 X

AAC ELD a partir 4.1 a partir 4.1 Mono/estéreo,

16-8kHz

AMR-NB X X 4.75 a 12.2 Kbps muestreada a @ 8kHz 3GPP (.3gp)

AMR-WB X X 9 ratios de 6.60 Kbps a 23.85 Kbps a @ 16kHz 3GPP (.3gp)

Page 2: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 2

MP3 X Mono/estéreo de 8 a 320 Kbps, bit rate

constante (CBR) o variable (VBR) MP3 (.mp3)

MIDI X

MIDI tipo 0 y 1. DLS v1 y v2. XMF y XMF

móvil. Soporte para tonos de llamada RTTTL /

RTX, OTA y iMelody.

Tipo 0 y 1 (.mid,

.xmf, .mxmf).

RTTTL / RTX

(.rtttl, .rtx),

OTA (.ota)

iMelody (.imy)

Ogg Vorbis X

Ogg (.ogg)

Matroska (.mkv

a partir 4.0)

FLAC a partir 3.1 mono/estereo

(no multicanal)

FLAC (.flac)

PCM/WAVE a partir 4.1 X 8 y 16 bits PCM lineal (frecuencias limitadas

por el hardware) WAVE (.wav)

Imagen

JPEG X X Base + progresivo JPEG (.jpg)

GIF X GIF (.gif)

PNG X X PNG (.png)

BMP X BMP (.bmp)

WEBP a partir 4.0 a partir 4.0 WebP (.webp)

Video

H.263 X X 3GPP (.3gp)

MPEG-4 (.mp4)

H.264 AVC a partir 3.0 X Baseline Profile (BP) 3GPP (.3gp)

MPEG-4 (.mp4)

MPEG-4 SP X 3GPP (.3gp)

WP8 a partir 2.3.3 Streaming a partir 4.0 WebM (.webm)

Matroska (.mkv)

Tabla 5: Formatos multimedia soportados en Android.

Page 3: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 3

2. LA VISTA VIDEOVIEW(1)

La forma más fácil de incluir un vídeo en tu aplicación es incluir una vista de tipo VideoView. Veamos

cómo hacerlo en el siguiente ejercicio

Ejercicio paso a paso: Reproducir un vídeo con VideoView

1. Crea una nueva aplicación.

2. Reemplaza el fichero ref/layout/activity_main.xml por <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <VideoView android:id="@+id/surface_view" android:layout_width="320px"

android:layout_height="240px"/> </LinearLayout>

3. Reemplaza el siguiente código en la clase MainActivity: public class videoView extends Activity { private VideoView mVideoView;

@Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mVideoView =(VideoView)findViewById(R.id.surface_view);

//de forma alternativa si queremos un streaming usar //mVideoView.setVideoURI(Uri.parse(URLstring)); mVideoView.setVideoPath("/mnt/sdcard/video.mp4"); mVideoView.start(); mVideoView.requestFocus(); }

}

En el parámetro del método setVideoPath() estamos indicando un fichero local.

4. Busca un fichero de video en codificación mp4. Renombra este fichero a video.mp4.

5. Es necesario almacenar un fichero de video en el simulador. Para ello, utiliza la opción del

menúWindow > Show View >Others… > Android > File Explorer. Te mostrará el sistema de ficheros del

emulador.

6. Selecciona la carpeta mnt/sdcard y utiliza el botón donde aparece un teléfono con una flecha para

almacenar un nuevo fichero. Indica el fichero video.mp4.

NOTA: el dispositivo ha de disponer de almacenamieno externo.

7. Ejecuta la aplicación y observa el resultado. Recuerda que con Ctrl-F11 puedes cambiar la

orientación. Si no funciona trata de usar otro tipo de emulador.

Page 4: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 4

8. Modifica el fichero xml para que el vídeo aparezca centrado y ocupe toda la pantalla del teléfono,

tal y como se muestra en la imagen de arriba

9. Añade la siguiente línea antes de la llamada al método start();

mVideoView.setMediaController(new MediaController(this));

De esta forma permitimos que el usuario pueda controlar la reproducción del vídeo mediante el

objetoMediaController.

10. Observa el resultado.

NOTA: Algunos emuladores pueden dar problemas a la hora de reprocucir vídeos.

La clase MediaPlayer

La reproducción multimedia en Android se lleva a cabo principalmente por medio de la claseMediaPlayer. Veremos a

continuación las características más importantes de esta clase y cómo podemos sacarle provecho.

Un objeto MediaPlayer va a poder pasar por gran variedad de estados: inicializados sus recursos (initialized),

preparando la reproducción (preparing), preparado para reproducir (prepared), reproduciendo (started), en pausa

(paused), parado (stopped), reproducción completada (playback completed), f inalizado (end) y con error (error). Resulta

importante conocer en qué estado se encuentra dado que muchos de los métodos solo pueden ser llamados desde

ciertos estados. Por ejemplo, no podemos ponerlo en reproducción (método start()) sino está en estado preparado. O

no podremos ponerlo en pausa (pause()), si está parado. Si llamamos a un método no admitido para un determinado

estado se producirá un error de ejecución.

La siguiente tabla permite conocer los métodos que podemos invocar desde cada uno de los estados y cuál es el

nuevo estado al que iremos tras invocarlo. Existen dos tipos de métodos, los que no están subrayados representan

métodos llamados de forma síncrona desde nuestro código, mientras que los que están subrayados representan

métodos llamados de forma asíncrona por el sistema.

Estado

salida

Estado entrada

Idle Initialized Preparing Prepared Started Paused Stopped Playback

Completed

Initialized setDataSource

Preparing prepareAsync prepareAsync

Prepared prepare onPrepared seekTo prepare

Started start seekTo

start start start

Paused pause seekTo

pause

Stopped stop stop stop stop stop

Playback

Completed onCompletion seekTo

End Release release release release release release release release

Error onError onError onError onError onError onError onError onError

Tabla 6: Transiciones entre estados de la clase MediaPlayer

Page 5: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 5

3. REPRODUCCIÓN DE AUDIO CON MEDIAPLAYER(1)

Si el audio o vídeo se va a reproducir siempre en nuestra aplicación resulta interesante incluirlo en el paquete .apk y

tratarlo como un recurso. Este uso ya ha sido ilustrado al comienzo de este capítulo. Recordemos como se hacía:

1. Crea una nueva carpeta con nombre raw dentro de la carpeta res.

2. Arrastra a su interior el fichero de audio. Por ejemplo audio.mp3.

3. Añade las siguientes líneas de código:

MediaPlayer mp = MediaPlayer.create(this, R.raw.audio); mp.start();

Si deseas parar la reproducción tendrás que utilizar el método stop() . Si a continuación quieres volver a reproducirlo

utiliza el método prepare() y a continuación start(). También puedes usar pause() ystart() para ponerlo en pausa y

reanudarlo.

Si en lugar de un recurso prefieres reproducirlo desde un f ichero utiliza el siguiente código. Observa como en este caso

es necesario llamar al método prepare(). En el caso anterior no ha sido necesario dado que esta llamada se hace

desde create().

MediaPlayer mp = new MediaPlayer(); mp.setDataSource(RUTA_AL_FICHERO); mp.prepare(); mp.start();

4. UN REPRODUCTOR MULTIMEDIA PASO A PASO(1)

En el siguiente ejercicio vamos a profundizar en el objeto MediaPlayer por medio de un ejemplo, donde trataremos de

realizar un reproductor de vídeos personalizado.

Ejercicio paso a paso: Un reproductor multimedia pasó a paso

1. Crea una nueva aplicación con los siguientes datos:

Project name: VideoPlayer

Application name: VideoPlayer Package name: org.example.videoplayer Create Activity: VideoPlayer Min SDK Version: 3

2. En la carpeta res/drawable arrastra los cuatro ficheros de

iconos: play.png, pause.png, stop.pngy log.pn.

play.png pause.png stop.png log.png

Page 6: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 6

3. Reemplaza el fichero el fichero res/layout/activity_main.xml por:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="match_parent" android:layout_width="match_parent"> <LinearLayout

android:id="@+id/ButonsLayout" android:layout_height="wrap_content" android:layout_width="match_parent" android:orientation="horizontal" android:layout_alignParentTop="true"> <ImageButton android:id="@+id/play" android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/play"/> <ImageButton android:id="@+id/pause"

android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/pause"/> <ImageButton android:id="@+id/stop" android:layout_height="wrap_content" android:layout_width="wrap_content"

android:src="@drawable/stop"/> <ImageButton android:id="@+id/logButton" android:layout_height="wrap_content" android:layout_width="wrap_content"

android:src="@drawable/log"/> <EditText android:id="@+id/path" android:layout_height="match_parent" android:layout_width="match_parent" android:text="/data/video.3gp"/> </LinearLayout>

<VideoView android:id="@+id/surfaceView" android:layout_height="match_parent" android:layout_width="match_parent" android:layout_below="@+id/ButonsLayout"/>

<ScrollView android:id="@+id/ScrollView" android:layout_height="100px" android:layout_width="match_parent" android:layout_alignParentBottom="true"> <TextView android:id="@+id/Log" android:layout_height="wrap_content"

android:layout_width="match_parent" android:text="Log:"/> </ScrollView> </RelativeLayout>

La apariencia del Layout anterior se muestra a continuación:

Page 7: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 7

4. Reemplaza el código de la clase VideoPlayer por:

public class VideoPlayer extends Activity implements

OnBufferingUpdateListener, OnCompletionListener, MediaPlayer.OnPreparedListener, SurfaceHolder.Callback { private MediaPlayer mediaPlayer; private SurfaceView surfaceView; private SurfaceHolder surfaceHolder; private EditText editText; private ImageButton bPlay, bPause, bStop, bLog; private TextView logTextView; private boolean pause; private String path;

private int savePos = 0; public void onCreate(Bundle bundle) { super.onCreate(bundle); setContentView(R.layout.activity_main); surfaceView = (SurfaceView) findViewById(R.id.surfaceView);

surfaceHolder = surfaceView.getHolder(); surfaceHolder.addCallback(this);

surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); editText = (EditText) findViewById(R.id.path); editText.setText(

"http://personales.gan.upv.es/~jtomas/video.3gp");

No tengo los derechos, pero es un tráiler, creo que no hace falta logTextView = (TextView) findViewById(R.id.Log); bPlay = (ImageButton) findViewById(R.id.play); bPlay.setOnClickListener(new OnClickListener() { public void onClick(View view) { if (mediaPlayer != null) { if (pause) {

mediaPlayer.start(); } else { playVideo(); } } } }); bPause = (ImageButton) findViewById(R.id.pause); bPause.setOnClickListener(new OnClickListener() { public void onClick(View view) {

if (mediaPlayer != null) { pause = true; mediaPlayer.pause(); } } }); bStop = (ImageButton) findViewById(R.id.stop); bStop.setOnClickListener(new OnClickListener() { public void onClick(View view) { if (mediaPlayer != null) {

pause = false; mediaPlayer.stop(); } } }); bLog = (ImageButton) findViewById(R.id.logButton);

bLog.setOnClickListener(new OnClickListener() { public void onClick(View view) { if (logTextView.getVisibility()==TextView.VISIBLE) { logTextView.setVisibility(TextView.INVISIBLE);

} else { logTextView.setVisibility(TextView.VISIBLE); } } }); log("");

}

Como puedes ver la aplicación extiende la clase Activity. Además implementamos cuatro

interfaces que corresponden a varios escuchadores de eventos. Luego continúa la declaración de

variables. Las primeras corresponden a diferentes elementos de la aplicación y su significado

resulta obvio. La variable pause nos indica si el usuario ha pulsado el botón correspondiente, la

Page 8: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 8

variable path nos indica dónde está el vídeo en reproducción y la variable savePos almacena la

posición de reproducción.

5. Añade:

private void playVideo() { try { pause = false; path = editText.getText().toString(); mediaPlayer = new MediaPlayer(); mediaPlayer.setDataSource(path); mediaPlayer.setDisplay(surfaceHolder); mediaPlayer.prepare(); // mMediaPlayer.prepareAsync(); Para streaming mediaPlayer.setOnBufferingUpdateListener(this);

mediaPlayer.setOnCompletionListener(this); mediaPlayer.setOnPreparedListener(this); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.seekTo(savePos); } catch (Exception e) { log("ERROR: " + e.getMessage()); }

}

El código continúa con la definición del método playVideo(). Este método se encarga de obtener la

ruta de reproducción, crear un nuevo objeto MediaPlayer, luego se le asigna la ruta y la superficie

de visualización, a continuación se prepara la reproducción del vídeo. En caso de querer reproducir

un streamdesde la red, esta función puede tardar bastante tiempo, en tal caso es recomendable

utilizar en su lugar el método prepareAsync() que permite continuar con la ejecución del programa,

aunque sin esperar a que el vídeo esté preparado. Las siguientes tres líneas asignan a nuestro

objeto varios escuchadores de eventos que serán descritos más adelante. Tras preparar el tipo de

audio, se sitúa la posición de reproducción a los milisegundos indicados en la variable savePos. Si

se trata de una nueva reproducción, esta variable será cero.

6. Añade el código:

public void onBufferingUpdate(MediaPlayer arg0, int percent) {

log("onBufferingUpdate percent:" + percent); } public void onCompletion(MediaPlayer arg0) {

log("onCompletion called"); }

Los métodos anteriores implementan los

interfaces OnBufferingUpdateListener y OnCompletionListener.El primero irá mostrando el

porcentaje de obtención de búfer de reproducción, mientras que el segundo será invocado cuando

el vídeo en reproducción llegue al final.

7. Añade el código: public void onPrepared(MediaPlayer mediaplayer) { log("onPrepared called"); int mVideoWidth = mediaPlayer.getVideoWidth(); int mVideoHeight = mediaPlayer.getVideoHeight(); if (mVideoWidth != 0 && mVideoHeight != 0) { surfaceHolder.setFixedSize(mVideoWidth, mVideoHeight);

mediaPlayer.start(); } }

El método anterior implementa la interfaz OnPreperedListener. Es invocado una vez que el vídeo

ya está preparado para su reproducción. En este momento podemos conocer el alto y el ancho del

vídeo y ponerlo en reproducción.

7. Añade el código:

public void surfaceCreated(SurfaceHolder) {

log("surfaceCreated called"); playVideo); }

public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) {

Page 9: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 9

log("surfaceChanged called"); }

public void surfaceDestroyed(SurfaceHolder surfaceholder) { log("surfaceDestroyed called"); }

Los métodos anteriores implementan la interfaz SurfaceHolder.Callback. Se invocarán cuando

nuestra superficie de visualización se cree, cambie o se destruya. Los métodos que siguen

corresponden a acciones del ciclo de vida de una actividad:

8. Añade el código:

@Override protected void onDestroy() { super.onDestroy(); if (mediaPlayer != null) {

mediaPlayer.release(); mediaPlayer = null; }

}

Este método se invoca cuando la actividad va a ser destruida. Dado que un objeto de la

claseMediaPlayer consume muchos recursos, resulta interesante liberarlos lo antes posible.

.10. Añade el código:

@Override public void onPause() { super.onPause();

if (mediaPlayer != null & !pause) { mediaPlayer.pause(); } } @Override public void onResume() { super.onResume(); if (mediaPlayer != null & !pause) { mediaPlayer.start(); } }

Los dos métodos anteriores se invocan cuando la actividad pasa a un segundo plano y cuando

vuelve a primer plano. Dado que queremos que el vídeo deje de reproducirse y continúe

reproduciéndose en cada uno de estos casos, se invocan a los

métodos pause() y start(), respectivamente. No hay que confundir esta acción con la

variable pause que lo que indica es que el usuario ha pulsado el botón correspondiente.

11. Añade el código: @Override

protected void onSaveInstanceState(Bundle guardarEstado) { super.onSaveInstanceState(guardarEstado); if (mediaPlayer != null) { int pos = mediaPlayer.getCurrentPosition(); guardarEstado.putString("ruta", path);

guardarEstado.putInt("posicion", pos); } }

@Override protected void onRestoreInstanceState(Bundle recEstado) { super.onRestoreInstanceState(recEstado); if (recEstado != null) { path = recEstado.getString("ruta"); savePos = recEstado.getInt("posicion");

} }

Cuando este sistema necesita memoria, puede decidir eliminar nuestra actividad. Antes de hacerlo

llamará al método onSaveInstanceState para darnos la oportunidad de guardar información

sensible. Si más adelante el usuario vuelve a la aplicación, esta se volverá a cargar, invocándose el

métodoonRestoreInstanceState, donde podremos restaurar el estado perdido. En nuestro caso la

información a guardar son las variables path y savePos, que representan el vídeo y la posición que

estamos reproduciendo.

Page 10: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 10

Ocurre el mismo proceso cuando el usuario cambia la posición del teléfono. Es decir, cuando el

teléfono se voltea las actividades son destruidas y vueltas a crear, por lo que también se invocan

estos métodos.

12. Añade el código: private void log(String s) { logTextView.append(s + "\n"); } }

El último método es utilizado por varios escuchadores de eventos para mostrar información sobre lo

que está pasando. Esta información puede visualizarse o no, utilizando el botón correspondiente.

13. Solicita el permiso para accede a Internet añadiendo en AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET"/>

5. INTRODUCIENDO EFECTOS DE AUDIO CON SOUNDPOOL(1)

Hemos aprendido a utilizar la clase MediaPlayer para reproducir audio y video. En un primer ejercicio

vamos a aprender a utilizarla para introducir efectos de audio en Asteroides. Como veremos esta clase no

resulta adecuada para este uso. A continuación se introducirá la clase SoundPool y se mostrará mediante un

ejercicio como esta sí que resulta eficiente para nuestro juego.

Ejercicio paso a paso: Introduciendo efectos de audio con MediaPlayer en Asteroides.

1. Abre el proyecto anterior.

2. Copia los siguientes ficheros a la carpeta res/raw disparo.mp3 y explosion.mp3.

3. Abre la clase VistaJuego y añade las siguientes variables:

MediaPlayer mpDisparo, mpExplosion;

4. En el constructor de la clase inicialízalas de la siguiente forma:.

mpDisparo = MediaPlayer.create(context, R.raw.disparo);

mpExplosion = MediaPlayer.create(context, R.raw.explosion);

5. Añade en el método ActivaMisil() de VistaJuego:

mpDisparo.start();

6. Añade en el método destruyeAsteroide() de VistaJuego:

mpExplosion.start();

7. Ejecuta el programa y verifica el resultado. ¿Qué pasa cuando disparamos o destruimos un

asteroide? ¿El sonido se oye de forma inmediata?

La clase SoundPool maneja y reproduce de forma rápida recursos de audio en las aplicaciones.

Un SoundPool es una colección de pistas de audio que se pueden cargar en la memoria desde un recurso

(dentro de la APK) o desde el sistema de archivos. SoundPool utiliza el servicio de la

clase MediaPlayer para descodificar el audio en un formato crudo (PCM de16 bits), lo que después

permite reproducirlo rápidamente por el hardware sin tener que decodificarlas cada vez.

Page 11: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 11

Los sonidos pueden repetirse en un bucle una cantidad establecida de veces, definiendo el valor al

reproducirlo, o dejarse reproduciendo en un bucle infinito con -1. En este caso, será necesario detenerlo

con el métodostop().

La velocidad de reproducción también se puede cambiar. El rango de velocidad de reproducción va de 0.5

a 2.0. Una tasa de reproducción de 1.0 hace que el sonido se reproduzca en su frecuencia original. Una

tasa de reproducción de 2.0 hace que el sonido se reproduzca al doble de su frecuencia original, y una

tasa de reproducción de 0.5 hace que se reproduzca a la mitad de su frecuencia original.

Cuando se crea un SoundPool hay que establecer en un parámetro del constructor el máximo de pistas

que se pueden reproducir simultáneamente. Este parámetro no tiene por qué coincidir con el número de

pistas cargadas. Cuando se pone una pista en reproducción (método play()) hay que indicar una

prioridad. Esta prioridad se utiliza para decidir que se hará cuando el número de reproducciones activas

exceda el valor máximo establecido en el constructor. En este caso, se detendrá el flujo con la prioridad

mas baja, y en caso de que haya varios, se detendrá el más antiguo. En caso de que el nuevo flujo sea el

de menor prioridad, este no se reproducirá.

Una lisita de todos los métodos de esta clase la puedes encontrar en el siguiente link:

http://developer.android.com/reference/android/media/SoundPool.html

Ejercicio paso a paso: Introduciendo efectos de audio con SoundPool en Asteroides

1. En proyecto anterior elimina todo el código introducido a partir del punto 3, del ejercicio

anterior.

2. Abre la clase VistaJuego y añade las siguientes variables: // //// MULTIMEDIA //////

SoundPool soundPool; int idDisparo, idExplosion;

3. En el constructor de la clase inicialízalas de la siguiente forma:

soundPool = new SoundPool( 5, AudioManager.STREAM_MUSIC , 0); idDisparo = soundPool.load(context, R.raw.disparo, 0);

idExplosion = soundPool.load(context, R.raw.explosion, 0);

En el constructor de SoundPool hay que indicar tres parámetros. El primero corresponde al

máximo de reproducciones simultáneas. El segundo es el tipo de stream de audio

(normalmente STREAM_MUSIC). El tercero es la calidad de reproducción, aunque actualmente no

se implementa.

Cada una de las pistas ha de ser cargada mediante el método load(). Existen muchas

sobrecargas para este método. La versión utilizada en el ejemplo permite cargar las pistas

desde los recursos. El último parámetro corresponde a la prioridad, aunque actualmente no tiene

ninguna utilidad.

4. Añade en el método ActivaMisil() de VistaJuego:

soundPool.play(idDisparo, 1, 1, 1, 0, 1);

El método play() permite reproducir una pista. Hay que indicarle el identificador de pista; el

volumen para el canal izquierdo y derecho (0.0 a 1.0); La prioridad; El número de repeticiones (-

1= siempre, 0=solo una vez, 1=repetir una vez, … ) y el ratio de reproducción, con el que

podremos modificar la velocidad o pitch (1.0 reproducción normal, rango: 0.5 a 2.0)

Page 12: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 12

5. Añade en el método destruyeAsteroide() de VistaJuego:

soundPool.play(idExplosion, 1, 1, 0, 0, 1);

Los parámetros utilizados para la explosión son similares, solo hemos introducido una prioridad

menor. La consecuencia será que si ya hay un total de 5 (ver constructor) pistas

reproduciéndose y se pide la reproducción de un nuevo disparo. El sistema detendrá la

reproducción de la explosión más antigua, por tener esta menos prioridad.

7 Ejecuta el programa y verifica el resultado. ¿Qué pasa cuando disparamos o destruimos un

asteroide? ¿El sonido se oye de forma inmediata?

8. Modifica algunos de los parámetros del método play() y verifica el resultado.

6. GRABACIÓN DE AUDIO(1)

Las APIs de Android disponen de facilidades para capturar audio y v ideo, permitiendo su

codificación en diferentes formatos. La clase MediaRecorder te permitirá de forma sencilla

integrar esta funcionalidad en tu aplicación.

La mayoría de dispositivos disponen de micrófono para capturar audio, sin embargo esta

facilidad no ha sido integrada en el emulador. Por lo tanto, has de probar los ejercicios de este

apartado en un dispositivo real.

La clase MediaRecorder dispone de una serie de métodos que podrás utilizar para configurar la grabación:

setAudioSource(int audio_source) – Dispositivo que se utilizará como fuente del sonido.

Normalmente MediaRecorder.AudioSource.MIC. También se pueden utilizar otras constantes

como DEFULT, CAMCORDER, VOICE_CALL, VOICE_COMUNICATION, …

setOutputFile (String fichero) – Nombre del f ichero de salida.

setOutputFormat(int output_forma) – Formato del f ichero de salida. Se pueden utilizar constantes de la

clase MediaRecorder.OutputFormat: DEFAULT, AMR_NB, AMR_WB, RAW_AMR (ARM), MPEG_4(MP4)

y THREE_GPP (3GPP).

setAudioEncoder(int audio_encoder) – Codif icación del audio. Cuatro posibles constantes de la

clase MediaRecorder.AudioEncoder: AAC, AMR_NB, AMR_WB y DEFAULT.

setAudioChannels(int numeroCanales) – Especif icamos el número de canales 1: mono y 2: estéreo.

setAudioEncodingBitRate (int bitRate) (desde nivel de API 8) – Especif icamos los bits por segundo (bps) a

utilizar en la codif icación.

setAudioSamplingRate (int samplingRate) (desde nivel de API 8) – Especif icamos el número de muetras por

segundo a utilizar en la codif icación.

setMaxDuration (int max_duration_ms) (desde nivel de API 3) – Indicamos una duración máxima para la

grabación. Tras este tiempo se detendrá.

setMaxFileSize (long max_filesize_bytes) (desde nivel de API 3) – Indicamos un tamaño máximo para el

f ichero. Al alcanzar el tamaño se detendrá.

prepare() – Prepara la grabación para la captura de datos. Antes de llamarlo hay que configurar la grabación y

después ya podemos invocar al método start().

start() – Comienza la captura

stop() – Finaliza la captura

reset() – Reinicia el objeto como si lo acabáramos de crear. Hay que volver a configurarlo.

release() – Libera todos los recursos utilizados de forma inmediata. Si no llamas al método se liberarán cuando

el objeto sea destruido.

Page 13: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 13

La clase MediaRecorder también dispone de métodos que podrás utilizar para configurar la grabación de video.

Más información en: http://developer.android.com/reference/android/media/MediaRecorder.html

La siguiente tabla muestra los diferentes métodos que pueden ser ejecutados en cada estado y el estado que

alcanzaremos tras la llamada:

Estado

salida

Estado entrada

Initial Initialized DataSource

Configured Prepared Recording Error

Initial reset reset reset reset

stop

reset

Initialized setAudioSource

setVideoSource

setAudioSource

setVideoSource

DataSource

Configured

setOutputFormat

setAudioEncoder

setVideoEncoder

setOutputFile

setVideoSize

setVideoFrameRate

setPreview Display

Prepared prepare

Recording start

Released releas

Error llamada incorrecta llamada incorrecta llamada

incorrecta

llamada

incorrecta

llamada

incorrecta

Tabla 7: Transiciones entre estados de la clase MediaRecorder

Ejercicio paso a paso: Grabación de audio utilizando MediaRecoder

1. Crea un nuevo proyecto con nombre Grabadora. El nombre del paquete ha de ser

org.example.grabadora y como actividad principal GrabadoraActivity.

2. Reemplaza el layout activity_main.xml por el siguiente código:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"

android:layout_height="match_parent" android:orientation="horizontal"> <Button android:id="@+id/bGrabar"

android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Grabar" android:onClick="grabar"/> <Button android:id="@+id/bDetener"

android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Detener Grabacion" android:onClick="detenerGrabacion"/> <Button android:id="@+id/bReproducir" android:layout_width="wrap_content" android:layout_height="wrap_content"

Page 14: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 14

android:text="Reproducir" android:onClick="reproducir"/> </LinearLayout>

3. Reemplaza el código de la actividad por:

public class GrabadoraActivity extends Activity {

private static final String LOG_TAG = "Grabadora"; private MediaRecorder mediaRecorder; private MediaPlayer mediaPlayer;

private static String fichero = Environment. getExternalStorageDirectory().getAbsolutePath()+"/audio.3gp"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);

} public void grabar(View view) { mediaRecorder = new MediaRecorder();

mediaRecorder.setOutputFile(fichero); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mediaRecorder.setOutputFormat(MediaRecorder. OutputFormat.THREE_GPP); mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder. AMR_NB);

try { mediaRecorder.prepare(); } catch (IOException e) { Log.e(LOG_TAG, "Fallo en grabación"); } mediaRecorder.start(); }

public void detenerGrabacion(View view) {

mediaRecorder.stop(); mediaRecorder.release(); }

public void reproducir(View view) { mediaPlayer = new MediaPlayer(); try { mediaPlayer.setDataSource(fichero); mediaPlayer.prepare(); mediaPlayer.start();

} catch (IOException e) { Log.e(LOG_TAG, "Fallo en reproducción"); } }

}

Comenzamos declarando dos objetos de las clase MediaRecorder y MediaPlayer que serán

usados para la grabación y reproducción respectivamente. También se declaran

dos String: La constanteLOG_TAG será utilizada como etiqueta para identificar nuestra

aplicación en el fichero de Log. La variable ficheroidentifica en nombre del fichero donde se

guardará la grabación. Este fichero se almacenará en una carpeta especialmente creada

para nuestra aplicación. NOTA: En la unidad 8 se introducirá la gestión de ficheros. En el

método onCreate() no se realiza ninguna acción especial.

A continuación se han introducido tres métodos que serán ejecutados al pulsar los botones

de nuestro Layout. El significado de cada uno de los métodos que se invocan acaba de ser

explicado.

4. Abre AndroidManifest.xml y en la pestaña Permissions pulsa el

botón Add… selecciona Uses Permissions. En el desplegable Name indica RECORD_AUDIO.

Repite este proceso para usar el permisoWRITE_EXTERNAL_STORAGE.

5. Ejecuta de nuevo la aplicación y verifica el resultado.

Page 15: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 15

Ejercicio paso a paso: Grabación de audio utilizando MediaRecoder (II)

La aplicación anterior resulta algo confusa de utilizar. Sería más sencillo si los botones que no

pudiéramos utilizar en un determinado momento estuvieran deshabilitados. Para conseguirlo vamos a

utilizar el métodoButton.setEnabled(boolean). Veamos como conseguirlo:

1. Declara las siguientes tres variables al principio de la Actividad:

private Button bGrabar, bDetener, bReproducir;

2. En el método onCreate() inicializa estos tres botones. Además comenzaremos

deshabilitando dos de los botones que al principio de la aplicación no deben ser

pulsados:

bGrabar = (Button) findViewById(R.id.bGrabar); bDetener = (Button) findViewById(R.id.bDetener);

bReproducir = (Button) findViewById(R.id.bReproducir); bDetener.setEnabled(false); bReproducir.setEnabled(false);

3. En el método grabar() añade el siguiente código:

bGrabar.setEnabled(false); bDetener.setEnabled(true); bReproducir.setEnabled(false);

4. En el método detenerGrabacion() añade el siguiente código:

bGrabar.setEnabled(true); bDetener.setEnabled(false);

bReproducir.setEnabled(true);

5. Ejecuta de nuevo la aplicación y verifica el resultado.

7. REPRODUCCIÓN Y CONTROL DE AUDIO(2)

Actualmente, las características de los teléfonos que vienen con Android nos permiten consumir

contenidos multimedia sin que el dispositivo sufra al cumplir con esta tarea. Así que el día de hoy

vamos a conocer las dos API’s que Android provee para trabajar con

sonidos: SoundPool y MediaPlayer.

Podemos utilizar SoundPool para reproducir pequeñas pistas de audio. Con esta clase podemos

repetir la reproducción de sonidos y hasta reproducir múltiples sonidos de manera simultánea. Un

dato importante que debes tomar en cuenta cuando trabajas con esta clase, es que los archivos de

sonido que quieras reproducir no deben sobrepasar 1 MB de tamaño.

Básicamente, esta clase carga el archivo de forma asíncrona; además de que a partir de la versión

Android 2.2 es posible comprobar si la carga se ha completado a través de un

objeto OnLoadCompleteListener.

Page 16: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 16

Por otro lado, Android soporta diferentes flujos de audio que pueden utilizarse para propósitos

diferentes. También resulta interesante saber, que el botón de volumen del teléfono puede ser

configurado para controlar un stream de audio en específico; un buen ejemplo es durante una

llamada en la cuál el botón de volumen nos ayuda a subir o bajar la intensidad del sonido de la

misma. Para conseguir esto es necesario especificar el tipo de audio que maneja nuestra aplicación,

por ejemplo la siguiente línea de código nos ayudaría a controlar el flujo de música que estemos

escuchando desde el reproductor: context.setVolumeControlStream(AudioManager.STREAM_MUSIC);

Si quieres revisar más acerca de los tipos de sonidos que podemos utilizar en nuestras aplicaciones,

échale un vistazo a la documentación de la clase AudioManager.

Cuando queramos trabajar con pistas de audio más largas y video, la clase MediaPlayerserá la

elección para trabajar.

En este tutorial haremos un pequeño ejemplo de cómo trabajar con la clase SoundPool.

1. Creamos un nuevo proyecto llamado SoundsTest con la versión Android 2.2.

El objetivo de la aplicación será reproducir un sonido cada vez que el usuario toque alguno de los

botones disponibles con el dedo. También, para efectos de jugar con propiedades como volumen,

velocidad y balance de las pistas de audio, trabajaremos con la claseAudioManager.

Interfaz de usuario

2. Nuestra interfaz la dividiremos en tres partes. Como es un tanto “compleja” su estructura, vamos a

irla trabajando por partes para que no te pierdas. Los siguientes trozos de código los vamos a ir

escribiendo dentro del archivo main.xml.

2.1 Tendremos un LinearLayout como elemento raíz tal y como te muestro a continuación:

Debes tomar en cuenta que esta es únicamente la estructura de partida y que los puntos

suspensivos los he escrito para que identifiques dentro de qué etiquetas va a ir todo el código que

manejaremos a partir de ahora.

2.2 El siguiente trozo que sigue es un TextView que desplegará el texto Sounds Test. Este elemento es

únicamente para darle un mejor aspecto visual a la app, no cumple ninguna función por lo que no es

necesario definirle una id.

Page 17: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 17

2.3 Inmediatamente después del código anterior, vamos a crear dos nuevos contenedores de

tipo LinearLayout que guardará tres botones cada uno. Esto nos permitirá alinear los elementos de

forma horizontal. Los botones para cadaLinearLayout deberán tener una id ya que los utilizaremos

para reproducir cada uno de los sonidos asociados. A continuación te adjunto el código del

primer LinearLayoutque contiene los botones para los sonidos “Zap”, “Boom”, “Pick up”:

2.4 Ahora, inmediatamente después de la etiqueta que cierra este contenedor, agregamos el

segundo LinearLayout de botones, que en este caso son para “Miau”, “Gua gua” y “Moo”:

Page 18: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 18

2.5 Ahora vamos a crear tres SeekBar con un TextView cada una. La primera nos permitirá manejar el

volumen de los sonidos. El siguiente código nos ayudará a crear la primera barra y deberás

escribirla justo después del cierre del segundoLinearLayout:

2.6 La segunda SeekBar corresponde a la barra que nos permitirá controlar el balance del sonido. El

balance va orientado a la calidad del sonido cuando se reproduce, y el código que deberás escribir

es el que te muestro a continuación:

Page 19: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 19

2.7 Por último, agregamos la última SeekBar que controlará la velocidad con la que se reproducirá el

sonido que elija el usuario.

3. ¡Listo! Ahora que ya tenemos la interfaz de usuario, será necesario agregar las pistas de audio

que sonarán cuando el usuario toque la pantalla. Te recomiendo visitar el este sitiopara descargar el

archivo de sonido de tu preferencia. Recuerda que cuando trabajamos con SoundPool, los archivos

deben ser más chicos que 1MB. Si quieres utilizar los mismos archivos que yo utilicé en este demo

los puedes descargar desde este link. Los archivos que descargues deberás guardarlo en el

directorio res > raw, directorio que también deberás crear en tu proyecto. Para que no tengas

problemas con el nombre del archivo, renómbralo utilizando únicamente letras minúsculas y

números y de preferencia sin utilizar espacios en blanco ni caracteres especiales como acentos y

“ñ”.

Page 20: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 20

4. Ahora pasemos a crear el código necesario para reproducir los sonidos. Para ello vamos a crear

una nueva clase dentro del paquete src donde se encuentra la actividad principal del proyecto. A

esta nueva clase la he llamado SoundManager.

4.1 Escribimos las sentencias import de las tres clases a utilizar: SoundPool que será el componente

principal de esta clase; AudioManager para controlar las configuraciones globales de la reproducción

de los sonidos de la aplicación; y Context que se necesita para obtener los recursos de sonido que

guardamos en el paso anterior.

import android.content.Context;

import android.media.AudioManager;

import android.media.SoundPool;

4.2 Pasamos a crear todas las variables que vamos a utilizar para que los ajustes que defina el

usuario se vean reflejados a la hora de reproducir los sonidos.

public class SoundManager {

private Context pContext;

private SoundPool sndPool;

private float rate = 1.0f;

private float masterVolume = 1.0f;

private float leftVolume = 1.0f;

private float rightVolume = 1.0f;

private float balance = 0.5f;

4.3 Definimos el constructor que nos permitirá inicializar un objeto de tipo SoundPool que define el

volumen de los sonidos al 100% y con la capacidad de poder controlar el audio de la pista.

public SoundManager(Context appContext){

sndPool = new SoundPool(16, AudioManager.STREAM_MUSIC, 100);

Page 21: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 21

pContext = appContext;

}

4.4 Después definimos los métodos para cargar los sonidos y reproducirlos. El primero recibe el id

de la pista para que la elija de los archivos alojados físicamente en el proyecto; y el segundo, es

simplemente una función que nos permita reproducir la pista pasando como parámetro el resto de

los ajustes como sonido, balance y velocidad.

public int load(int sound_id){

return sndPool.load(pContext, sound_id, 1);

}

public void play(int sound_id){

sndPool.play(sound_id, leftVolume, rightVolume, 1, 0, rate);

}

4.5 Los siguientes tres métodos nos ayudarán a controlar las variaciones de las tresSeekBar de la

aplicación para aumentar o disminuir los parámetros de volumen, velocidad y balance.

Page 22: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 22

4.6 Por último, el método unloadAll() nos permitirá liberar la memoria de todos los

objetos SoundPool que ya no son requeridos y evitar así, que la aplicación alente el teléfono donde se

está ejecutando la app.

public void unloadAll(){

sndPool.release();

}

5. Ahora modificaremos la actividad principal. En mi caso la clase se llamaSoundsTestActivity y en ella

vamos a asignar todos los eventos a cada uno de los botones que definimos en la interfaz de

usuario en el paso 2.

5.1 Escribimos las sentencias import de las clases que utilizaremos a lo largo del desarrollo de esta

clase:

import android.app.Activity;

import android.media.AudioManager;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.SeekBar;

import android.widget.SeekBar.OnSeekBarChangeListener;

5.2 Ya en nuestra clase (y antes del comienzo del método onCreate()) declaramos todas las variables

que vamos a utilizar. Una de tipo SoundManager para definir la carga de los archivos de sonido y sus

propiedades de reproducción. Seis variables de tipo entero que guardan los id’s de cada uno de los

archivos de audio que guardamos en el directorio res > raw. Una variable OnSeekBarChangeListener que

controlarán los cambios hechos a cada una de las SeekBar de la app.

public class SoundsTestActivity extends Activity {

SoundManager snd;

int laser, explode, pickup,

meow , bark, moo;

OnSeekBarChangeListener barChange;

OnClickListener buttonClick;

......

}

5.3 Ahora, vamos a escribir el contenido del método onCreate().

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

snd = new SoundManager(getApplicationContext());

this.setVolumeControlStream(AudioManager.STREAM_MUSIC);

laser = snd.load(R.raw.laser);

explode = snd.load(R.raw.explosion);

Page 23: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 23

pickup = snd.load(R.raw.pickup);

meow = snd.load(R.raw.cat);

bark = snd.load(R.raw.barkloud);

moo = snd.load(R.raw.cow);

barChange = new OnSeekBarChangeListener()

{

@Override

public void onStopTrackingTouch(SeekBar seekBar) { }

@Override

public void onStartTrackingTouch(SeekBar seekBar)

{ }

@Override

public void onProgressChanged(SeekBar seekBar, int

progress, boolean fromUser)

{

switch (seekBar.getId())

{

case R.id.VolBar1:

snd.setVolume((float)progress/100.0f);

break;

case R.id.BalBar:

snd.setBalance((float)progress/100.0f);

break;

case R.id.SpeedBar:

snd.setSpeed((float)progress/100.0f);

break;

}

}

};

SeekBar sb;

sb = (SeekBar)findViewById(R.id.SpeedBar);

sb.setOnSeekBarChangeListener(barChange);

sb = (SeekBar)findViewById(R.id.BalBar);

sb.setOnSeekBarChangeListener(barChange);

sb = (SeekBar)findViewById(R.id.VolBar1);

sb.setOnSeekBarChangeListener(barChange);

}

Lo primero que hacemos es crear la instancia en el objeto SoundManager. Después, definimos el

volumen para el flujo de audio que manejará la app. Acto seguido, inicializamos todas las

variables int con los id’s de los archivos de audio de nuestro proyecto, observa que en este caso

utilizamos la notación R.draw.NombreDelSonido.

La siguiente parte corresponde a la creación del manejador de eventos de las SeekBaren el que

recuperamos las referencias de los widgets SeekBar del archivo main.xml, y por último le asignamos

este listener a cada SeekBar para que podamos trabajar con las variaciones que el usuario haga en la

aplicación.

5.4 Por último, creamos un método llamado clickHandler() para controlar cada uno de los eventos de

click hechos a cada uno de los seis botones de la interfaz. Si recuerdas, en la declaración en XML

de cada botón, definimos un atributo android:onClick, cuyo valor es “clickHandler”. Todos los botones lo

Page 24: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 24

tienen, por lo que, este método, por medio de una sentencia switch hace la selección del botón

presionado a través del ID de la vista que recibe como parámetro. La vista es precisamente el botón

que manda a llamar a este método. También, podrás ver que en cada case, existe una línea Log.i();

esta la he definido para imprimir en la pestaña de Log de Eclipse qué botón se está presionando. A

continuación, puedes ver el código de este método:

public void clickHandler(View v)

{

int id = v.getId(); // Use the button id to determine which sample

should be played

switch (id)

{

case R.id.button1:

snd.play(laser);

Log.i("---","Button1");

break;

case R.id.button2:

snd.play(explode);

Log.i("---","Button2");

break;

case R.id.button3:

snd.play(pickup);

Log.i("---","Button3");

break;

case R.id.button4:

snd.play(meow);

Log.i("---","Button4");

break;

case R.id.button5:

snd.play(bark);

Log.i("---","Button5");

break;

case R.id.button6:

snd.play(moo);

Log.i("---","Button6");

break;

}

}

6. Ahora sí, ya podemos correr el demo y escuchar cada uno de los sonidos que hemos puesto en el

directorio res > raw. También haz pruebas de los ajustes de volumen, velocidad y balance.

Page 25: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 25

8. REPRODUCCIÓN DE AUDIO: PAUSE,STOP(3)

Se realiza una práctica para la reproducción de sonidos y el control de los botones Pause y Stop

Se crean en el área de trabajo 3 botones: Play, Pause y Stop.

Page 26: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 26

Crearemos la carpeta raw, dentro de la carpeta res y almacenaremos en la misma el archivo mp3. Refrescaremos la carpeta raw para actualizar el

proyecto.

Page 27: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 27

El código fuente quedaría de la siguiente manera el cual estaría en este caso

en MainActivity.

Page 28: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 28

A continuación se describirá brevemente el código:

1.- Se importaran las siguientes librerías, para utilizarlas previamente:

import android.media.MediaPlayer; import android.view.View; import android.widget.Button;

2.- Se crearan las siguientes variables:

MediaPlayer pp;//Se instanciara el Media Player Button btn1;//Se instanciara el botón 1 int po= 0;//Se creara una variable para controlar la posición private Button btn2;//Se creara una variable para el botón 2.

3.- Se instanciará los botones para saber que botón corresponde a cada uno de ellos. btn1=(Button) findViewById(R.id.btnpau); btn2=(Button) findViewById(R.id.button2);

4.- El método LimpiarMP, realizara una comparación quiere decir que si la

variable PP es diferente o igual a null, la reproducción de audio empezara.

public void LimpiarMP(){ if(pp!=null){ pp.release(); } }

5.- Se método sonido, mandara a llamar el método Limpiar, después se mandara a llamar por medio de la variable pp el sonido que se desea reproducir, la variable nu=0 y empezara la reproducción del sonido.

public void Sonido (View v){ LimpiarMP(); pp = MediaPlayer.create(this, R.drawable.to); nu=0; pp.start(); }

6.- El método Pause comparara o verifica que el objeto de la clase Media

Player este creado y en ejecución, en caso afirmativo recuperaremos la posición actual de la reproducción.

Page 29: Aplicaciones moviles clase10 multimedia

IESTP “MARÍA ROSARIO ARAOZ PINTO” COMPUTACIÓN E INFORMÁTICA

APLICACIONES MÓVILES 29

public void Pause (View v){

if(pp!=null && pp.isPlaying()){ po=pp.getCurrentPosition(); btn2.setText ("Reaunudar"); pp.pause(); nu=1; }

7.- El método detener interrumpir la ejecución del mp3 e inicializa el atributo posición con cero.

public void Detener (View v){ if(pp!=null){ pp.stop(); po=0; nu=0; LimpiarMP(); } }

Por último se mandaran a llamar los métodos creados en el área de trabajo, se seleccionara el botón, en la barra de Propiedades, seleccionar On Click se

mandara a llamar el método.

MATERIAL EXTRAÍDO DE:

1. http://www.androidcurso.com/index.php/tutoriales-android/37-unidad-6-multimedia-

y-ciclo-de-vida/167-un-reproductor-multimedia-paso-a-paso#_ftn1

2. http://androideity.com/2011/11/13/reproducir-sonidos-en-android/

3. https://sites.google.com/site/tutorialesuach/android-con-eclipse/reproduccion-de-

audio-pause-stop