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 {
// No properties need to be modified to upgrade to version 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;
}
......
......@@ -850,6 +850,13 @@ public class BlockSaveFile {
}
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;
}
......
......@@ -170,8 +170,10 @@ public class YaVersion {
// - PHONENUMBERPICKER_COMPONENT_VERSION was incremented to 4.
// For YOUNG_ANDROID_VERSION 55:
// - 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 ...............................
......@@ -419,7 +421,13 @@ public class YaVersion {
// - The Player.PlayerError event was added.
// For PLAYER_COMPONENT_VERSION 3:
// - 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:
// - The Sound.SoundError event was added.
......
......@@ -13,17 +13,21 @@ import com.google.appinventor.components.annotations.UsesPermissions;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.common.PropertyTypeConstants;
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.MediaUtil;
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Vibrator;
import android.util.Log;
import java.io.IOException;
//import openblocks.yacodeblocks.FeedbackReporter;
// TODO: This implementation does nothing about releasing the Media
// Player resources when the application stops. This needs to be handled
// at the application level, not just at the component level.
......@@ -65,7 +69,7 @@ import java.io.IOException;
@SimpleObject
@UsesPermissions(permissionNames = "android.permission.VIBRATE, android.permission.INTERNET")
public final class Player extends AndroidNonvisibleComponent
implements Component, OnDestroyListener, Deleteable {
implements Component, OnCompletionListener, OnDestroyListener, Deleteable {
private MediaPlayer mp;
private final Vibrator vibe;
......@@ -137,6 +141,7 @@ public final class Player extends AndroidNonvisibleComponent
if (sourcePath.length() > 0) {
Log.i("Player", "Source path is " + sourcePath);
mp = new MediaPlayer();
mp.setOnCompletionListener(this);
try {
MediaUtil.loadMediaPlayer(mp, form, sourcePath);
......@@ -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.)
}
}
/**
* 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.
* If it was previously stopped, it starts from the beginning.
*/
@SimpleFunction
public void Start() {
......@@ -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
public void Stop() {
......@@ -194,6 +262,7 @@ public final class Player extends AndroidNonvisibleComponent
if (playerState == 1 || playerState == 2) {
mp.stop();
prepare();
mp.seekTo(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
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
@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