2012-05-31 8 views
5

バックグラウンドでは、マイク経由で連続して記録し、バッファにデータを保存するアプリケーションを作成しようとしています。プログラムの目的は、バッファ内のデータに対して何らかの処理を行い、それに基づいて処理することです。 現在のところ、このアプリはデータをバッファに読み込んですぐに書き込みます。アプリを実行すると、マイクに向かって話し、ちょうど話したことが相手側に出てくるのを聞くことができます。作成時に無限ループを含むサービスを停止/開始する方法

ここで、Androidでの私の未経験がその頭を後にし始めるところです。私は無限ループとして読み書き操作を行っています。サービスは以下の通りです:

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

このサービスは、アクティビティで[レコード]ボタンがクリックされたときに呼び出されます。私はレコードをクリックし、このループを止めるためにキャンセルをクリックするオプションを持つことができるようにしたい。その下にあるリスナーは、次のとおりです。

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

}; 

これで問題は明らかになりました。 startService(serviceIntent)に達した時点でアプリケーションを実行することができず、残高にハングアップするだけです。

私の義務は何ですか?私は無限ループの中からサービスを制御する何らかの方法を考えていましたが、Androidの経験がなくて私はそれをどうやって行うのか不思議でした。おそらく、ループ内で新しいボタンをインスタンス化することによって中断する何らかの方法を誘発する。 startIntentではループから抜け出して「狂気を終わらせる」ことができます。

ご協力いただければ幸いです。私はまた、このサービスがUIからの独立したスレッド上で開始されるべきであることを認識しているので、「App not responding ...」という問題は回避されますが、それは別の話題です。私の今の主な目標は、ループから逃れることであり、私はthiszをどうやってやるかについての助けや方向性に感謝しています。

答えて

4

サービスは

以下の問題#1:あなたはあなたのループを抜け出しの方法がありません。

問題#2:ループがメインのアプリケーションスレッドで実行されています。

これは悪いです。

私の義務は何ですか?

あなたは必要なときに停止する(例えば、onDestroy())をそのスレッドを伝えるために何か(例えば、AtomicBoolean)を使用して、バックグラウンドスレッドでは、あなたの無限ループを置きます。 「アプリケーションが応答していない...」問題を回避するために、私はまた、このサービスを実現しています

は、UIからの別々のスレッド上で開始されなければならないが、それは別のトピックの一種です。

いいえ、同じトピックです。多分

サービスはUIを持っていないループ内で新しいボタンをインスタンス化することによって分割するいくつかの方法を扇動

そのアクティビティにstartService()への呼び出しをトリガーする「レコード」ボタンがあるため、おそらくそのアクティビティにstopService()への呼び出しをトリガーする「停止」ボタンが必要です。

どこで、どのようstopService()を呼び出すために、あなたは、あなたがする必要があるすべてはonDestroy()stopService()への呼び出しによってトリガーされるように、バックグラウンドスレッドが実行を停止させるために、あなたのサービスのonDestroy()を取得され、決定したら。

+0

完璧!私はバックグラウンドスレッドにループを動かす作業に着くでしょう。キャンセルボタンがありますが、その目的はこれをすべて止めることでしたが、私はレコードを押した後も引き続きつかんでいました。ありがとう! – user1429581

関連する問題