/**
* Copyright 2012 Neurowork Consulting S.L.
*
* This file is part of eMobc.
*
* AudioActivityGenerator.java
* eMobc Android Framework
*
* eMobc is free software: you can redistribute it and/or modify
* it under the terms of the Affero GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* eMobc is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the Affero GNU General Public License
* along with eMobc. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.emobc.android.activities.generators;
import java.io.IOException;
import android.app.Activity;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import com.emobc.android.ActivityType;
import com.emobc.android.NextLevel;
import com.emobc.android.activities.R;
import com.emobc.android.levels.AppLevel;
import com.emobc.android.levels.AppLevelData;
import com.emobc.android.levels.impl.AudioLevelDataItem;
import com.emobc.android.menu.CreateMenus;
import com.emobc.android.utils.ImagesUtils;
import com.emobc.android.utils.InvalidFileException;
/**
* This type of Activity plays an audio file from a remote or local URL.
*
* @author Jorge E. Villaverde
* @version 0.1
* @since 0.1
*/
public class AudioActivityGenerator extends LevelActivityGenerator {
/**
*
*/
private static final long serialVersionUID = 2972211420118350904L;
private SeekBar audioBar;
private ImageButton playPause;
private ImageButton prev;
private ImageButton next;
private MediaPlayer mp;
private Handler handler;
private AudioLevelDataItem item;
private boolean firstTime;
private Runnable notification;
private Activity activity;
public AudioActivityGenerator(AppLevel appLevel, NextLevel nextLevel){
super(appLevel, nextLevel);
firstTime = true;
}
@Override
protected void loadAppLevelData(Activity activity, AppLevelData data) {
item = (AudioLevelDataItem)data.findByNextLevel(nextLevel);
audioBar = (SeekBar) activity.findViewById(R.id.seekBarAudio);
playPause = (ImageButton) activity.findViewById(R.id.playPauseButton);
prev = (ImageButton) activity.findViewById(R.id.prevButton);
next = (ImageButton) activity.findViewById(R.id.nextButton);
mp = new MediaPlayer();
handler = new Handler();
this.activity = activity;
initializeHeader(activity, item);
//Create Banner
CreateMenus c = (CreateMenus)activity;
c.createBanner();
//Audio Image
ImageView audioImage = (ImageView) activity.findViewById(R.id.imageAudio);
if (item.getImage()!=null){
try {
audioImage.setImageDrawable(ImagesUtils.getDrawable(activity, item.getImage()));
} catch (InvalidFileException e1) {
e1.printStackTrace();
}
}
//Description
//TextView description = (TextView) activity.findViewById(R.id.description);
//Lyrics
if (item.getLyrics()!=null){
TextView lyrics = (TextView) activity.findViewById(R.id.lyrics);
lyrics.setText(item.getLyrics());
}
//Media Player
mp.setOnBufferingUpdateListener(new OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
audioBar.setSecondaryProgress(percent);
}
});
mp.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
playPause.setImageResource(R.drawable.ic_media_play);
}
});
mp.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
play();
}
});
//Button Play/Pause
playPause.setImageResource(R.drawable.ic_media_play);
playPause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
playPause();
}
});
//Button next
next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
//Button prev
prev.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mp.seekTo(0);
audioBar.setProgress(0);
}
});
//Audio Bar
audioBar.setMax(99);
audioBar.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(v.getId()==R.id.seekBarAudio){
SeekBar sb = (SeekBar)v;
int playPositionInMillisecconds = (mp.getDuration() / 100) * sb.getProgress();
mp.seekTo(playPositionInMillisecconds);
}
return false;
}
});
}
/**
* Updates primary bar progress
*/
private void primarySeekBarProgressUpdater() {
audioBar.setProgress((int)(((float)mp.getCurrentPosition()/mp.getDuration())*100)); // This math construction give a percentage of "was playing"/"song length"
if (mp.isPlaying()) {
notification = new Runnable() {
public void run() {
if (mp.isPlaying()){
primarySeekBarProgressUpdater();
}
}
};
handler.postDelayed(notification,1000);
}
}
/**
* Play music
*/
private void play(){
mp.start();
playPause.setImageResource(R.drawable.ic_media_pause);
primarySeekBarProgressUpdater();
}
/**
* Pause music
*/
private void pause(){
mp.pause();
playPause.setImageResource(R.drawable.ic_media_play);
handler.removeCallbacks(notification);
}
/**
* Method for play/pause button. If is playing, pause. Else, play.
*/
private void playPause(){
if (firstTime){
try {
if (item.isLocal()){
//the audio is in assets/audio folder
AssetFileDescriptor afd = activity.getAssets().openFd("audio/"+item.getAudioUrl());
mp.setDataSource(afd.getFileDescriptor());
}else{
mp.setDataSource(item.getAudioUrl());
}
} catch (IllegalArgumentException e) {
Log.e("AudioActivityGenerator: playPause", e.getMessage());
} catch (SecurityException e) {
Log.e("AudioActivityGenerator: playPause", e.getMessage());
} catch (IllegalStateException e) {
Log.e("AudioActivityGenerator: playPause", e.getMessage());
} catch (IOException e) {
Log.e("AudioActivityGenerator: playPause", e.getMessage());
}
mp.prepareAsync();
firstTime = false;
}else{
if(mp.isPlaying()){
pause();
}else{
play();
}
}
}
@Override
protected int getContentViewResourceId(Activity activity) {
if(appLevel.getXib() != null && appLevel.getXib().length() > 0){
int id = getActivityLayoutIdFromString(activity, appLevel.getXib());
if(id >0)
return id;
}
return R.layout.audio_layout;
}
/**
* Clear threads and mediaPlayer
*/
public void finishAudio() {
mp.release();
handler.removeCallbacks(notification);
}
public void pauseAudio() {
if (!firstTime){
if (mp.isPlaying()){
pause();
}
}
}
@Override
protected ActivityType getActivityGeneratorType() {
return ActivityType.AUDIO_ACTIVITY;
}
}