2012-05-31 12 views
5

Quindi, per lo sfondo, sto tentando di creare un'applicazione che registra continuamente tramite il microfono e memorizza i dati in un buffer. L'obiettivo del programma sarebbe quello di eseguire un certo tipo di elaborazione sui dati nel buffer e agire su di esso. Attualmente l'app legge i dati in un buffer e li scrive al più presto. Quando si esegue l'app, si parla al microfono e poi si sente quello che hai appena pronunciato dall'altra parte.Come arrestare/avviare un servizio che contiene un ciclo infinito sulla creazione

Ora qui è dove la mia inesperienza con Android inizia a far girare la testa. Sto conducendo l'operazione di lettura e scrittura come un ciclo infinito. Il servizio è di seguito:

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; 
} 

Questo servizio viene chiamato quando si fa clic sul pulsante "Registra" nell'attività. Voglio poter fare clic su Registra e avere l'opzione di fare clic su Annulla per interrompere questo ciclo. L'ascoltatore sotto che implementa questo è:

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(); 

}; 

E ora il problema diventa ovvio. L'applicazione non è in grado di completare l'esecuzione quando raggiunge startService (serviceIntent) e si blocca in giro.

Allora, qual è il mio ricorso? Stavo pensando ad un modo per controllare il servizio dall'interno del ciclo infinito ma la mia inesperienza con Android mi lascia chiedermi come farlo. Incitare in qualche modo a rompere forse creando un'istanza di un nuovo pulsante all'interno del ciclo; così durante startIntent sarei in grado di uscire dal giro e "finire la follia".

Qualsiasi aiuto sarebbe apprezzato. Sto anche realizzando che questo servizio dovrebbe essere avviato su un thread separato dall'interfaccia utente in modo da evitare il problema "App non risponde ..." ma è una specie di altro argomento. Il mio obiettivo principale per ora è rompere il loop e apprezzerei qualsiasi aiuto o direzione su come fare questo.

risposta

4

Il servizio è al di sotto

Problema # 1: Non hai modo di rompere fuori del vostro ciclo.

Problema 2: il loop è in esecuzione sul thread dell'applicazione principale.

Questo è male.

Allora, qual è il mio ricorso?

si mette il ciclo infinito in un thread in background, utilizzando qualcosa (per esempio, un AtomicBoolean) per dire quel filo di fermarsi in caso di necessità (ad esempio, onDestroy()).

Sto anche la realizzazione di questo servizio dovrebbe essere avviato su un filo separato da interfaccia utente in modo da evitare la "App non risponde ..." problema, ma questa è una sorta di un altro argomento.

No, è lo stesso argomento.

Istigazione qualche modo per rompere con forse un'istanza di un nuovo pulsante all'interno del ciclo

Servizi non hanno un'interfaccia utente.

Poiché si dispone di un pulsante "record" in tale attività che attiva una chiamata a startService(), allora forse quell'attività dovrebbe avere un pulsante "stop" che attiva una chiamata a stopService().

Una volta a determinare dove e come chiamare stopService(), allora tutto quello che dovete fare è ottenere onDestroy() del vostro servizio per causare il thread in background per smettere di correre, come onDestroy() saranno attivati ​​dalla chiamata a stopService().

+0

Perfetto! Dovrò lavorare sullo spostamento del ciclo su un thread in background. C'è un pulsante di annullamento il cui obiettivo era quello di fermare tutto questo ma ho continuato a rimanere bloccato dopo aver premuto Record. Grazie! – user1429581

Problemi correlati