从服务中录制音频,给出ERROR_INVALID_OPERATION错误

时间:2013-10-15 08:13:13

标签: android audio service audio-recording

我正在录制音频并将其保存在SD卡上。当我在我的活动中这样做时效果很好,但是当我从服务中调用录制方法时,它会给出ERROR_INVALID_OPERATION错误。

我的活动:

public class Hearactivity extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //b = (Button) findViewById(R.id.btnStart);  
    setButtonHandlers();
    enableButtons(false);

    record = (Button) findViewById(R.id.btnStart);      
    record.setEnabled(true);

    startservice = (Button) findViewById(R.id.ServiceStart);   

    stopservice = (Button) findViewById(R.id.ServiceStop);

    bufferSize = AudioRecord.getMinBufferSize(8000,
            AudioFormat.CHANNEL_IN_MONO,
            AudioFormat.ENCODING_PCM_16BIT);
}

private void setButtonHandlers() {
    ((Button)findViewById(R.id.btnStart)).setOnClickListener(btnClick);

    ((Button)findViewById(R.id.ServiceStart)).setOnClickListener(btnClick);

    ((Button)findViewById(R.id.ServiceStop)).setOnClickListener(btnClick);
}

private void enableButton(int id,boolean isEnable){
    ((Button)findViewById(id)).setEnabled(isEnable);
}

private void enableButtons(boolean isRecording) {
    enableButton(R.id.btnStart,!isRecording);
    //enableButton(R.id.btnStop,isRecording);
}

private String getFilename(){
    String filepath = Environment.getExternalStorageDirectory().getPath();
    File file = new File(filepath,AUDIO_RECORDER_FOLDER);

    if(!file.exists()){
        file.mkdirs();
    }

    return (file.getAbsolutePath() + "/" + "RecordAudio" + AUDIO_RECORDER_FILE_EXT_WAV);
}

private String getTempFilename(){
    String filepath = Environment.getExternalStorageDirectory().getPath();
    File file = new File(filepath,AUDIO_RECORDER_FOLDER);

    if(!file.exists()){
        file.mkdirs();
    }

    File tempFile = new File(filepath,AUDIO_RECORDER_TEMP_FILE);

    if(tempFile.exists())
        tempFile.delete();

    return (file.getAbsolutePath() + "/" + AUDIO_RECORDER_TEMP_FILE);
}

