2014-09-23 3 views
1

Я новичок в Android, и я следую примеру Android AudioRecord. Целью является запись звука в файл при нажатии кнопки btnStart и остановке записи при нажатии кнопки btnStop. Код выглядит следующим образом:java.lang.NullPointerException при использовании Android AudioRecord

package com.example.blaqx.audio_record; 

import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import android.app.Activity; 
import android.media.AudioFormat; 
import android.media.AudioRecord; 
import android.media.MediaRecorder; 
import android.os.Bundle; 
import android.view.KeyEvent; 
import android.view.View; 
import android.widget.Button; 

import com.example.blaqx.audio_record.R; 

public class Audio_Record extends Activity { 
    private static final int RECORDER_SAMPLERATE = 8000; 

    private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO; 

    private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT; 

    private AudioRecord recorder = null; 
    private Thread recordingThread = null; 
    private boolean isRecording = false; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     setButtonHandlers(); 
     enableButtons(false); 

     int bufferSize = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE, 
       RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING); 
    } 

    private void setButtonHandlers() { 
     ((Button) findViewById(R.id.btnStart)).setOnClickListener(btnClick); 
     ((Button) findViewById(R.id.btnStop)).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); 
    } 

    int BufferElements2Rec = 1024; // want to play 2048 (2K) since 2 bytes we use only 1024 
    int BytesPerElement = 2; // 2 bytes in 16bit format 

    private void startRecording() { 

     recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 
       RECORDER_SAMPLERATE, RECORDER_CHANNELS, 
       RECORDER_AUDIO_ENCODING, BufferElements2Rec * BytesPerElement); 

     recorder.startRecording(); 

     isRecording = true; 

     recordingThread = new Thread(new Runnable() { 

      public void run() { 

       writeAudioDataToFile(); 

      } 
     }, "AudioRecorder Thread"); 
     recordingThread.start(); 
    } 

    //Conversion of short to byte 
    private byte[] short2byte(short[] sData) { 
     int shortArrsize = sData.length; 
     byte[] bytes = new byte[shortArrsize * 2]; 

     for (int i = 0; i < shortArrsize; i++) { 
      bytes[i * 2] = (byte) (sData[i] & 0x00FF); 
      bytes[(i * 2) + 1] = (byte) (sData[i] >> 8); 
      sData[i] = 0; 
     } 
     return bytes; 
    } 

    private void writeAudioDataToFile() { 
     // Write the output audio in byte 
     String filePath = "/sdcard/8k16bitMono.pcm"; 

     short sData[] = new short[BufferElements2Rec]; 

     FileOutputStream os = null; 
     try { 
      os = new FileOutputStream(filePath); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } 

     while (isRecording) { 
      // gets the voice output from microphone to byte format 
      recorder.read(sData, 0, BufferElements2Rec); 
      System.out.println("Short writing to file" + sData.toString()); 
      try { 
       // writes the data to file from buffer stores the voice buffer 
       byte bData[] = short2byte(sData); 

       os.write(bData, 0, BufferElements2Rec * BytesPerElement); 

      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

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

    private void stopRecording() { 
     // stops the recording activity 
     if (null != recorder) { 
      isRecording = false; 


      recorder.stop(); 
      recorder.release(); 

      recorder = null; 
      recordingThread = null; 
     } 
    } 

    private View.OnClickListener btnClick = new View.OnClickListener() { 
     public void onClick(View v) { 
      switch (v.getId()) { 
       case R.id.btnStart: { 
        enableButtons(true); 
        startRecording(); 
        break; 
       } 
       case R.id.btnStop: { 
        enableButtons(false); 
        stopRecording(); 
        break; 
       } 
      } 
     } 
    }; 

    // onClick of backbutton finishes the activity. 
    @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
     if (keyCode == KeyEvent.KEYCODE_BACK) { 
      finish(); 
     } 
     return super.onKeyDown(keyCode, event); 
    } 
} 

Я получаю следующее исключение:

java.lang.NullPointerException 
      at com.example.blaqx.audio_record.Audio_Record.writeAudioDataToFile(Audio_Record.java:118) 
      at com.example.blaqx.audio_record.Audio_Record.access$000(Audio_Record.java:23) 
      at com.example.blaqx.audio_record.Audio_Record$1.run(Audio_Record.java:77) 
      at java.lang.Thread.run(Thread.java:841) 

То, что я делаю неправильно?

Заранее спасибо.

ответ

1

Когда вы используете блок try, вы намерены разместить все, что зависит от объектов, созданных внутри него внутри блока.

Таким образом, в то время как у вас есть это:

FileOutputStream os = null; 
try { 
    os = new FileOutputStream(filePath); 
} catch (FileNotFoundException e) { 
    e.printStackTrace(); 
} 

... если os не может быть создана, она будет null при попытке разыменования его позже (что вы делаете). Проверьте правильность пути.

Вот как это может выглядеть. Вы также можете настроить close как условие finally, чтобы вы всегда гарантировали его закрытие, если оно было инициализировано.

FileOutputStream os = null; 
try { 
    os = new FileOutputStream(filePath); 
    while (isRecording) { 
     // gets the voice output from microphone to byte format 
     recorder.read(sData, 0, BufferElements2Rec); 
     System.out.println("Short writing to file" + sData.toString()); 
     try { 
      // writes the data to file from buffer stores the voice buffer 
      byte bData[] = short2byte(sData); 

      os.write(bData, 0, BufferElements2Rec * BytesPerElement); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} catch (FileNotFoundException e) { 
    e.printStackTrace(); 
} finally { 
    if(os != null) { 
     try { 
      os.close(); 
     } catch(IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

Это работало как очарование. Спасибо Макото. Еще один вопрос: в примере записывается звук в исходный файл байта ... как мне его записать, чтобы записать файл mp3 или ogg? – Wedava