Commit 490f459f authored by Katie Laverty's avatar Katie Laverty

Updates for the Player component

parent d89d9325
...@@ -688,6 +688,13 @@ public final class YoungAndroidFormUpgrader { ...@@ -688,6 +688,13 @@ public final class YoungAndroidFormUpgrader {
// No properties need to be modified to upgrade to version 3. // No properties need to be modified to upgrade to version 3.
srcCompVersion = 3; srcCompVersion = 3;
} }
if (srcCompVersion <4) {
// The Looping and Volume properties were added.
// The Completed Event was added.
// The IsPlaying method was added.
// No properties need to be modified to upgrade to version 4.
srcCompVersion = 4;
}
return srcCompVersion; return srcCompVersion;
} }
......
...@@ -850,6 +850,13 @@ public class BlockSaveFile { ...@@ -850,6 +850,13 @@ public class BlockSaveFile {
} }
blkCompVersion = 3; blkCompVersion = 3;
} }
if (blkCompVersion < 4) {
// The Looping and Volume properties were added.
// The Completed Event was added.
// The IsPlaying method was added.
// No properties need to be modified to upgrade to version 4.
blkCompVersion = 4;
}
return blkCompVersion; return blkCompVersion;
} }
......
...@@ -170,8 +170,10 @@ public class YaVersion { ...@@ -170,8 +170,10 @@ public class YaVersion {
// - PHONENUMBERPICKER_COMPONENT_VERSION was incremented to 4. // - PHONENUMBERPICKER_COMPONENT_VERSION was incremented to 4.
// For YOUNG_ANDROID_VERSION 55: // For YOUNG_ANDROID_VERSION 55:
// - ACCELEROMETERSENSOR_COMPONENT_VERSION was incremented to 2. // - ACCELEROMETERSENSOR_COMPONENT_VERSION was incremented to 2.
// For YOUNG_ANDROID_VERSION 56:
// - PLAYER_COMPONENT_VERSION was incremented to 4.
public static final int YOUNG_ANDROID_VERSION = 55; public static final int YOUNG_ANDROID_VERSION = 56;
// ............................... Blocks Language Version Number ............................... // ............................... Blocks Language Version Number ...............................
...@@ -419,7 +421,13 @@ public class YaVersion { ...@@ -419,7 +421,13 @@ public class YaVersion {
// - The Player.PlayerError event was added. // - The Player.PlayerError event was added.
// For PLAYER_COMPONENT_VERSION 3: // For PLAYER_COMPONENT_VERSION 3:
// - The Player.PlayerError event was marked userVisible false and is no longer used. // - The Player.PlayerError event was marked userVisible false and is no longer used.
public static final int PLAYER_COMPONENT_VERSION = 3; // For PLAYER_COMPONENT_VERSION 4:
// - The Player.Completed event was added.
// - The IsLooping property was added.
// - The Volume property was added.
// - The IsPlaying method was added.
public static final int PLAYER_COMPONENT_VERSION = 4;
// For SOUND_COMPONENT_VERSION 2: // For SOUND_COMPONENT_VERSION 2:
// - The Sound.SoundError event was added. // - The Sound.SoundError event was added.
......
...@@ -13,17 +13,21 @@ import com.google.appinventor.components.annotations.UsesPermissions; ...@@ -13,17 +13,21 @@ import com.google.appinventor.components.annotations.UsesPermissions;
import com.google.appinventor.components.common.ComponentCategory; import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.common.PropertyTypeConstants; import com.google.appinventor.components.common.PropertyTypeConstants;
import com.google.appinventor.components.common.YaVersion; import com.google.appinventor.components.common.YaVersion;
import com.google.appinventor.components.runtime.errors.IllegalArgumentError;
import com.google.appinventor.components.runtime.util.ErrorMessages; import com.google.appinventor.components.runtime.util.ErrorMessages;
import com.google.appinventor.components.runtime.util.MediaUtil; import com.google.appinventor.components.runtime.util.MediaUtil;
import android.content.Context; import android.content.Context;
import android.media.AudioManager; import android.media.AudioManager;
import android.media.MediaPlayer; import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Vibrator; import android.os.Vibrator;
import android.util.Log; import android.util.Log;
import java.io.IOException; import java.io.IOException;
//import openblocks.yacodeblocks.FeedbackReporter;
// TODO: This implementation does nothing about releasing the Media // TODO: This implementation does nothing about releasing the Media
// Player resources when the application stops. This needs to be handled // Player resources when the application stops. This needs to be handled
// at the application level, not just at the component level. // at the application level, not just at the component level.
...@@ -65,7 +69,7 @@ import java.io.IOException; ...@@ -65,7 +69,7 @@ import java.io.IOException;
@SimpleObject @SimpleObject
@UsesPermissions(permissionNames = "android.permission.VIBRATE, android.permission.INTERNET") @UsesPermissions(permissionNames = "android.permission.VIBRATE, android.permission.INTERNET")
public final class Player extends AndroidNonvisibleComponent public final class Player extends AndroidNonvisibleComponent
implements Component, OnDestroyListener, Deleteable { implements Component, OnCompletionListener, OnDestroyListener, Deleteable {
private MediaPlayer mp; private MediaPlayer mp;
private final Vibrator vibe; private final Vibrator vibe;
...@@ -137,6 +141,7 @@ public final class Player extends AndroidNonvisibleComponent ...@@ -137,6 +141,7 @@ public final class Player extends AndroidNonvisibleComponent
if (sourcePath.length() > 0) { if (sourcePath.length() > 0) {
Log.i("Player", "Source path is " + sourcePath); Log.i("Player", "Source path is " + sourcePath);
mp = new MediaPlayer(); mp = new MediaPlayer();
mp.setOnCompletionListener(this);
try { try {
MediaUtil.loadMediaPlayer(mp, form, sourcePath); MediaUtil.loadMediaPlayer(mp, form, sourcePath);
...@@ -158,9 +163,72 @@ public final class Player extends AndroidNonvisibleComponent ...@@ -158,9 +163,72 @@ public final class Player extends AndroidNonvisibleComponent
// Player should now be in state 1. (If prepare failed, we are in state 0.) // Player should now be in state 1. (If prepare failed, we are in state 0.)
} }
} }
/**
* Returns a boolean which tells if the media is playing.
*/
@SimpleProperty(
description = "Whether the media is playing",
category = PropertyCategory.BEHAVIOR)
public boolean IsPlaying() {
if (playerState == 1 || playerState == 2) {
return mp.isPlaying();
}
return false;
}
/**
* Returns a boolean which tells if the media is looping.
*/
@SimpleProperty(
description = "Whether the media is looping",
category = PropertyCategory.BEHAVIOR)
public boolean IsLooping() {
if (playerState == 1 || playerState == 2) {
return mp.isLooping();
}
return false;
}
/**
* Sets the looping property to true or false.
*
* @param looping tells if the media should be looping
*/
@DesignerProperty(
editorType = PropertyTypeConstants.PROPERTY_TYPE_BOOLEAN,
defaultValue = "False")
@SimpleProperty
public void IsLooping(boolean looping) {
if (playerState == 1 || playerState == 2) {
mp.setLooping(looping);
Log.i("Player", "Looping is " + String.valueOf(looping));
}
}
/**
* Sets the volume property to a number between 0 and 100.
*
* @param vol the desired volume level
*/
@DesignerProperty(
editorType = PropertyTypeConstants.PROPERTY_TYPE_NON_NEGATIVE_FLOAT,
defaultValue = "50")
@SimpleProperty(
description = "Sets the volume to a number between 0 and 100")
public void Volume(int vol) {
if (playerState == 1 || playerState == 2) {
if (vol > 100 || vol < 0) {
throw new IllegalArgumentError("Volume must be set to a number between 0 and 100");
}
mp.setVolume(((float) vol)/100, ((float) vol)/100);
Log.i("Player", "Volume is " + String.valueOf(vol));
}
}
/** /**
* Plays the media. If it was previously paused, the playing is resumed. * Plays the media. If it was previously paused, the playing is resumed.
* If it was previously stopped, it starts from the beginning.
*/ */
@SimpleFunction @SimpleFunction
public void Start() { public void Start() {
...@@ -186,7 +254,7 @@ public final class Player extends AndroidNonvisibleComponent ...@@ -186,7 +254,7 @@ public final class Player extends AndroidNonvisibleComponent
} }
/** /**
* Stops playing the media * Stops playing the media and seeks to the beginning of the song.
*/ */
@SimpleFunction @SimpleFunction
public void Stop() { public void Stop() {
...@@ -194,6 +262,7 @@ public final class Player extends AndroidNonvisibleComponent ...@@ -194,6 +262,7 @@ public final class Player extends AndroidNonvisibleComponent
if (playerState == 1 || playerState == 2) { if (playerState == 1 || playerState == 2) {
mp.stop(); mp.stop();
prepare(); prepare();
mp.seekTo(0);
// Player should now be in state 1. (If prepare failed, we are in state 0.) // Player should now be in state 1. (If prepare failed, we are in state 0.)
} }
} }
...@@ -229,7 +298,23 @@ public final class Player extends AndroidNonvisibleComponent ...@@ -229,7 +298,23 @@ public final class Player extends AndroidNonvisibleComponent
ErrorMessages.ERROR_UNABLE_TO_PREPARE_MEDIA, sourcePath); ErrorMessages.ERROR_UNABLE_TO_PREPARE_MEDIA, sourcePath);
} }
} }
// OnCompletionListener implementation
@Override
public void onCompletion(MediaPlayer m) {
Completed();
}
/**
* Indicates that the media has reached the end
*/
@SimpleEvent
public void Completed() {
Log.i("Player", "Calling Completed -- State=" + playerState);
EventDispatcher.dispatchEvent(this, "Completed");
}
// OnDestroyListener implementation // OnDestroyListener implementation
@Override @Override
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment