我对android编程比较陌生,需要一些帮助。我正在编写一个记录音频的应用程序,但是当我运行录制代码时代码崩溃了。
以下是应用崩溃时报告的错误...
04-29 19:02:24.833 30257-30257 / com.deemo.taglist E / AudioRecordTest:prepare()失败 04-29 19:02:24.833 30257-30257 / com.deemo.taglist E / MediaRecorder:开始调用无效状态:4 04-29 19:02:24.843 30257-30257 / com.deemo.taglist E / AndroidRuntime:FATAL EXCEPTION:main java.lang.IllegalStateException 在android.media.MediaRecorder.start(Native方法) 在com.deemo.taglist.acts.BpcAct.startRecording(BpcAct.java:335) 在com.deemo.taglist.acts.BpcAct.onClick(BpcAct.java:498) 在android.view.View.performClick(View.java:4191) 在android.view.View $ PerformClick.run(View.java:17184) 在android.os.Handler.handleCallback(Handler.java:615) 在android.os.Handler.dispatchMessage(Handler.java:92) 在android.os.Looper.loop(Looper.java:137) 在android.app.ActivityThread.main(ActivityThread.java:4867) at java.lang.reflect.Method.invokeNative(Native Method) 在java.lang.reflect.Method.invoke(Method.java:511) 在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1007) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774) 在dalvik.system.NativeStart.main(本地方法)
...这里是执行录音的整个活动:
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Environment;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.wesoft.songscrapbook.mods.DataModel;
import com.wesoft.songscrapbook.R;
import com.wesoft.songscrapbook.misc.SongChords;
import com.wesoft.songscrapbook.misc.SongStruct;
import com.wesoft.songscrapbook.misc.SsbAtt;
import com.wesoft.songscrapbook.utils.BestScaler;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
public class BpcAct extends Activity implements View.OnClickListener {
BestScaler newScaler = new BestScaler();
private boolean scalingComplete = false;
SsbAtt btnAttributes = new SsbAtt();
DataModel dataModel = new DataModel();
// File ssAudioPath;
ProgressBar recordAudioGuidePB;
EditText songTitle, songLyrics;
Button startRecordBtn, stopRecordBtn, startPlaybackBtn, stopPlaybackBtn, deleteAudioBtn, defineChordsBtn, goToReviewBtn, exitToMainBtn;
TextView songDate, audioCheck, songStructure, songIntroChords, songVerseChords, songChorusChords, songBridgeChords, songOutroChords, audioGuideDuration, audioGuidePBarFill, audioGuideFilePath;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Hide the Title Bar of the Application --> Must come before setting the Layout. \\
requestWindowFeature(Window.FEATURE_NO_TITLE);
// Hide the Status Bar of Android OS --> Can also be done later. \\
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
// Now you can draw the first Layout --> HomeScreen of the Application. \\
setContentView(R.layout.act_bpc_lyt);
// Prevent the onboard keyboard from popping up automatically. \\
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
// Instantiate (or get references to) all buttons laid out in this Activity. \\
songTitle = (EditText) findViewById(R.id.song_Title_Input_ET); // Do not DELETE. Needed for the 'DataModel.java' class. \\
songLyrics = (EditText) findViewById(R.id.song_Lyrics_Input_ET); // Do not DELETE. Needed for the 'DataModel.java' class. \\
songDate = (TextView) findViewById(R.id.song_Creation_Date_TV); // Do not DELETE. Needed for the 'DataModel.java' class. \\
audioCheck = (TextView) findViewById(R.id.song_Audio_Check_TV); // Do not DELETE. Needed for the 'DataModel.java' class. \\
stopWatch = (Chronometer) findViewById(R.id.recorder_Chrono_CM); // Do not DELETE. Needed for the 'Audio Guide' recorder. \\
audioGuidePBarFill = (TextView) findViewById(R.id.audio_Guide_PBar_Fill_TV); // Do not DELETE. Needed for the 'Audio Guide' recorder. \\
audioGuideFilePath = (TextView) findViewById(R.id.audio_Guide_File_Path_TV); // Do not DELETE. Needed for the 'Audio Guide' recorder. \\
recordAudioGuidePB = (ProgressBar) findViewById(R.id.audio_Guide_Create_PB); // Do not DELETE. Needed for the 'DataModel.java' class. \\
audioGuideDuration = (TextView) findViewById(R.id.recorded_Audio_Guide_Duration_TV); // Do not DELETE. Needed for the 'Audio Guide' recorder. \\
songIntroChords = (TextView) findViewById(R.id.song_Intro_Input_TV); // Do not DELETE. Needed for the 'DataModel.java' class. \\
songVerseChords = (TextView) findViewById(R.id.song_Verse_Input_TV); // Do not DELETE. Needed for the 'DataModel.java' class. \\
songChorusChords = (TextView) findViewById(R.id.song_Chorus_Input_TV); // Do not DELETE. Needed for the 'DataModel.java' class. \\
songBridgeChords = (TextView) findViewById(R.id.song_Bridge_Input_TV); // Do not DELETE. Needed for the 'DataModel.java' class. \\
songOutroChords = (TextView) findViewById(R.id.song_Outro_Input_TV); // Do not DELETE. Needed for the 'DataModel.java' class. \\
songStructure = (TextView) findViewById(R.id.song_Structure_Input_TV); // Do not DELETE. Needed for the 'DataModel.java' class. \\
songStructure.setOnClickListener(this);
startRecordBtn = (Button) findViewById(R.id.start_Audio_Record_BTN);
startRecordBtn.setOnClickListener(this);
stopRecordBtn = (Button) findViewById(R.id.stop_Audio_Record_BTN);
stopRecordBtn.setOnClickListener(this);
startPlaybackBtn = (Button) findViewById(R.id.start_Audio_Play_BTN);
startPlaybackBtn.setOnClickListener(this);
stopPlaybackBtn = (Button) findViewById(R.id.stop_Audio_Play_BTN);
stopPlaybackBtn.setOnClickListener(this);
deleteAudioBtn = (Button) findViewById(R.id.delete_Audio_Guide_BTN);
deleteAudioBtn.setOnClickListener(this);
defineChordsBtn = (Button) findViewById(R.id.define_Song_Chords_BTN);
defineChordsBtn.setOnClickListener(this);
goToReviewBtn = (Button) findViewById(R.id.review_Song_BTN);
goToReviewBtn.setOnClickListener(this);
exitToMainBtn = (Button) findViewById(R.id.review_Close_Song_BTN);
exitToMainBtn.setOnClickListener(this);
// Deactivate all the buttons in this view by using the 'SsbAtt' class to set 'Alpha' and 'Enable' fields. \\
btnAttributes.oneButtonSetAlpha35(startPlaybackBtn);
btnAttributes.oneButtonSetAlpha35(deleteAudioBtn);
// Set the Visibility of the 'Start Audio Play' button to 'GONE'. \\
stopRecordBtn.setVisibility(View.GONE);
stopPlaybackBtn.setVisibility(View.GONE);
// Set the 'Audio Guide Progress Bar' length to 2 minutes (i.e. 120 000 milliseconds). \\
recordAudioGuidePB.setMax(120000);
// Create the main folder on the devices external storage (if available) for storing NB Song Scrapbook data. \\
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) // Check if SD card is mounted. \\
{
// Set up a reference to the directories you want to create for access by or via this Activity - for saving data to or retrieving data from. \\
File ssAudioPath = new File(Environment.getExternalStorageDirectory() + "/Song Scrapbook/Audio Guides");
if(!(ssAudioPath).exists()) { // If the directory linked to 'ssAudioPath' already exits, do nothing and simply use that as the destination folder. \\
ssAudioPath.mkdirs(); // If the directory linked to 'ssAudioPath' does not already exit...then create the directory. \\
} else;
} else;
// ---------------------------------------------------------------- Data Fetching Section - START --------------------------------------------------------------------- \\
/** Check to see if any data was passed from the previous Activity...if TRUE, then extract all data from the data bundle received **/
if(getIntent().getExtras() != null) { // Check to see if there is any data in the default Activity Data Object. \\
// Create a new bundle object and add to it the data passed from the previous activity...
Bundle dataIn = getIntent().getExtras();
// Update the relevant UI fields with the data passed from the previous activity...
dataModel.importBpcData(dataIn, songTitle, songDate, songStructure, songIntroChords, songVerseChords, songChorusChords, songBridgeChords, songOutroChords, songLyrics, audioCheck, audioGuideDuration, audioGuidePBarFill, audioGuideFilePath);
} else;
// ---------------------------------------------------------------- Data Fetching Section - END ----------------------------------------------------------------------- \\
if(audioCheck.getText().length() == 3) {
// [1] Set the file path of the 'Audio Guide' linked to this song entry. \\
agFileName = (String) audioGuideFilePath.getText();
// [2] Update the 'Audio Guide' Record ProgressBar status. \\
String getPbarFill = (String) audioGuidePBarFill.getText();
recordAudioGuidePB.setProgress(Integer.parseInt(getPbarFill));
// [3] Activate the 'Playback' and 'Delete' buttons. \\
btnAttributes.oneButtonSetAlpha100(deleteAudioBtn);
btnAttributes.oneButtonSetAlpha100(startPlaybackBtn);
// [4] Deactivate the 'Audio Record' buttons. \\
btnAttributes.oneButtonSetAlpha35(startRecordBtn);
// Toast tst = Toast.makeText(this, "Value: " + getPbarFill, Toast.LENGTH_SHORT);
// tst.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL, 0, 0);
// tst.show();
} else;
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
if (!scalingComplete) // only do this once!!
{
newScaler.scaleContents(findViewById(R.id.songCreationContents), findViewById(R.id.songCreationContainer));
scalingComplete = true;
}
super.onWindowFocusChanged(hasFocus);
}
// Called when the views have been created. We override this in order to scale the UI, which we can't do before this.
@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
View view = super.onCreateView(name, context, attrs);
return view;
}
// ----------------------------------------------------------- Audio Guide RECORD, Play and Delete Code START ------------------------------------------------------------- \\
long elapsedTimeBeforeStop;
private MediaPlayer mPlayer = null;
private MediaRecorder mRecorder = null;
private static String agFileName = null;
private final int TIMER_TICK = 1000; // Tells the TIMER to fire/tick ONCE every SECOND, decrease this to fire more frequently. \\
Timer progressBarAdvancer;
CountDownTimer recordingCountDown;
private static final String LOG_TAG = "AudioRecordTest";
// Needed for updating the recording 'Audio Guide' progress. \\
int countUp;
private Chronometer stopWatch = null; // Initialize a chronometer for count the time lapsed. \\
private int startCounter () {
stopWatch.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
@Override
public void onChronometerTick(Chronometer chrono) {
countUp = (int) ((SystemClock.elapsedRealtime() - chrono.getBase()) / 1000);
int minutes = (countUp / 60);
int seconds = (countUp % 60);
audioGuideDuration.setText(String.format("%d:%02d", minutes, seconds));
}
});
// Quickly reset the 'Counter' before starting it up again. This will ensure a clean start time everytime. \\
resetCounter();
// Start counting the time elapsed. \\
stopWatch.start();
// Start the updating of the Audio Guide recording progress bar. \\
updateAudioRecordProgress();
// Serve the 'countUp' object while the timing is in progress. \\
return countUp;
}
private void startRecordingCountDownTimer() {
recordingCountDown = new CountDownTimer(121000, 1000) {
public void onTick(long millisUntilFinished) {
// mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
// mTextField.setText("done!");
stopRecording();
}
}.start();
}
private long stopCounter () {
stopWatch.stop();
// Get an immediate reference to the current 'SystemClock' time, and log that into the 'elapsedTimeBeforeStop' time object. \\
long elapsedTimeBeforeStop = SystemClock.elapsedRealtime() - stopWatch.getBase();
return elapsedTimeBeforeStop;
}
private void stopRecordingCountDownTimer() {
// [1] Stop the 'recordingCountDown' counter. \\
recordingCountDown.cancel();
}
private void resetCounter () {
// Reset the 'stopWatch' to get a new start time. \\
stopWatch.setBase(SystemClock.elapsedRealtime() - elapsedTimeBeforeStop);
}
public void createNewAudioID() {
// Check if the 'audioGuideFilePath' hasn't already been defined and create a new file path if not already defined. \\
if(audioGuideFilePath.getText() == "") {
// [1] Create an ID for the 'Audio Guide' using the 'Song Title' of the song. \\
String songTitleWowSpace = songTitle.getText().toString().replace(" ", "");
String songIDPart1 = songTitleWowSpace.substring(0, 3); // Splice 1 - Take the first 3 characters of the 'Song Title' string. \\
String songIDPart2 = songTitleWowSpace.substring(songTitleWowSpace.length() - 3, songTitleWowSpace.length()); // Splice 2 - Take the last 3 characters of the 'Somg Title' string. \\
String songIDPart3 = songTitleWowSpace.substring(songTitleWowSpace.length()-3, songTitleWowSpace.length()-2); // Splice 3 - Take the 3rd last character of the 'Song Title' string. \\
String songID = songIDPart1 + songIDPart3 + songIDPart2 + ".3gp"; // Stitch all splices (i.e. 1, 2 & 3) together to create a new UNIQUE 'Song ID' string for the 'Audio Guide'. \\
// [2] Get a reference to the 'Audio Guide' directory for saving the audio recording to. \\
agFileName = Environment.getExternalStorageDirectory() + "/Song Scrapbook/Audio Guides";
agFileName += "/" + songID;
// [3] Set the 'audioGuideFilePath' value to that of the 'agFileName' string object. \\
audioGuideFilePath.setText(agFileName);
/**Toast tst = Toast.makeText(this, "Created: " + agFileName, Toast.LENGTH_SHORT);
tst.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL, 0, 0);
tst.show(); **/
} else;
}
private void getSongCreationDate() {
// [1] Get an instance to the System Calendar, extract current date and insert it into the 'currDate' string object. \\
Calendar cal = Calendar.getInstance();
// [2] Define a date format, apply it to the 'currDate' string and insert it into another string object (i.e. ''). \\
SimpleDateFormat dateForm = new SimpleDateFormat("dd-MMM-yy");
String songCreationDate = dateForm.format(cal.getTime());
// [3] Set the value/text of the 'songDate' to the newly created 'songCreationDate' string result. \\
songDate.setText(songCreationDate);
/** Toast tst = Toast.makeText(this, "Created: " + songCreationDate, Toast.LENGTH_SHORT);
tst.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL, 0, 0);
tst.show(); **/
}
public void startRecording() {
createNewAudioID();
// Create a new Media Recorder and get the recording process in motion. \\
mRecorder = new MediaRecorder();
mRecorder.setMaxDuration(120000);
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mRecorder.setOutputFile(agFileName);
try {
mRecorder.prepare();
}
catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
// Start audio recording. \\
mRecorder.start();
// Start the clock to time the duration of the recording. \\
startCounter();
// Start the countdown to make sure recording doesn't exceed 2 minutes. \\
startRecordingCountDownTimer();
}
public void stopRecording() {
// Stop the audio recorder timer. \\
stopCounter();
// Stop and clean the 'Audio Guide' progressbar updating process. \\
progressBarAdvancer.cancel();
progressBarAdvancer.purge();
// Stop the recorder CountDownTimer. \\
stopRecordingCountDownTimer();
mRecorder.stop();
mRecorder.release();
mRecorder = null;
// [1] Make the 'stopRecordBtn' button invisible and the 'startRecordBtn' button visible. \\
startRecordBtn.setVisibility(View.VISIBLE); // Set visibility to GONE. \\
stopRecordBtn.setVisibility(View.GONE); // Set visibility to VISIBLE. \\
// [2] Re-enable ALL other views to prevent interruption of the current Audio Process. \\
songTitle.setEnabled(true);
songLyrics.setEnabled(true);
goToReviewBtn.setEnabled(true);
exitToMainBtn.setEnabled(true);
songStructure.setEnabled(true);
defineChordsBtn.setEnabled(true);
// [3] Deactivate the 'Audio Record' button. \\
btnAttributes.oneButtonSetAlpha35(startRecordBtn);
// [4] Activate the following buttons. \\
btnAttributes.oneButtonSetAlpha100(startPlaybackBtn);
btnAttributes.oneButtonSetAlpha100(deleteAudioBtn);
btnAttributes.oneButtonSetAlpha100(goToReviewBtn);
btnAttributes.oneButtonSetAlpha100(exitToMainBtn);
// [5] Insert the 'Yes' text into the 'audioCheK' TextView. \\
audioCheck.setText("Yes");
}
public void startPlaying() {
mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(agFileName);
mPlayer.prepare();
mPlayer.start();
}
catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
}
public void stopPlaying() {
mPlayer.release();
mPlayer = null;
}
public void deleteAudioGuide() {
// [1] Create a new File object and delete the value inserted into it by the 'createNewAudioID()' function. \\
File thisAG = new File(agFileName);
thisAG.delete();
// [2] Clear the 'Audio Guide' progress bar. \\
recordAudioGuidePB.setProgress(0);
// [3] Reset the 'stopWatch' to get a new start time. \\
resetCounter();
// [4] Clear the 'Audio Guide' recording duration time. \\
audioGuideDuration.setText("0:00");
// [5] Insert the 'No' text into the 'audioCheK' TextView. \\
audioCheck.setText("No");
}
public void updateAudioRecordProgress() {
progressBarAdvancer = new Timer();
progressBarAdvancer.scheduleAtFixedRate(new TimerTask() {
public void run() {
// [1] Run the timer for every 1000 milliseconds = 1 second. \\
int runProgress = recordAudioGuidePB.getProgress() + TIMER_TICK;
recordAudioGuidePB.setProgress(runProgress);
}
},
1000, // Delay before first execution
TIMER_TICK);
}
// ------------------------------------------------------------ Audio Guide RECORD, Play and Delete Code END -------------------------------------------------------------- \\
@Override
public void onClick (View v) {
if (v.getId() == R.id.song_Structure_Input_TV) {
// Create a bundle object. \\
Bundle dataKeeper = new Bundle();
// Get the NB data and pass it to the next Activity. \\
dataModel.exportBpcData(dataKeeper, songTitle, songDate, songStructure, songIntroChords, songVerseChords, songChorusChords, songBridgeChords, songOutroChords, songLyrics, audioCheck, audioGuideDuration, recordAudioGuidePB, audioGuideFilePath);
// Start new intent to move from the current activity to the next activity...
Intent Bpc2SS = new Intent(BpcAct.this, SongStruct.class);
Bpc2SS.putExtras(dataKeeper);
startActivity(Bpc2SS);
}
else if (v.getId() == R.id.define_Song_Chords_BTN) {
// Create a bundle object. \\
Bundle dataKeeper = new Bundle();
// Get the NB data and pass it to the next Activity. \\
dataModel.exportBpcData(dataKeeper, songTitle, songDate, songStructure, songIntroChords, songVerseChords, songChorusChords, songBridgeChords, songOutroChords, songLyrics, audioCheck, audioGuideDuration, recordAudioGuidePB, audioGuideFilePath);
// Start new intent to move from the current activity to the next activity...
Intent Bpc2SC = new Intent (BpcAct.this, SongChords.class);
Bpc2SC.putExtras(dataKeeper);
startActivity(Bpc2SC);
}
else if (v.getId() == R.id.start_Audio_Record_BTN) {
if (songTitle.length() == 0) { // Check to see if the 'Song Title' EditText is empty. \\
// If the 'Song Title' is empty, then show a warning message to the user. \\
Toast tost = Toast.makeText(this, "Please create a Song Title first.", Toast.LENGTH_SHORT);
tost.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL, 0, 0);
tost.show();
}
else if (songTitle.length() <= 3) { // Check to see if the 'Song Title' EditText is shorter than 3 characters. \\
// If the 'Song Title' is empty, then show a warning message to the user. \\
Toast tost = Toast.makeText(this, "The Song Title must be longer than 3 characters.", Toast.LENGTH_SHORT);
tost.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL, 0, 0);
tost.show();
}
else if (songTitle.length() > 3) { // Check to see if the 'Song Title' EditText is longer than 3 characters. \\
// [1] Start the recording the 'Audio Guide' file for the current song. \\
startRecording();
}
}
else if (v.getId() == R.id.stop_Audio_Record_BTN) {
// [1] Deactivate the 'Audio Record' button. \\
btnAttributes.oneButtonSetAlpha35(startRecordBtn);
// [2] Activate the following buttons. \\
btnAttributes.oneButtonSetAlpha100(startPlaybackBtn);
btnAttributes.oneButtonSetAlpha100(deleteAudioBtn);
btnAttributes.oneButtonSetAlpha100(goToReviewBtn);
btnAttributes.oneButtonSetAlpha100(exitToMainBtn);
// [3] Stop the recording the 'Audio Guide' file for the current song. \\
stopRecording();
}
else if (v.getId() == R.id.start_Audio_Play_BTN) {
// [1] Start playback of the 'Audio Guide' file for the current song. \\
startPlaying();
// [2] Make the 'stopRecordBtn' button visible and make the 'startRecordBtn' button invisible. \\
stopPlaybackBtn.setVisibility(View.VISIBLE);
startPlaybackBtn.setVisibility(View.INVISIBLE);
// [3] Deactivate the 'DELETE Audio Guide' button. \\
btnAttributes.oneButtonSetAlpha35(deleteAudioBtn);
}
else if (v.getId() == R.id.stop_Audio_Play_BTN) {
// [1] Stop playback of the 'Audio Guide' file for the current song. \\
stopPlaying();
// [2] Make the 'stopRecordBtn' button visible and make the 'startRecordBtn' button invisible. \\
startPlaybackBtn.setVisibility(View.VISIBLE);
stopPlaybackBtn.setVisibility(View.GONE);
// [3] Reactivate the 'DELETE Audio Guide' button. \\
btnAttributes.oneButtonSetAlpha100(deleteAudioBtn);
}
else if (v.getId() == R.id.delete_Audio_Guide_BTN) {
// [1] Delete the relevant 'Audio Guide' file from the storage folder. \\
deleteAudioGuide();
// [2] Re-Activate the 'Record Audio' button. \\
btnAttributes.oneButtonSetAlpha100(startRecordBtn);
// [3] Deactivate the 'Delete Audio Guide' and 'Play Audio Guide' buttons. \\
btnAttributes.oneButtonSetAlpha35(deleteAudioBtn);
btnAttributes.oneButtonSetAlpha35(startPlaybackBtn);
}
else if (v.getId() == R.id.review_Song_BTN) {
// [1] Check if the 'getSongCreationDate' object is empty and insert the current date into the object. \\
if(songDate.getText().length() == 0) {
// Create a new song creation date (i.e. insert current date) by executing the 'getSongCreationDate()' function. \\
getSongCreationDate();
}else;
// [2] Create a bundle object...
Bundle dataKeeper = new Bundle();
// [3] Get the NB data and pass it to the next Activity. \\
dataModel.exportBpcData(dataKeeper, songTitle, songDate, songStructure, songIntroChords, songVerseChords, songChorusChords, songBridgeChords, songOutroChords, songLyrics, audioCheck, audioGuideDuration, recordAudioGuidePB, audioGuideFilePath);
// [4] Start new intent to move from the current activity to the next activity. \\
Intent bpc2bpr = new Intent (BpcAct.this, BprAct.class);
bpc2bpr.putExtras(dataKeeper);
startActivity(bpc2bpr);
overridePendingTransition(R.anim.slide_right_in, R.anim.slide_left_out);
}
else if (v.getId() == R.id.review_Close_Song_BTN) {
Intent bpc2main = new Intent (BpcAct.this, MainAct.class);
bpc2main.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(bpc2main);
overridePendingTransition(R.anim.slide_right_out, R.anim.slide_left_in);
}
}
@Override
public void onBackPressed() {
super.onBackPressed();
overridePendingTransition(R.anim.slide_right_out, R.anim.slide_left_in);
}
}
我一直在努力解决这个问题,我真的不知道问题出在哪里。奇怪的事情,我有两个物理设备(Galaxy Mega 6.3和Galaxy X-Cover 2),我不时地测试应用程序。该应用程序似乎在Mega 6.3(运行Android 4.2.2)上正常运行,但每次我在X-cover 2(运行Android 4.1.2)上运行它时都会崩溃。注意问题也只有在我按下录音按钮时才会发生。任何帮助都感激不尽。
答案 0 :(得分:1)
我不确定mRecorder有什么问题,但我通常使用AudioRecord对象来录制音频而不是完整的MediaRecorder,这可能会比录制音频更多。无论哪种方式,请查看AudioRecord http://developer.android.com/reference/android/media/AudioRecord.html的android开发页面,希望有所帮助。
P.S。在媒体记录器http://developer.android.com/images/mediarecorder_state_diagram.gif的状态下找到此图表 如果您不喜欢AudioRecord,此图表可以帮助您调试MediaRecorder处于无效状态的位置
答案 1 :(得分:1)
private void startRecord(){
File file = new File(Environment.getExternalStorageDirectory(), "test.pcm");
try {
file.createNewFile();
recording=true;
OutputStream outputStream = new FileOutputStream(file);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream);
int minBufferSize = AudioRecord.getMinBufferSize(44100,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
short[] audioData = new short[minBufferSize];
AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
44100,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
minBufferSize);
//int sessionId=audioRecord.getAudioSessionId();
// NoiseSuppressor.create(sessionId);
audioRecord.startRecording();
while(recording){
int numberOfShort = audioRecord.read(audioData, 0, minBufferSize);
for(int i = 0; i < numberOfShort; i++){
dataOutputStream.writeShort(audioData[i]);
}
}
audioRecord.stop();
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
这里使用此功能将原始记录数据(PCM)保存在外部目录中。你应该使用AudioTrack对象播放这个录音。