You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by bo...@apache.org on 2012/07/12 23:44:09 UTC
[3/14] android commit: Working with Lorin's change
Working with Lorin's change
Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/commit/c030770b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/tree/c030770b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/diff/c030770b
Branch: refs/heads/master
Commit: c030770be741606388b32ce5f154580e672198a6
Parents: b97748d 3ea72e5
Author: Joe Bowser <bo...@apache.org>
Authored: Tue Jul 10 14:37:26 2012 -0700
Committer: Joe Bowser <bo...@apache.org>
Committed: Tue Jul 10 14:37:26 2012 -0700
----------------------------------------------------------------------
framework/src/org/apache/cordova/AudioHandler.java | 25 +-
framework/src/org/apache/cordova/AudioPlayer.java | 402 +++++++++------
2 files changed, 259 insertions(+), 168 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/c030770b/framework/src/org/apache/cordova/AudioHandler.java
----------------------------------------------------------------------
diff --cc framework/src/org/apache/cordova/AudioHandler.java
index 492043b,c4e3063..3b92fe5
mode 100755,100644..100644
--- a/framework/src/org/apache/cordova/AudioHandler.java
+++ b/framework/src/org/apache/cordova/AudioHandler.java
http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/c030770b/framework/src/org/apache/cordova/AudioPlayer.java
----------------------------------------------------------------------
diff --cc framework/src/org/apache/cordova/AudioPlayer.java
index 5df00f9,14645b2..4f72fd0
mode 100755,100644..100644
--- a/framework/src/org/apache/cordova/AudioPlayer.java
+++ b/framework/src/org/apache/cordova/AudioPlayer.java
@@@ -41,15 -43,20 +43,20 @@@ import org.apache.cordova.AudioPlayer.M
* sdcard: file name is just sound.mp3
*/
public class AudioPlayer implements OnCompletionListener, OnPreparedListener, OnErrorListener {
-
- private static final String LOG_TAG = "AudioPlayer";
-
-
- // AudioPlayer modes
- public enum MODE { NONE, PLAY, RECORD };
-
- // AudioPlayer states
- public enum STATE { MEDIA_NONE,
- MEDIA_LOADING,
- MEDIA_STARTING,
- MEDIA_RUNNING,
- MEDIA_PAUSED,
- MEDIA_STOPPED
- };
-
++
++ // AudioPlayer modes
++ public enum MODE { NONE, PLAY, RECORD };
++
+ // AudioPlayer states
- public static int MEDIA_NONE = 0;
- public static int MEDIA_STARTING = 1;
- public static int MEDIA_RUNNING = 2;
- public static int MEDIA_PAUSED = 3;
- public static int MEDIA_STOPPED = 4;
++ public enum STATE { MEDIA_NONE,
++ MEDIA_LOADING,
++ MEDIA_STARTING,
++ MEDIA_RUNNING,
++ MEDIA_PAUSED,
++ MEDIA_STOPPED
++ };
++
+ private static final String LOG_TAG = "AudioPlayer";
// AudioPlayer message ids
private static int MEDIA_STATE = 1;
@@@ -64,17 -71,20 +71,20 @@@
private static int MEDIA_ERR_DECODE = 3;
private static int MEDIA_ERR_NONE_SUPPORTED = 4;
- private AudioHandler handler; // The AudioHandler object
- private String id; // The id of this player (used to identify Media object in JavaScript)
- private int state = MEDIA_NONE; // State of recording or playback
- private String audioFile = null; // File name to play or record to
- private float duration = -1; // Duration of audio
-
- private MediaRecorder recorder = null; // Audio recording object
- private String tempFile = null; // Temporary recording file name
+ private AudioHandler handler; // The AudioHandler object
+ private String id; // The id of this player (used to identify Media object in JavaScript)
- private MODE mode = MODE.NONE; // Playback or Recording mode
++ private MODE mode = MODE.NONE; // Playback or Recording mode
+ private STATE state = STATE.MEDIA_NONE; // State of recording or playback
+
+ private String audioFile = null; // File name to play or record to
+ private float duration = -1; // Duration of audio
+
+ private MediaRecorder recorder = null; // Audio recording object
+ private String tempFile = null; // Temporary recording file name
- private MediaPlayer mPlayer = null; // Audio player object
- private boolean prepareOnly = false;
+ private MediaPlayer player = null; // Audio player object
- private boolean prepareOnly = true; // playback after file prepare flag
- private int seekOnPrepared = 0; // seek to this location once media is prepared
++ private boolean prepareOnly = true; // playback after file prepare flag
++ private int seekOnPrepared = 0; // seek to this location once media is prepared
/**
* Constructor.
@@@ -82,14 -92,17 +92,17 @@@
* @param handler The audio handler object
* @param id The id of this audio player
*/
- public AudioPlayer(AudioHandler handler, String id) {
+ public AudioPlayer(AudioHandler handler, String id, String file) {
this.handler = handler;
this.id = id;
- this.audioFile = file;
++ this.audioFile = file;
+
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
this.tempFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/tmprecording.mp3";
} else {
- this.tempFile = "/data/data/" + handler.ctx.getActivity().getPackageName() + "/cache/tmprecording.mp3";
+ this.tempFile = "/data/data/" + handler.cordova.getActivity().getPackageName() + "/cache/tmprecording.mp3";
}
+
}
/**
@@@ -118,34 -131,37 +131,37 @@@
* @param file The name of the file
*/
public void startRecording(String file) {
- if (this.mPlayer != null) {
- switch (this.mode) {
- case PLAY:
- Log.d(LOG_TAG, "AudioPlayer Error: Can't record in play mode.");
++ switch (this.mode) {
++ case PLAY:
+ Log.d(LOG_TAG, "AudioPlayer Error: Can't record in play mode.");
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});");
- }
- // Make sure we're not already recording
- else if (this.recorder == null) {
- this.audioFile = file;
- this.recorder = new MediaRecorder();
- this.recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
- this.recorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); // THREE_GPP);
- this.recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); //AMR_NB);
- this.recorder.setOutputFile(this.tempFile);
- try {
- this.recorder.prepare();
- this.recorder.start();
- this.setState(MEDIA_RUNNING);
- return;
- } catch (IllegalStateException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
+ break;
- case NONE:
- // Make sure we're not already recording
- if (this.recorder == null) {
- this.audioFile = file;
- this.recorder = new MediaRecorder();
- this.recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
- this.recorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); // THREE_GPP);
- this.recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); //AMR_NB);
- this.recorder.setOutputFile(this.tempFile);
- try {
- this.recorder.prepare();
- this.recorder.start();
- this.setState(STATE.MEDIA_RUNNING);
- return;
- } catch (IllegalStateException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});");
- }
- break;
- case RECORD:
- Log.d(LOG_TAG, "AudioPlayer Error: Already recording.");
- this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});");
- }
++ case NONE:
++ // Make sure we're not already recording
++ if (this.recorder == null) {
++ this.audioFile = file;
++ this.recorder = new MediaRecorder();
++ this.recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
++ this.recorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); // THREE_GPP);
++ this.recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); //AMR_NB);
++ this.recorder.setOutputFile(this.tempFile);
++ try {
++ this.recorder.prepare();
++ this.recorder.start();
++ this.setState(STATE.MEDIA_RUNNING);
++ return;
++ } catch (IllegalStateException e) {
++ e.printStackTrace();
++ } catch (IOException e) {
++ e.printStackTrace();
++ }
++ this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});");
+ }
- this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});");
- }
- else {
++ break;
++ case RECORD:
+ Log.d(LOG_TAG, "AudioPlayer Error: Already recording.");
+ this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});");
+ }
}
/**
@@@ -189,87 -209,27 +209,27 @@@
* @param file The name of the audio file.
*/
public void startPlaying(String file) {
- if (this.recorder != null) {
- Log.d(LOG_TAG, "AudioPlayer Error: Can't play in record mode.");
- this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});");
- }
-
- // If this is a new request to play audio, or stopped
- else if ((this.mPlayer == null) || (this.state == MEDIA_STOPPED)) {
- try {
- // If stopped, then reset player
- if (this.mPlayer != null) {
- this.mPlayer.reset();
- }
- // Otherwise, create a new one
- else {
- this.mPlayer = new MediaPlayer();
- }
- this.audioFile = file;
-
- // If streaming file
- if (this.isStreaming(file)) {
- this.mPlayer.setDataSource(file);
- this.mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
- this.setState(MEDIA_STARTING);
- this.mPlayer.setOnPreparedListener(this);
- this.mPlayer.prepareAsync();
- }
-
- // If local file
- else {
- if (file.startsWith("/android_asset/")) {
- String f = file.substring(15);
- android.content.res.AssetFileDescriptor fd = this.handler.cordova.getActivity().getAssets().openFd(f);
- this.mPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
- }
- else {
- File fp = new File(file);
- if (fp.exists()) {
- FileInputStream fileInputStream = new FileInputStream(file);
- this.mPlayer.setDataSource(fileInputStream.getFD());
- }
- else {
- this.mPlayer.setDataSource("/sdcard/" + file);
- }
- }
- this.setState(MEDIA_STARTING);
- this.mPlayer.setOnPreparedListener(this);
- this.mPlayer.prepare();
-
- // Get duration
- this.duration = getDurationInSeconds();
- }
- } catch (Exception e) {
- e.printStackTrace();
- this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});");
- }
- }
-
- // If we have already have created an audio player
- else {
-
- // If player has been paused, then resume playback
- if ((this.state == MEDIA_PAUSED) || (this.state == MEDIA_STARTING)) {
- this.mPlayer.start();
- this.setState(MEDIA_RUNNING);
- }
- else {
- Log.d(LOG_TAG, "AudioPlayer Error: startPlaying() called during invalid state: " + this.state);
- this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});");
- }
- if (this.readyPlayer(file)) {
- this.player.start();
- this.setState(STATE.MEDIA_RUNNING);
- } else {
- //
- this.prepareOnly = false;
- }
++ if (this.readyPlayer(file)) {
++ this.player.start();
++ this.setState(STATE.MEDIA_RUNNING);
++ } else {
++ //
++ this.prepareOnly = false;
+ }
}
/**
* Seek or jump to a new time in the track.
*/
public void seekToPlaying(int milliseconds) {
- if (this.mPlayer != null) {
- this.mPlayer.seekTo(milliseconds);
- if (this.readyPlayer(this.audioFile)) {
++ if (this.readyPlayer(this.audioFile)) {
+ this.player.seekTo(milliseconds);
Log.d(LOG_TAG, "Send a onStatus update for the new seek");
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_POSITION + ", " + milliseconds / 1000.0f + ");");
}
- else {
- this.seekOnPrepared = milliseconds;
- }
++ else {
++ this.seekOnPrepared = milliseconds;
++ }
}
/**
@@@ -377,29 -337,28 +337,28 @@@
/**
* Callback to be invoked when the media source is ready for playback.
*
- * @param mPlayer The MediaPlayer that is ready for playback
+ * @param player The MediaPlayer that is ready for playback
*/
- public void onPrepared(MediaPlayer mPlayer) {
+ public void onPrepared(MediaPlayer player) {
// Listen for playback completion
- this.mPlayer.setOnCompletionListener(this);
-
+ this.player.setOnCompletionListener(this);
// If start playing after prepared
if (!this.prepareOnly) {
-
- // Start playing
- this.mPlayer.start();
-
- // Set player init flag
- this.setState(MEDIA_RUNNING);
+ this.player.start();
+ this.setState(STATE.MEDIA_RUNNING);
+ } else {
- this.setState(STATE.MEDIA_STARTING);
++ this.setState(STATE.MEDIA_STARTING);
}
-
// Save off duration
this.duration = getDurationInSeconds();
- this.prepareOnly = false;
-
+ // reset prepare only flag
+ this.prepareOnly = true;
+ // seek to any location received while not prepared
+ this.seekToPlaying(this.seekOnPrepared);
+ // reset seek location
+ this.seekOnPrepared = 0;
// Send status notification to JavaScript
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_DURATION + "," + this.duration + ");");
-
}
/**
@@@ -445,6 -403,19 +403,19 @@@
}
/**
+ * Set the mode and send it to JavaScript.
+ *
+ * @param state
+ */
+ private void setMode(MODE mode) {
+ if (this.mode != mode) {
- //mode is not part of the expected behaviour, so no notification
++ //mode is not part of the expected behaviour, so no notification
+ //this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_STATE + ", " + mode + ");");
+ }
+ this.mode = mode;
+ }
+
+ /**
* Get the audio state.
*
* @return int
@@@ -459,6 -430,121 +430,121 @@@
* @param volume
*/
public void setVolume(float volume) {
- this.mPlayer.setVolume(volume, volume);
+ this.player.setVolume(volume, volume);
+ }
+
+ /**
+ * attempts to put the player in play mode
+ * @return true if in playmode, false otherwise
+ */
+ private boolean playMode() {
- switch(this.mode) {
- case NONE:
- this.setMode(MODE.PLAY);
- break;
- case PLAY:
- break;
- case RECORD:
++ switch(this.mode) {
++ case NONE:
++ this.setMode(MODE.PLAY);
++ break;
++ case PLAY:
++ break;
++ case RECORD:
+ Log.d(LOG_TAG, "AudioPlayer Error: Can't play in record mode.");
+ this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});");
+ return false; //player is not ready
- }
- return true;
++ }
++ return true;
+ }
+
+ /**
+ * attempts to initialize the media player for playback
+ * @param file the file to play
+ * @return false if player not ready, reports if in wrong mode or state
+ */
+ private boolean readyPlayer(String file) {
- if (playMode()) {
- switch (this.state) {
- case MEDIA_NONE:
- if (this.player == null) {
- this.player = new MediaPlayer();
- }
- try {
- this.loadAudioFile(file);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return false;
- case MEDIA_LOADING:
- //cordova js is not aware of MEDIA_LOADING, so we send MEDIA_STARTING insntead
- Log.d(LOG_TAG, "AudioPlayer Loading: startPlaying() called during media preparation: " + STATE.MEDIA_STARTING.ordinal());
- this.prepareOnly = false;
- return false;
- case MEDIA_STARTING:
- case MEDIA_RUNNING:
- case MEDIA_PAUSED:
- return true;
- case MEDIA_STOPPED:
- //if we are readying the same file
- if (this.audioFile.compareTo(file) == 0) {
- //reset the audio file
- player.seekTo(0);
- player.pause();
- return true;
- } else {
- //reset the player
- this.player.reset();
- try {
- this.loadAudioFile(file);
- } catch (Exception e) {
- e.printStackTrace();
- this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});");
- }
- //if we had to prepare= the file, we won't be in the correct state for playback
- return false;
- }
- default:
- Log.d(LOG_TAG, "AudioPlayer Error: startPlaying() called during invalid state: " + this.state);
- this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});");
- }
- }
- return false;
++ if (playMode()) {
++ switch (this.state) {
++ case MEDIA_NONE:
++ if (this.player == null) {
++ this.player = new MediaPlayer();
++ }
++ try {
++ this.loadAudioFile(file);
++ } catch (Exception e) {
++ e.printStackTrace();
++ }
++ return false;
++ case MEDIA_LOADING:
++ //cordova js is not aware of MEDIA_LOADING, so we send MEDIA_STARTING insntead
++ Log.d(LOG_TAG, "AudioPlayer Loading: startPlaying() called during media preparation: " + STATE.MEDIA_STARTING.ordinal());
++ this.prepareOnly = false;
++ return false;
++ case MEDIA_STARTING:
++ case MEDIA_RUNNING:
++ case MEDIA_PAUSED:
++ return true;
++ case MEDIA_STOPPED:
++ //if we are readying the same file
++ if (this.audioFile.compareTo(file) == 0) {
++ //reset the audio file
++ player.seekTo(0);
++ player.pause();
++ return true;
++ } else {
++ //reset the player
++ this.player.reset();
++ try {
++ this.loadAudioFile(file);
++ } catch (Exception e) {
++ e.printStackTrace();
++ this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});");
++ }
++ //if we had to prepare= the file, we won't be in the correct state for playback
++ return false;
++ }
++ default:
++ Log.d(LOG_TAG, "AudioPlayer Error: startPlaying() called during invalid state: " + this.state);
++ this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});");
++ }
++ }
++ return false;
+ }
+
- /**
- * load audio file
- * @throws IOException
- * @throws IllegalStateException
- * @throws SecurityException
- * @throws IllegalArgumentException
- */
- private void loadAudioFile(String file) throws IllegalArgumentException, SecurityException, IllegalStateException, IOException {
- if (this.isStreaming(file)) {
- this.player.setDataSource(file);
- this.player.setAudioStreamType(AudioManager.STREAM_MUSIC);
- //if it's a streaming file, play mode is implied
- this.setMode(MODE.PLAY);
- this.setState(STATE.MEDIA_STARTING);
- this.player.setOnPreparedListener(this);
- this.player.prepareAsync();
- }
- else {
- if (file.startsWith("/android_asset/")) {
- String f = file.substring(15);
- android.content.res.AssetFileDescriptor fd = this.handler.ctx.getActivity().getAssets().openFd(f);
++ /**
++ * load audio file
++ * @throws IOException
++ * @throws IllegalStateException
++ * @throws SecurityException
++ * @throws IllegalArgumentException
++ */
++ private void loadAudioFile(String file) throws IllegalArgumentException, SecurityException, IllegalStateException, IOException {
++ if (this.isStreaming(file)) {
++ this.player.setDataSource(file);
++ this.player.setAudioStreamType(AudioManager.STREAM_MUSIC);
++ //if it's a streaming file, play mode is implied
++ this.setMode(MODE.PLAY);
++ this.setState(STATE.MEDIA_STARTING);
++ this.player.setOnPreparedListener(this);
++ this.player.prepareAsync();
++ }
++ else {
++ if (file.startsWith("/android_asset/")) {
++ String f = file.substring(15);
++ android.content.res.AssetFileDescriptor fd = this.handler.ctx.getActivity().getAssets().openFd(f);
+ this.player.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
- }
++ }
+ else {
- File fp = new File(file);
++ File fp = new File(file);
+ if (fp.exists()) {
+ FileInputStream fileInputStream = new FileInputStream(file);
+ this.player.setDataSource(fileInputStream.getFD());
+ }
+ else {
- this.player.setDataSource("/sdcard/" + file);
++ this.player.setDataSource("/sdcard/" + file);
+ }
+ }
- this.setState(STATE.MEDIA_STARTING);
- this.player.setOnPreparedListener(this);
- this.player.prepare();
-
- // Get duration
- this.duration = getDurationInSeconds();
- }
- }
++ this.setState(STATE.MEDIA_STARTING);
++ this.player.setOnPreparedListener(this);
++ this.player.prepare();
++
++ // Get duration
++ this.duration = getDurationInSeconds();
++ }
+ }
}