我正在录制音频并将其保存在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卡上。
存储后,我必须对此文件执行一些操作,我在应用程序的类中进行操作。
这样做的最佳方法是什么?