private void writeAudioDataToFile(){
    byte data[] = new byte[bufferSize];
    String filename = getTempFilename();
    FileOutputStream os = null;

    try {
        os = new FileOutputStream(filename);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    int read = 0;

    if(null != os){
        while(isRecording){
            read = recorder.read(data, 0, bufferSize);

            if(AudioRecord.ERROR_INVALID_OPERATION != read){
                try {
                    os.write(data);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        try {
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public void stopRecording(){
    if(null != recorder){
        isRecording = false;

        int i = recorder.getState();
        if(i==1)
            recorder.stop();
        recorder.release();
        //    b.setEnabled(true);
        recorder = null;
        recordingThread = null;
    }

    copyWaveFile(getTempFilename(),getFilename());
    deleteTempFile();       
}

private void deleteTempFile() {
    File file = new File(getTempFilename());

    file.delete();
}

private void copyWaveFile(String inFilename,String outFilename){
    FileInputStream in = null;
    FileOutputStream out = null;
    long totalAudioLen = 0;
    long totalDataLen = totalAudioLen + 36;
    long longSampleRate = RECORDER_SAMPLERATE;
    int channels = 2;
    long byteRate = RECORDER_BPP * RECORDER_SAMPLERATE * channels/8;

    byte[] data = new byte[bufferSize];

    try {
        in = new FileInputStream(inFilename);
        out = new FileOutputStream(outFilename);
        totalAudioLen = in.getChannel().size();
        totalDataLen = totalAudioLen + 36;

        AppLog.logString("File size: " + totalDataLen);

        WriteWaveFileHeader(out, totalAudioLen, totalDataLen,
                longSampleRate, channels, byteRate);

        while(in.read(data) != -1){
            out.write(data);
        }

        in.close();
        out.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public View.OnClickListener btnClick = new View.OnClickListener() {
    @Override
    public void onClick(View v) {

        switch(v.getId()){
        case R.id.btnStart:{
            AppLog.logString("Start Recording");
            hHandler.sendEmptyMessage(0);           
            enableButtons(true);
            ((Button)findViewById(R.id.btnStart)).setVisibility(0);

            Recordtrigger();

        }
        break;
        case R.id.ServiceStart:
        {

            Intent ser= new Intent(Hearactivity.this, Hearservice.class);
            startService(ser);

            bindService(ser, mConnection, Hearactivity.this.BIND_AUTO_CREATE);

            System.out.println("service called======");

        }
        break;
        case R.id.ServiceStop:
        {
            Intent name = new Intent(Hearactivity.this, Hearservice.class);
            stopService(name);


            System.out.println("service stop======");

        }
        break;
        }       
    }
}; 


private ServiceConnection mConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName className,
            IBinder service) {
        // We've bound to LocalService, cast the IBinder and get LocalService instance
        LocalBinder binder = (LocalBinder) service;
        mService = binder.getService();
        mService.Recordtrigger();

        mBound = true;
    }

    @Override
    public void onServiceDisconnected(ComponentName arg0) {
        mBound = false;
    }
};


public void Recordtrigger()
{
    Thread stopper = new Thread(new Runnable() {
        public void run() {
            try {
                Thread.sleep(10000);
                //  flag++;
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            //recorder.finish();
            // flag=1;
            stopRecording();
            // ((Button)findViewById(id.btnStart)).setEnabled(true);
            //enableButtons(false);                      
        }
    });
    stopper.start();
    //    startRecording();


    Hearactivity.this.startRecord();
}

private Handler hHandler = new Handler()
{
    @Override
    public void handleMessage(Message msg)
    {
        if(index > 0)
        {
            try
            {
                record.setText("Recording");
                index--;
                Thread.sleep(1000);
                hHandler.sendEmptyMessage(0);
            } 
            catch (InterruptedException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        else
        {
            record.setEnabled(true);
            record.setText("Record");
        }
    }
};

private static final int DEFAULT_BUFFER_INCREASE_FACTOR = 3;
public int startRecord()
{
    return startRecording(8000,
            AudioFormat.ENCODING_PCM_16BIT);
}
public int startRecording(final int sampleRate, int encoding)
{
    int bufferSize = determineMinimumBufferSize(sampleRate, encoding);
    return doRecording(sampleRate, encoding, bufferSize, bufferSize,
            DEFAULT_BUFFER_INCREASE_FACTOR);
}

private int determineMinimumBufferSize(final int sampleRate, int encoding)
{
    int minBufferSize =
            AudioRecord.getMinBufferSize(sampleRate,
                    AudioFormat.CHANNEL_IN_MONO, encoding);
    return minBufferSize;
}

public int doRecording(final int sampleRate, int encoding,
        int recordingBufferSize, int readBufferSize, 
        int bufferIncreaseFactor)
{

    byte data[] = new byte[bufferSize];

    String filename = getTempFilename();
    FileOutputStream os = null;

    try {
        os = new FileOutputStream(filename);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    if (recordingBufferSize == AudioRecord.ERROR_BAD_VALUE)
    {
        return 0;
    }
    else if (recordingBufferSize == AudioRecord.ERROR)
    {
        return 0;
    }

    // give it extra space to prevent overflow
    int increasedRecordingBufferSize = 
            recordingBufferSize * bufferIncreaseFactor;

    recorder =
            new AudioRecord(AudioSource.MIC, sampleRate,
                    AudioFormat.CHANNEL_IN_MONO, encoding,
                    increasedRecordingBufferSize);

    final short[] readBuffer = new short[readBufferSize];

    isRecording = true;


    /*System.out.println("recording"+ "recording bufferSize: "
            + increasedRecordingBufferSize 
            + " read buffer size: " + readBufferSize);*/

    //Note: possible IllegalStateException
    //if audio recording is already recording or otherwise not available
    //AudioRecord.getState() will be AudioRecord.STATE_UNINITIALIZED
    recorder.startRecording();
    int bufferResult=0;
    while (isRecording)
    {
        bufferResult = recorder.read(data, 0, readBufferSize);
        if(AudioRecord.ERROR_INVALID_OPERATION != bufferResult){
            try {

                os.write(data);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        else
        {
            //System.out.println("ERROR_INVALID_OPERATION");

        }
        System.out.println("buffer result in audio recorder===="+bufferResult);
        //in case external code stopped this while read was happening
        if ((!isRecording) )
        {
            break;
        }
        // check for error conditions
        if (bufferResult == AudioRecord.ERROR_INVALID_OPERATION)
        {
        }
        else if (bufferResult == AudioRecord.ERROR_BAD_VALUE)
        {
        }
        else
            // no errors, do processing
        {
            /*heard = clipListener.heard(readBuffer, sampleRate);

                if (heard)
                {
                    stopRecording();
                }*/
        }
    }
    try {
        os.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    done();

    return bufferResult;
}

public void done()
{
    if (recorder != null)
    {
        //recorder.stop();
        recorder.release();
        recorder = null;


    }
    UploadFile();
}
}

我的服务类:

public class Hearservice extends Service {
Hearactivity hr;
private final Handler handler = new Handler();

private final IBinder mBinder = new LocalBinder();

@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    System.out.println("SERVICE onBind=-===============");
    return mBinder;
}

public class LocalBinder extends Binder {
    public Hearservice getService() {
        // Return this instance of LocalService so clients can call public methods
        return Hearservice.this;
    }
}

public void SendData(){
    System.out.println( "Send msg"); 
}

@Override
public void onCreate() {
    // TODO Auto-generated method stub


    super.onCreate();

    //mp = MediaPlayer.create(getApplicationContext(), R.raw.song); 

    hr=new Hearactivity();

    //Recordtrigger();

    System.out.println("SERVICE onCreate=-===============");
}

@Override
public void onStart(Intent intent, int startId) {

    hr.startRecord();
    final Handler handler = new Handler();
    handler.postDelayed(new Runnable()
    {
        public void run()
        {
            hr.stopRecording();
        }
    }, 10000L);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // TODO Auto-generated method stub
    System.out.println("SERVICE onStartCommand=-===============");
    //mp.start();

    return(START_NOT_STICKY);
}

@Override
public void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();

    //mp.release();
    System.out.println("SERVICE onDestroy=-===============");
}

public void Recordtrigger()
{
    hr.startRecord();
    final Handler handler = new Handler();
    handler.postDelayed(new Runnable()
    {
        public void run()
        {
            hr.stopRecording();
        }
    }, 10000L);
}
}

我在清单中添加了服务。请帮助我理解为什么它在我的活动中运行时,但是当我从服务中调用录制方法时,它会给出ERROR_INVALID_OPERATION错误。

我的另一个问题:

我想实现:

  • 每隔10秒从背景录制声音并存储在SD卡上。

  • 存储后,我必须对此文件执行一些操作,我在应用程序的类中进行操作。

这样做的最佳方法是什么?

0 个答案:

没有答案