2012-05-31 22 views
5

De modo que, en segundo plano, intento crear una aplicación que registre continuamente a través del micrófono y almacene los datos en un búfer. El objetivo del programa sería realizar algún tipo de procesamiento en los datos en el búfer y actuar en consecuencia. Actualmente, la aplicación solo lee los datos en un búfer y lo escribe lo antes posible. Cuando ejecutas la aplicación, uno habla por el micrófono y luego escucha lo que acabas de decir al otro lado.Cómo detener/iniciar un servicio que contiene un bucle infinito en la creación

Ahora aquí es donde mi inexperiencia con Android comienza a crecer. Estoy llevando a cabo la operación de lectura y escritura como un ciclo infinito. El servicio está por debajo:

public class AudioService extends Service { 

private final int MIC = AudioSource.MIC; 
private final int SAMPLE = 44100; 
private final int CHANNELI = AudioFormat.CHANNEL_IN_MONO; 
private final int CHANNELO = AudioFormat.CHANNEL_OUT_MONO; 
private final int FORMAT = AudioFormat.ENCODING_PCM_16BIT; 
private final int BUFFERSIZE = AudioRecord.getMinBufferSize(SAMPLE, 
     CHANNELI, FORMAT); 
private final int STREAM = AudioManager.STREAM_MUSIC; 
private final int MODE = AudioTrack.MODE_STREAM; 
private boolean play = true; 

AudioRecord recorder = null; 
AudioTrack track = null; 

short[] buffer = null; 

public void OnCreate() { 

} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    recorder = new AudioRecord(MIC, SAMPLE, CHANNELI, FORMAT, BUFFERSIZE); 
    track = new AudioTrack(STREAM, SAMPLE, CHANNELO, FORMAT, BUFFERSIZE, 
      MODE); 
    buffer = new short[BUFFERSIZE]; 
    recorder.startRecording(); 
    track.play(); 

    while (play) { 
     recorder.read(buffer, 0, buffer.length); 
     track.write(buffer, 0, buffer.length); 
    } 
    return START_STICKY; 
} 

Este servicio se llama cuando se hace clic en un botón "Grabar" en la actividad. Quiero poder hacer clic en grabar y tener la opción de hacer clic en cancelar para detener este ciclo. El oyente a continuación que implementa esto es:

private OnClickListener Recording = new OnClickListener() { 
    public void onClick(View v) { 

     serviceIntent = new Intent(getApplicationContext(), 
       AudioService.class); 
     serviceIntent.putExtra("extraData", "somedata"); 
     startService(serviceIntent); 

     record.setEnabled(false); 
     cancel.setEnabled(true); 
     cancel.requestFocus(); 

}; 

Y ahora el problema se vuelve obvio. La aplicación no puede completar la ejecución cuando llega a startService (serviceIntent) y simplemente se queda en la balanza.

¿Cuál es mi recurso? Estaba pensando en alguna forma de controlar el servicio desde el infinito, pero mi inexperiencia con Android me deja pensando cómo hacerlo. Incitar a alguna forma de romper al crear un nuevo botón dentro del ciclo; entonces, durante el inicio, yo sería capaz de salir del círculo y "terminar con la locura".

Cualquier ayuda sería apreciada. También me doy cuenta de que este servicio se debe iniciar en un hilo separado de la interfaz de usuario a fin de evitar la cuestión de que "la aplicación no responde ..." pero ese es otro tema. Mi principal objetivo en este momento es salir del circuito y agradecería cualquier ayuda o dirección sobre cómo hacer esto.

Respuesta

4

El servicio está por debajo

Problema # 1: Usted no tiene manera de romper el bucle.

Problema n. ° 2: Su bucle se ejecuta en la cadena principal de la aplicación.

Esto es malo.

¿Cuál es mi recurso?

usted pone su bucle infinito en un subproceso en segundo plano, el uso de algo (por ejemplo, un AtomicBoolean) para decirle que el hilo para detener cuando sea necesario (por ejemplo, onDestroy()).

También me doy cuenta de que este servicio se debe iniciar en un hilo separado de la IU para evitar el problema "La aplicación no responde ..." pero ese es otro tema.

No, es el mismo tema.

Incitar alguna manera de romper por tal instancias de un nuevo botón en el interior del bucle

Los servicios no tienen una interfaz de usuario.

Dado que tiene un botón "grabar" en esa actividad que desencadena una llamada al startService(), entonces tal vez esa actividad debe tener un botón "detener" que desencadena una llamada al stopService().

Una vez que determine dónde y cómo llamar stopService(), entonces todo lo que necesita hacer es conseguir onDestroy() de su servicio para hacer que el subproceso de fondo para detener la ejecución, como onDestroy() se disparará por la llamada a stopService().

+0

¡Perfecto! Empezaré a trabajar en mover el ciclo a un hilo de fondo. Hay un botón cancelar cuyo objetivo era detener todo esto, pero seguí colgando después de presionar Grabar. ¡Gracias! – user1429581

Cuestiones relacionadas