I am using hourglass library for a countdown. Lets say 5 minutes. During that time i am playing the same 5 audio files over and over. This is working great. The problem is with the pause. When its on the first audio. It pauses and resumes just fine. After it gets to the next song, and i pause it, it throws a IllegalStateException.
The code is a bit ugly. In onCompletion it keeps playing the files until it gets to the end. Then i call playAudio() and the cycle starts over until the hour glass has reached zero.
pause.setOnClickListener(new View.OnClickListener() is a floating action button and i toggle between pause icon and play icon
Java Class code
tracks[0] = R.raw.audio0;
tracks[1] = R.raw.audio1;
tracks[2] = R.raw.audio2;
tracks[3] = R.raw.audio3;
tracks[4] = R.raw.audio4;
countDown = (TextView) findViewById(R.id.txtCountdown);
cancel = (FloatingActionButton)findViewById(R.id.cancelMeditation);
pause = (FloatingActionButton)findViewById(R.id.pauseMeditation);
Intent intent = getIntent();
check = intent.getIntExtra("DURATION", -1);
milliseconds = check * 60000;
countDown.setText("" + String.format("%d min",
TimeUnit.MILLISECONDS.toMinutes(milliseconds)));
pause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(hourglass == null){
startTimer(milliseconds);
currentTrack = 0;
isTimerDone = false;
playAudio();
pause.setImageResource(R.drawable.ic_pause);
return;
}
if(hourglass.isPaused()){
hourglass.resumeTimer();
pause.setImageResource(R.drawable.ic_pause);
isPaused = false;
mediaAffyPlayer.seekTo(length);
mediaAffyPlayer.start();
}else if(hourglass.isRunning()){
hourglass.pauseTimer();
pause.setImageResource(R.drawable.ic_play1);
isPaused = true;
if(mediaAffyPlayer != null) {
mediaAffyPlayer.pause();
length = mediaAffyPlayer.getCurrentPosition();
}
} else{
startTimer(milliseconds);
playAudio();
}
}
});
cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
public void startTimer(long milliseconds){
hourglass = new Hourglass(milliseconds, 1000) {
#Override
public void onTimerTick(long timeRemaining) {
countDown.setText("" + String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes(timeRemaining),
TimeUnit.MILLISECONDS.toSeconds(timeRemaining) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(timeRemaining))));
if(TimeUnit.MILLISECONDS.toMinutes(timeRemaining) ==0){
return;
}
}
#Override
public void onTimerFinish() {
isTimerDone = true;
}
};
hourglass.startTimer();
}
private void playAudio(){
if(mediaAffyPlayer == null){
mediaAffyPlayer = MediaPlayer.create(getApplicationContext(), tracks[0]);
mediaAffyPlayer.setOnCompletionListener(this);
mediaAffyPlayer.start();
isPaused = false;
return;
}
if(mediaAffyPlayer != null) {
mediaAffyPlayer.release();
mediaAffyPlayer = MediaPlayer.create(getApplicationContext(), tracks[0]);
mediaAffyPlayer.setOnCompletionListener(this);
isPaused = false;
mediaAffyPlayer.start();
}
mediaAffyPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
return false;
}
});
}
public void onCompletion(MediaPlayer mediaPlayer) {
if (currentTrack < tracks.length - 1) {
if(isTimerDone){
countDown.setText("" + String.format("%d min",
TimeUnit.MILLISECONDS.toMinutes(milliseconds)));
pause.setImageResource(R.drawable.ic_play1);
mediaPlayer.reset();
mediaPlayer.release();
mediaPlayer=null;
hourglass = null;
return;
}
currentTrack++;
mediaPlayer.release();
mediaPlayer = MediaPlayer.create(getApplicationContext(), tracks[currentTrack]);
mediaPlayer.setOnCompletionListener(ShowMeditationActivity.this);
mediaPlayer.start();
} else {
if(!isTimerDone){
currentTrack = 0;
playAudio();
}
}
}
Exception
java.lang.IllegalStateException
at android.media.MediaPlayer._pause(Native Method)
at android.media.MediaPlayer.pause(MediaPlayer.java:1512)
Which throws it at mediaAffyPlayer.pause(); in hourglass.isRunning()
I know the code is ugly, but I just think that when it plays the second track the media player object has changed and thats why it throws error. I just dont know how to fix it.
Any help is appreciated as i already burned through many hours trying to fix it.
Thanks
EDIT I fixed the issue.
I commented out the code in OnCompletion that created and played the mediaplayer. I called playAudio() and stuck the code in there.
private void playAudio(){
if(mediaAffyPlayer == null){
mediaAffyPlayer = MediaPlayer.create(getApplicationContext(), tracks[0]);
mediaAffyPlayer.setOnCompletionListener(this);
mediaAffyPlayer.start();
isPaused = false;
return;
}
if(mediaAffyPlayer != null) {
currentTrack++;
mediaAffyPlayer.release();
mediaAffyPlayer = MediaPlayer.create(getApplicationContext(), tracks[currentTrack]);
mediaAffyPlayer.setOnCompletionListener(ShowMeditationActivity.this);
mediaAffyPlayer.start();
}
Problem with isPaused() code
try with this!!
try{
if (mediaAffyPlayer.isPlaying()) {
mediaAffyPlayer.pause();
}
}catch(Exception we){
we.printStackTrace();
}
Related
I designed an online music player which streams file from my server and shows them in a recyclerView. when I click on the specific song it plays automatically, but when I go back to my recyclerview and I choose it again it doesn't play anymore and even duration of song becomes an insane number. I even tried to handle my media player onBackPressed() method or in OnRestart() or onResume() method. I'm confused. Please let me know about any suggestion.
Here's my code for player:
public class PlayerActivity extends AppCompatActivity implements View.OnClickListener {
private CircularMusicProgressBar cover;
private ImageButton playPause, rewind, forward, repeat, fav, download;
private TextView title, term, spendingTime, totalTime, emptyRec;
private Context context;
public static MediaPlayer mediaPlayer;
int i;
private Timer timer;
private Bundle extra;
Uri uri;
RecyclerView recyclerView;
RequestQueue requestQueue;
SuggestionAdapter suggestionAdapter;
LinearLayoutManager layoutManager;
List<Listening> list = new ArrayList<>();
String url = "https://www.learnhere.ir/listening.php";
AccessDataOnServer suggestionData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
initFields();
playOnStart();
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.play_pause:
if (i == 1) {
i = 2;
playPause.setImageResource(R.drawable.ic_baseline_play);
mediaPlayer.pause();
} else {
i = 1;
playPause.setImageResource(R.drawable.ic_baseline_pause);
int b = mediaPlayer.getCurrentPosition();
mediaPlayer.seekTo(b);
mediaPlayer.start();
}
break;
case R.id.rewind:
Toast.makeText(context, "rewind", Toast.LENGTH_SHORT).show();
break;
case R.id.forward:
Toast.makeText(context, "forward", Toast.LENGTH_SHORT).show();
break;
case R.id.repeat:
Toast.makeText(context, "repeat", Toast.LENGTH_SHORT).show();
break;
case R.id.fav:
Toast.makeText(context, "fav", Toast.LENGTH_SHORT).show();
break;
case R.id.download:
Toast.makeText(context, "download", Toast.LENGTH_SHORT).show();
break;
}
}
public void initFields() {
i = 0;
context = this;
cover = findViewById(R.id.cover_progress);
playPause = findViewById(R.id.play_pause);
rewind = findViewById(R.id.rewind);
forward = findViewById(R.id.forward);
repeat = findViewById(R.id.repeat);
fav = findViewById(R.id.fav);
download = findViewById(R.id.download);
title = findViewById(R.id.title_tv);
term = findViewById(R.id.term_tv);
emptyRec = findViewById(R.id.empty_rec);
spendingTime = findViewById(R.id.spending_time);
totalTime = findViewById(R.id.total_time);
playPause.setOnClickListener(this);
rewind.setOnClickListener(this);
forward.setOnClickListener(this);
repeat.setOnClickListener(this);
fav.setOnClickListener(this);
download.setOnClickListener(this);
extra = getIntent().getExtras();
Picasso.get().load(extra.getString("cover")).into(cover);
title.setText(extra.getString("title"));
term.setText(extra.getString("term"));
timer = new Timer();
uri = Uri.parse(extra.getString("link"));
recyclerView = findViewById(R.id.suggestion_recycler);
requestQueue = Volley.newRequestQueue(context);
layoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
suggestionAdapter = new SuggestionAdapter(list, context);
suggestionData = new AccessDataOnServer();
recyclerView.setAdapter(suggestionAdapter);
recyclerView.setLayoutManager(layoutManager);
suggestionData.getSuggestion(context, list, recyclerView, url, requestQueue);
if (list.size() <= 1) {
emptyRec.setVisibility(View.VISIBLE);
recyclerView.setVisibility(View.GONE);
} else {
emptyRec.setVisibility(View.GONE);
recyclerView.setVisibility(View.VISIBLE);
}
}
public void play() {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioAttributes(
new AudioAttributes
.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build());
mediaPlayer.setDataSource(context, uri);
mediaPlayer.prepare();
mediaPlayer.start();
} catch (Exception e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
getTime();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
});
thread.start();
}
public void playOnStart() {
Toast.makeText(context, "Please wait until the audio plays...", Toast.LENGTH_SHORT).show();
play();
i = 1;
playPause.setImageResource(R.drawable.ic_baseline_pause);
}
public String millisecondToSecond(long millisecond) {
String finalTimerString = "";
String secondString = "";
String minuteString = "";
//convert total duration into time
int hour = (int) (millisecond / (1000 * 60 * 60));
int minute = (int) (millisecond % (1000 * 60 * 60) / (1000 * 60));
int second = (int) (millisecond % (1000 * 60 * 60) % (1000 * 60) / 1000);
//Add hours if there
if (hour > 0) {
finalTimerString = hour + ":";
}
//Prepending 0 to second if it's one digit
if (second < 10) {
secondString = "0" + second;
} else {
secondString = "" + second;
}
//Prepending 0 to minute if it's one digit
if (minute < 10) {
minuteString = "0" + minute;
} else {
minuteString = "" + minute;
}
finalTimerString = finalTimerString + minuteString + ":" + secondString;
//Return timer string
return finalTimerString;
}
public void getTime() {
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// Without runOnUiThread we don't have access to modifiers like text view
runOnUiThread(new Runnable() {
#Override
public void run() {
long current = mediaPlayer.getCurrentPosition();
int i = (mediaPlayer.getCurrentPosition() * 100) / mediaPlayer.getDuration();
spendingTime.setText("" + millisecondToSecond(current));
cover.setValue(i);
int duration = mediaPlayer.getDuration();
String time = String.format(Locale.US, "%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(duration),
TimeUnit.MILLISECONDS.toSeconds(duration) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration)));
totalTime.setText(time);
}
});
}
}, 0, 1000);
}
#Override
public void onBackPressed() {
mediaPlayer.stop();
finish();
}
#Override
protected void onRestart() {
super.onRestart();
playOnStart();
}
Well I reviewed your codes and it seems you aren't using Media player class properly.
I made a few changes to each block of your codes. I hope it solves your problem.
First of all change the following scope:
public static MediaPlayer mediaPlayer;
To
MediaPlayer mediaPlayer = new MediaPlayer();
I made a method for your mediaPlayer and you should use it in your onCreate() :
private void prepareMediaPlayer() {
try {
mediaPlayer.setDataSource(context, uri);
mediaPlayer.prepare();
updateSeekBarTimer();
} catch (Exception e) {
e.printStackTrace();
}
}
A method to update your seekbar :
private void updateSeekBarTimer() {
try {
if (mediaPlayer.isPlaying()) {
total_time = mediaPlayer.getDuration();
current_time = mediaPlayer.getCurrentPosition();
totalTime.setText("" + utils.milliSecondsToTimer(total_time));
spendingTime.setText("" + utils.milliSecondsToTimer(current_time));
int progress = (int) (utils.getProgressPercentage(current_time, total_time));
seekBar.setProgress(progress);
Runnable runnable = new Runnable() {
#Override
public void run() {
updateSeekBarTimer();
}
};
handler.postDelayed(runnable, 1000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
And finally you need an Interface to decide what happens when your track ends:
public class PlayerActivity extends AppCompatActivity implements View.OnClickListener, MediaPlayer.OnCompletionListener
#Override
public void onCompletion(MediaPlayer mp) {
handler.removeCallbacks(null);
playPause.setImageResource(R.drawable.ic_baseline_play);
if (rep) {
mediaPlayer.start();
playPause.setImageResource(R.drawable.ic_baseline_pause);
updateSeekBarTimer();
} else {
seekBar.setProgress(0);
totalTime.setText(R.string.zero_time);
spendingTime.setText(R.string.zero_time);
playPause.setImageResource(R.drawable.ic_baseline_play);
mediaPlayer.reset();
prepareMediaPlayer();
}
}
I am currently working on Chat application. In this there is feature of sending voice notes. The sending and playing of voice notes is working fine. But the problem is that when I play the voice notes, the previous voice notes playing not stoping.. both are playing together.
here is my code for playing voice notes,
public static class MessageViewHolder extends RecyclerView.ViewHolder {
private TextView messageTextView;
private ImageView messageImageView;
private TextView timeTextView;
private LinearLayout textMessageLayout;
private TextView messengerNameTextView;
private CircleImageView messengerPhotoImageView;
ImageView leftQuackImage, rightQuackImage;
private LinearLayout voiceNotesLayout;
private ImageView playImageView, stopImageView;
private SeekBar progressSeekbar;
private MediaPlayer mPlayer;
double timeElapsed = 0, finalTime = 0;
Handler durationHandler = new Handler();
Runnable updateSeekBarTime;
boolean isPlaying;
public MessageViewHolder(View itemView) {
super(itemView);
messageTextView = (TextView) itemView.findViewById(R.id.messageTextView);
messageImageView = (ImageView) itemView.findViewById(R.id.messageImageView);
timeTextView = (TextView) itemView.findViewById(R.id.timeTextView);
textMessageLayout = (LinearLayout) itemView.findViewById(R.id.textMessageLayout);
messengerNameTextView = (TextView) itemView.findViewById(R.id.messengerTextView);
messengerPhotoImageView = (CircleImageView) itemView.findViewById(R.id.messengerImageView);
leftQuackImage = (ImageView) itemView.findViewById(R.id.leftQuackImage);
rightQuackImage = (ImageView) itemView.findViewById(R.id.rightQuackImage);
voiceNotesLayout = (LinearLayout) itemView.findViewById(R.id.voiceNotesLayout);
playImageView = (ImageView) itemView.findViewById(R.id.playImageView);
stopImageView = (ImageView) itemView.findViewById(R.id.stopImageView);
progressSeekbar = (SeekBar) itemView.findViewById(R.id.progressSeekbar);
isPlaying = false;
mPlayer = new MediaPlayer();
}
public void setupAudioPlay(final long duration, final String url){
progressSeekbar.setMax((int) duration);
progressSeekbar.setClickable(false);
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mPlayer.setDataSource(url);
mPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}catch (IllegalStateException e){
e.printStackTrace();
}
playImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.e("Media player","isPlaying"+mPlayer.isPlaying()+isPlaying);
if (mPlayer.isPlaying()) {
mPlayer.stop();
mPlayer.release();
mPlayer = null;
}
if (!isPlaying) {
isPlaying = true;
mPlayer.start();
playImageView.setVisibility(View.GONE);
stopImageView.setVisibility(View.VISIBLE);
timeElapsed = mPlayer.getCurrentPosition();
progressSeekbar.setProgress((int) timeElapsed);
durationHandler.postDelayed(updateSeekBarTime, 100);
} else {
isPlaying = false;
mPlayer.pause();
}
}
});
stopImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (isPlaying) {
if (stopPlaying()) {
playImageView.setVisibility(View.VISIBLE);
stopImageView.setVisibility(View.GONE);
}
}
}
});
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
if (mp != null) {
mPlayer.seekTo(0);
isPlaying = false;
progressSeekbar.setProgress(0);
}
playImageView.setVisibility(View.VISIBLE);
stopImageView.setVisibility(View.GONE);
}
});
updateSeekBarTime = new Runnable() {
public void run() {
if (mPlayer != null) {
if (mPlayer.isPlaying()) {
timeElapsed = mPlayer.getCurrentPosition();
progressSeekbar.setProgress((int) timeElapsed);
durationHandler.postDelayed(this, 100);
} else {
mPlayer.pause();
isPlaying = false;
progressSeekbar.setProgress(0);
playImageView.setVisibility(View.VISIBLE);
stopImageView.setVisibility(View.GONE);
}
}
}
};
}
private boolean stopPlaying() {
mPlayer.pause();
mPlayer.seekTo(0);
if (!mPlayer.isPlaying()) {
return true;
}
return false;
}
}
here the mPlayer.isPlaying always gets false.
Please Help me!
From the documentation:
When the call to pause() returns, the MediaPlayer object enters the Paused state. Note that the transition from the Started state to the Paused state and vice versa happens asynchronously in the player engine. It may take some time before the state is updated in calls to isPlaying(), and it can be a number of seconds in the case of streamed content.
This may be the case here. The reasons why sound is not stopping and why isPlaying() returns true might be different. For example multiple instances of MediaPlayer might exist in parallel, making mPlayer static would exclude such an option.
You can check the system Audio status whenever it is necessary. In your case, whenever the play button is clicked the condition below should be checked first.
AudioManager manager = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE);
if(manager.isMusicActive())
{
// to do
}
In to do part you should implement the primary action which is:
KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PAUSE);
audioManager.dispatchMediaKeyEvent(event);
You can find the whole documentation here
I have developed an app that has two buttons (left and right) and a Textview that will pop up on the screen.Each button has it's corresponding word.
The user has to click the button that corresponds to TextView's word as quickly as possible when it shows. I want to calculate it's reaction time on clicking the button.
Below is my code.
public class Place_to_go_1 extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_place_to_go_1);
placeone = Global_variables.getFirst_choice_label();
placetwo = Global_variables.getSecond_choice_label();
p_one = (TextView)findViewById(R.id.p_one);
p_two = (TextView)findViewById(R.id.p_two);
btnleft = (ImageButton)findViewById(R.id.btnleft);
btnright = (ImageButton)findViewById(R.id.btnright);
next = (ImageButton)findViewById(R.id.Next);
lblmaintext = (TextView)findViewById(R.id.lblmaintext);
lblprompt = (TextView)findViewById(R.id.lblprompt);
lblreact = (TextView)findViewById(R.id.lblreact);
imgmain = (ImageView)findViewById(R.id.imgmain);
//prac = (ImageView) findViewById(R.id.prac);
Intent intent = getIntent();
final String randomId = intent.getStringExtra("Info_id");
//============ validate image if not empty
setImage_onLaunch();
//==== populate left and right choices===
populate_headers(placeone, placetwo);
//==== populate attributes=====
populate_attributes();
//============== instruction ======
setInstruction();
//=============media
wrong_press = MediaPlayer.create(this, R.raw.wrong_press);
react_fast = MediaPlayer.create(this, R.raw.react_faster);
//=== left button click trigger
btnleft.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String position = "H";
if (tanan[counter].equals(p_one.getText().toString())) {
lblprompt.setVisibility(View.INVISIBLE);
HashMap<String,String> queryValues = new HashMap<String, String>();
queryValues.put("Info_id",randomId);
queryValues.put("Choice",p_one.getText().toString());
queryValues.put("Reaction_time",String.valueOf(elapsedTime));
queryValues.put("Position",position);
queryValues.put("Main",main);
queryValues.put("Error",error);
mydb.insertTest(queryValues);
counter++;
if (counter < tanan.length) {
btnleft.setEnabled(false);
btnright.setEnabled(false);
timeStamp = System.currentTimeMillis();
//Toast.makeText(Place_to_go_1.this, ""+timeStamp, Toast.LENGTH_SHORT).show();
getreactionTime(p_one.getText().toString(), String.valueOf((((timeStamp) / 1000.0) - ((timeRun) / 1000.0))));
setIntervalTime();
} else {
//======end sa data
postEnd();
}
} else {
// Toast.makeText(Place_to_go_1.this, "Wrong pressed", Toast.LENGTH_SHORT).show();
//wrong_press.start();
wrong_click_audio();
error = "1";
lblprompt.setVisibility(View.VISIBLE);
}
}
});
//==== right button click trigger
btnright.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String position = "A";
if (tanan[counter].equals(p_two.getText().toString())) {
lblprompt.setVisibility(View.INVISIBLE);
HashMap<String,String> queryValues = new HashMap<String, String>();
queryValues.put("Info_id",randomId);
queryValues.put("Choice",p_two.getText().toString());
queryValues.put("Reaction_time", String.valueOf(elapsedTime));
queryValues.put("Position",position);
queryValues.put("Main",main);
queryValues.put("Error",error);
mydb.insertTest(queryValues);
counter++;
if (counter < tanan.length) {
btnleft.setEnabled(false);
btnright.setEnabled(false);
timeStamp = System.currentTimeMillis();
//Toast.makeText(Place_to_go_1.this, ""+timeStamp, Toast.LENGTH_SHORT).show();
getreactionTime(p_two.getText().toString(), String.valueOf((((timeStamp) / 1000.0) - ((timeRun) / 1000.0))));
setIntervalTime();
} else {
//======end sa data
postEnd();
}
} else {
// Toast.makeText(Place_to_go_1.this, "Wrong pressed", Toast.LENGTH_SHORT).show();
// wrong_press.start();
wrong_click_audio();
error = "1";
lblprompt.setVisibility(View.VISIBLE);
}
}
});
// ==== next button for the next activity (Place to go 2)
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = getIntent();
String randomId = intent.getStringExtra("Info_id");
//============= launch activity 2 for place to go
if (instruct == true) {
next.setVisibility(View.INVISIBLE);
// prac.setVisibility(View.VISIBLE);
CountDownTimer();
} else {
//Toast.makeText(getApplication(),"Saved Successfully.",Toast.LENGTH_SHORT).show();
Intent i = new Intent(getApplicationContext(), Place_to_go_2.class);
i.putExtra("Info_id", randomId);
startActivity(i);
}
}
});
}
public void interval(){
if(counter < tanan.length){
lblmaintext.setVisibility(View.VISIBLE);
timeRun = System.currentTimeMillis();
btnleft.setEnabled(true);
btnright.setEnabled(true);
lblmaintext.setText(tanan[counter]);
setImage();
imgmain.setVisibility(View.VISIBLE);
react = true;
reacFaster();
}else{
//======end sa data
Toast.makeText(Place_to_go_1.this, "End data", Toast.LENGTH_SHORT).show();
lblmaintext.setVisibility(View.VISIBLE);
lblmaintext.setText("Ok for now");
}
}
public void setIntervalTime(){
react = false;
lblreact.setVisibility(View.INVISIBLE);
reactFaster_timer.cancel();
lblmaintext.setVisibility(View.INVISIBLE);
lblreact.setVisibility(View.INVISIBLE);
imgmain.setVisibility(View.INVISIBLE);
timer = new CountDownTimer(Global_variables.interval_time_before_choices_will_show,Global_variables.interval_time_before_choices_will_show) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
interval();
}
}.start();
}
int counter_countdown = 0;
int drawwable_amber = R.drawable.amber;
String arr[] = {"Ready...","Set...","Start."};
public void CountDownTimer(){
btnleft.setVisibility(View.INVISIBLE);
btnright.setVisibility(View.INVISIBLE);
lblmaintext.setBackgroundResource(0);
timer = new CountDownTimer(4000,1000) {
#Override
public void onTick(long millisUntilFinished) {
lblmaintext.setTextSize(35);
lblmaintext.setText(arr[counter_countdown]);
counter_countdown++;
}
#Override
public void onFinish() {
btnleft.setVisibility(View.VISIBLE);
btnright.setVisibility(View.VISIBLE);
lblmaintext.setBackgroundResource(drawwable_amber);
// lblmaintext.setText(tanan[counter]);
//setImage();
val_first_launch();
timeRun = System.currentTimeMillis();
react = true;
reacFaster();
}
}.start();
}
public void reacFaster(){
reactFaster_timer = new CountDownTimer(Global_variables.reaction_time_first_param,Global_variables.reaction_time_second_param) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
if(react == true){
//Toast.makeText(Place_to_go_1.this, "please react faster", Toast.LENGTH_SHORT).show();
react_fast.start();
lblreact.setVisibility(View.VISIBLE);
}
}
}.start();
}
public void populate_headers(String one,String two){
//== this methos sets headers as random==//
headers = new ArrayList<String>();
headers.add(one);
headers.add(two);
Collections.shuffle(headers);
p_one.setText(headers.get(0));
p_two.setText(headers.get(1));
}
public void populate_attributes(){
attributes = new ArrayList<String>();
for(int h =0;h < 5;h++){
attributes.add(placeone);
attributes.add(placetwo);
}
Collections.shuffle(attributes);
tanan = new String[attributes.size()];
for(int k = 0; k < tanan.length;k++ ){
tanan[k] = attributes.get(k);
}
}
public void postEnd(){
instruct = false;
lblprompt.setVisibility(View.INVISIBLE);
btnright.setVisibility(View.INVISIBLE);
btnleft.setVisibility(View.INVISIBLE);
next.setVisibility(View.VISIBLE);
lblmaintext.setBackgroundResource(0);
lblmaintext.setTextSize(20);
p_one.setVisibility(View.INVISIBLE);
p_two.setVisibility(View.INVISIBLE);
imgmain.setVisibility(View.INVISIBLE);
reactFaster_timer.cancel();
lblreact.setVisibility(View.INVISIBLE);
lblmaintext.setText("Well done!\nNext, is the main task. It is exactly the same as before but this time words will appear on the screen that might distract you. \nPlease respond as quickly as you can.\n Press Next to begin");
}
//=========== validate if image is enabled/ disble if not set
public void setImage_onLaunch(){
if(Global_variables.getFirst_choice_image().equals("") || Global_variables.getSecond_choice_image().equals("")){
disbaleImage();
}else{
}
}
public void setImage(){
/* if(tanan[counter].equals(p_one.getText().toString())){
imgmain.setImageBitmap(BitmapFactory.decodeFile(Global_variables.getFirst_choice_image()));
}else{
imgmain.setImageBitmap(BitmapFactory.decodeFile(Global_variables.getSecond_choice_image()));
}*/
if(placeone.equals(tanan[counter])){
imgmain.setImageBitmap(BitmapFactory.decodeFile(Global_variables.getFirst_choice_image()));
}else{
imgmain.setImageBitmap(BitmapFactory.decodeFile(Global_variables.getSecond_choice_image()));
}
}
public void val_first_launch(){
if(Global_variables.getFirst_choice_image().equals("") || Global_variables.getSecond_choice_image().equals("")){
lblmaintext.setVisibility(View.VISIBLE);
lblmaintext.setText(tanan[counter]);
}else{
imgmain.setVisibility(View.VISIBLE);
if(placeone.equals(tanan[counter])){
imgmain.setImageBitmap(BitmapFactory.decodeFile(Global_variables.getFirst_choice_image()));
}else{
imgmain.setImageBitmap(BitmapFactory.decodeFile(Global_variables.getSecond_choice_image()));
}
}
}
public void disbaleImage(){
imgmain.setBackgroundResource(0);
imgmain.setVisibility(View.GONE);
}
#Override
public void onBackPressed() {
super.onBackPressed();
startActivity(new Intent(getApplication(), MainActivity.class));
finish();
}
public String getreactionTime(String domain, String time){
// Toast.makeText(Place_to_go_1.this, time, Toast.LENGTH_SHORT).show();
//== get reaction time to every activity
Global_variables.set_timeStamps(domain, time);
return domain;
}
//===== prompt instruction====
public void setInstruction(){
btnleft.setVisibility(View.INVISIBLE);
btnright.setVisibility(View.INVISIBLE);
lblmaintext.setBackgroundResource(0);
lblmaintext.setTextSize(20);
lblmaintext.setText("Instruction:\n\nIf " + p_one.getText().toString() + " appears, press arrow left.\n If " + p_two.getText().toString() +
" appears, press arrow right.\n\nRespond as quickly as you can.");
next.setVisibility(View.VISIBLE);
}
//===== prompt instruction====
public void wrong_click_audio(){
wrong_press.start();
}
//=============end class====================
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
// Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
//Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
}
}
Here a simple logic to calculate reaction time is to create a variable which hold a time when a question is popped up to user and the time when a user show a click reaction to question and calculate the time difference between these two action.
long timeWhenQuestionShowed = System.currentTimeMillis();
long timeWhenUserReacted = System.currentTimeMillis();
long reactionTime = timeWhenQuestionShowed - timeWhenUserReacted;
This should help:
Try using onTouch instead of onClick.
long timeBefor=0;
long timeReaction=0;
btnleft.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: // when pressed
timeBefore=System.currentTimeMillis();
break;
case MotionEvent.ACTION_UP: // when released
timeReaction=System.currentTimeMillis() - timeBefore; // calculate difference
break;
}
}
timeReaction is your desired value.
The idea is to calculate the difference between 2 points in time. I will write 2 examples of calculating time difference in Java / measuring reaction time in Java:
System.nanoTime() or System.currentTimeMillis()
Differences are discussed here: Time measuring overhead in Java
long endTimeNanoSec = 0;
long startTimeNanoSec = System.nanoTime();
myWorkThatNeedsTiming(); // wait for user button press here
endTimeNanoSec = System.nanoTime();
long totalWorkTimeNanos = endTimeNanoSec - startTimeNanoSec;
Java StopWatch
JavaDoc: StopWatch
Stopwatch stopwatch = Stopwatch.createStarted();
myWorkThatNeedsTiming(); // wait for user button press here
stopwatch.stop();
long totalWorkTimeMillis = stopwatch.elapsedMillis();
I have this code below that is in my main activity. Basicly whenever I click the button, it will first check if an alarm is set, if it is false it will go into a loop which reads the RSSI on a connected device until it is above a RSSI value. My question is how do i make this loop not crash my app, which it currently does. Also for some reason the mRSSI text field never gets populated with the RSSI value. Can someone please help me out. This is the last thing in my app i need to get done.
public void onMonitorClick(final View view){
if (isBLEEnabled()) {
if (!isDeviceConnected()) {
// do nothing
} else if (isImmediateAlertOn == true) {
showMonitor();
DebugLogger.v(TAG, "app is high alert");
isImmediateAlertOn = true;
}
else {
DebugLogger.v(TAG, "app is no alert");
hideMonitor();
while(monitorStop != 1)
{
((ProximityService.ProximityBinder) getService()).getRssi();
rssilevel = ((ProximityService.ProximityBinder) getService()).getRssiValue();
if (rssilevel > -50 ) {
DebugLogger.v(TAG, "greater then -50");
monitorStop = 1;
}
mRSSI.setText("-" + String.valueOf(rssilevel) + "dB");
isImmediateAlertOn = false;
mFindMeButton.setEnabled(false);
}
}
} else {
showBLEDialog();
}
}
edit redone code
public void onMonitorClick(final View view){
if (isBLEEnabled()) {
if (!isDeviceConnected()) {
// do nothing
} else if (monitorvis == 0) {
showMonitor();
} else if (isImmediateAlertOn == true) {
showMonitor();
DebugLogger.v(TAG, "app is high alert");
isImmediateAlertOn = true;
}
else {
DebugLogger.v(TAG, "app is no alert");
hideMonitor();
monitorStop = 0;
do { run(); run2(); } while(monitorStop != 1);
}
} else {
showBLEDialog();
}
}
protected void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
((ProximityService.ProximityBinder) getService()).getRssi();
rssilevel = ((ProximityService.ProximityBinder) getService()).getRssiValue();
mRSSI.setText("-" + String.valueOf(rssilevel) + "dB");
}
});
}
protected void run2() {
runOnUiThread(new Runnable() {
#Override
public void run() {
mRSSI.setText("-" + String.valueOf(rssilevel) + "dB");
if (rssilevel < -60)
{
monitorStop = 1;
showMonitor();
((ProximityService.ProximityBinder) getService()).startImmediateAlert();
}
}
});
}
This is (IMHO) the easiest way to delay execution of a piece of code:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// Do what you need to do
}
}, MILISECONDS_BEFORE_EXECUTION);
Here, MILISECONDS_BEFORE_EXECUTION is a value (constant or variable) of the milliseconds you need to wait before executing the code. Documentation of Handler in Android.
Hey guys working on a media player for my android device but not sure how to get the seekbar working and also i want to be able to fast forward and rewind by holding down the the buttons instead of pressing once
here's what i have so far
MyMediaPlayerActivity class:
package com.technegames.mymediaplayer;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import android.app.Activity;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
public class MyMediaPlayerActivity extends Activity {
WakeLock wakeLock;
private static final String[] EXTENSIONS = { ".mp3", ".mid", ".wav", ".ogg", ".mp4" }; //Playable Extensions
List<String> trackNames; //Playable Track Titles
List<String> trackArtworks; //Track artwork names
AssetManager assets; //Assets (Compiled with APK)
File path; //directory where music is loaded from on SD Card
File path2; //directory where album artwork is loaded from on SD Card
Music track; //currently loaded track
ImageView bg; //Track artwork
Button btnPlay; //The play button will need to change from 'play' to 'pause', so we need an instance of it
Random random; //used for shuffle
boolean shuffle; //is shuffle mode on?
boolean isTuning; //is user currently jammin out, if so automatically start playing the next track
int currentTrack; //index of current track selected
int type; //0 for loading from assets, 1 for loading from SD card
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "Lexiconda");
setContentView(R.layout.main);
initialize(0);
}
#Override
public void onResume(){
super.onResume();
wakeLock.acquire();
}
#Override
public void onPause(){
super.onPause();
wakeLock.release();
if(track != null){
if(track.isPlaying()){
track.pause();
isTuning = false;
btnPlay.setBackgroundResource(R.drawable.play);
}
if(isFinishing()){
track.dispose();
finish();
}
} else{
if(isFinishing()){
finish();
}
}
}
private void initialize(int type){
bg = (ImageView) findViewById(R.id.bg);
btnPlay = (Button) findViewById(R.id.btnPlay);
btnPlay.setBackgroundResource(R.drawable.play);
trackNames = new ArrayList<String>();
trackArtworks = new ArrayList<String>();
assets = getAssets();
currentTrack = 0;
shuffle = false;
isTuning = false;
random = new Random();
this.type = type;
addTracks(getTracks());
loadTrack();
}
//Generate a String Array that represents all of the files found
private String[] getTracks(){
if(type == 0){
try {
String[] temp = getAssets().list("");
return temp;
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}
} else if(type == 1){
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
|| Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED_READ_ONLY)){
path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
path2 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
String[] temp = path.list();
return temp;
} else{
Toast.makeText(getBaseContext(), "SD Card is either mounted elsewhere or is unusable", Toast.LENGTH_LONG).show();
}
}
return null;
}
//Adds the playable files to the trackNames List
private void addTracks(String[] temp){
if(temp != null){
for(int i = 0; i < temp.length; i++){
//Only accept files that have one of the extensions in the EXTENSIONS array
if(trackChecker(temp[i])){
trackNames.add(temp[i]);
trackArtworks.add(temp[i].substring(0, temp[i].length()-4));
}
}
Toast.makeText(getBaseContext(), "Loaded " + Integer.toString(trackNames.size()) + " Tracks", Toast.LENGTH_SHORT).show();
}
}
//Checks to make sure that the track to be loaded has a correct extenson
private boolean trackChecker(String trackToTest){
for(int j = 0; j < EXTENSIONS.length; j++){
if(trackToTest.contains(EXTENSIONS[j])){
return true;
}
}
return false;
}
//Loads the track by calling loadMusic
private void loadTrack(){
if(track != null){
track.dispose();
}
if(trackNames.size() > 0){
track = loadMusic(type);
setImage("drawable/" + trackArtworks.get(currentTrack));
}
}
//loads a Music instance using either a built in asset or an external resource
private Music loadMusic(int type){
switch(type){
case 0:
try{
AssetFileDescriptor assetDescriptor = assets.openFd(trackNames.get(currentTrack));
return new Music(assetDescriptor);
} catch(IOException e){
e.printStackTrace();
Toast.makeText(getBaseContext(), "Error Loading " + trackNames.get(currentTrack), Toast.LENGTH_LONG).show();
}
return null;
case 1:
try{
FileInputStream fis = new FileInputStream(new File(path, trackNames.get(currentTrack)));
FileDescriptor fileDescriptor = fis.getFD();
return new Music(fileDescriptor);
} catch(IOException e){
e.printStackTrace();
Toast.makeText(getBaseContext(), "Error Loading " + trackNames.get(currentTrack), Toast.LENGTH_LONG).show();
}
return null;
default:
return null;
}
}
//Sets the background image to match the track currently playing or a default image
private void setImage(String name) {
if(type == 0){
int imageResource = getResources().getIdentifier(name, null, getPackageName());
if(imageResource != 0){
Drawable image = getResources().getDrawable(imageResource);
bg.setImageDrawable(image);
} else{
int defaultImageResource = getResources().getIdentifier("drawable/defaultbg", null, getPackageName());
if(defaultImageResource != 0){
Drawable image = getResources().getDrawable(defaultImageResource);
bg.setImageDrawable(image);
}
}
} else if(type == 1){
if(new File(path2.getAbsolutePath(), trackArtworks.get(currentTrack) + ".jpg").exists()){
bg.setImageDrawable(Drawable.createFromPath(path2.getAbsolutePath() + "/" + trackArtworks.get(currentTrack) + ".jpg"));
} else{
int defaultImageResource = getResources().getIdentifier("drawable/defaultbg", null, getPackageName());
if(defaultImageResource != 0){
Drawable image = getResources().getDrawable(defaultImageResource);
bg.setImageDrawable(image);
}
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu){
super.onCreateOptionsMenu(menu);
createMenu(menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item){
switch(item.getItemId()){
case 0:
//Set Looping
synchronized(this){
if(track.isLooping()){
track.setLooping(false);
Toast.makeText(getBaseContext(), "Playing Tracks Sequentially", Toast.LENGTH_SHORT).show();
} else{
track.setLooping(true);
Toast.makeText(getBaseContext(), "Looping " + trackNames.get(currentTrack), Toast.LENGTH_SHORT).show();
}
}
return true;
case 1:
//Set Shuffle
synchronized(this){
if(shuffle){
setShuffle(false);
} else{
setShuffle(true);
}
}
return true;
case 2:
//Stop Music
synchronized(this){
track.switchTracks();
btnPlay.setBackgroundResource(R.drawable.play);
}
return true;
case 3:
//Change Source from Assets to SD Card and vice versa
synchronized(this){
type++;
if(type > 1){
type = 0;
}
}
if(type == 0){
Toast.makeText(getBaseContext(), "Loading Tracks from Assets ", Toast.LENGTH_SHORT).show();
} else if(type == 1){
Toast.makeText(getBaseContext(), "Loading Tracks from SD Card", Toast.LENGTH_SHORT).show();
}
initialize(type);
return true;
default:
return false;
}
}
private void createMenu(Menu menu){
MenuItem miLooping = menu.add(0, 0, 0, "Looping");{
miLooping.setIcon(R.drawable.looping);
}
MenuItem miShuffle = menu.add(0, 1, 1, "Shuffle");{
miShuffle.setIcon(R.drawable.shuffle);
}
MenuItem miStop = menu.add(0, 2, 2, "Stop");{
miStop.setIcon(R.drawable.stop);
}
MenuItem miSource = menu.add(0, 3, 3, "Source");{
miSource.setIcon(R.drawable.source);
}
}
public void click(View view){
int id = view.getId();
switch(id){
case R.id.btnPlay:
synchronized(this){
if(isTuning){
isTuning = false;
btnPlay.setBackgroundResource(R.drawable.play);
track.pause();
} else{
isTuning = true;
btnPlay.setBackgroundResource(R.drawable.pause);
playTrack();
}
}
return;
case R.id.btnPrevious:
setTrack(0);
loadTrack();
playTrack();
return;
case R.id.btnNext:
setTrack(1);
loadTrack();
playTrack();
return;
default:
return;
}
}
private void setTrack(int direction){
if(direction == 0){
currentTrack--;
if(currentTrack < 0){
currentTrack = trackNames.size()-1;
}
} else if(direction == 1){
currentTrack++;
if(currentTrack > trackNames.size()-1){
currentTrack = 0;
}
}
if(shuffle){
int temp = random.nextInt(trackNames.size());
while(true){
if(temp != currentTrack){
currentTrack = temp;
break;
}
temp++;
if(temp > trackNames.size()-1){
temp = 0;
}
}
}
}
//Plays the Track
private void playTrack(){
if(isTuning && track != null){
track.play();
Toast.makeText(getBaseContext(), "Playing " + trackNames.get(currentTrack).substring(0, trackNames.get(currentTrack).length()-4), Toast.LENGTH_SHORT).show();
}
}
//Simply sets shuffle to isShuffle and then displays a message for confirmation
private void setShuffle(boolean isShuffle) {
shuffle = isShuffle;
if(shuffle){
Toast.makeText(getBaseContext(), "Shuffle On", Toast.LENGTH_SHORT).show();
} else{
Toast.makeText(getBaseContext(), "Shuffle Off", Toast.LENGTH_SHORT).show();
}
}
}
Music class:
import java.io.FileDescriptor;
import java.io.IOException;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
public class Music implements OnCompletionListener{
MediaPlayer mediaPlayer;
boolean isPrepared = false;
public Music(AssetFileDescriptor assetDescriptor){
mediaPlayer = new MediaPlayer();
try{
mediaPlayer.setDataSource(assetDescriptor.getFileDescriptor(), assetDescriptor.getStartOffset(), assetDescriptor.getLength());
mediaPlayer.prepare();
isPrepared = true;
mediaPlayer.setOnCompletionListener(this);
} catch(Exception ex){
throw new RuntimeException("Couldn't load music, uh oh!");
}
}
public Music(FileDescriptor fileDescriptor){
mediaPlayer = new MediaPlayer();
try{
mediaPlayer.setDataSource(fileDescriptor);
mediaPlayer.prepare();
isPrepared = true;
mediaPlayer.setOnCompletionListener(this);
} catch(Exception ex){
throw new RuntimeException("Couldn't load music, uh oh!");
}
}
public void onCompletion(MediaPlayer mediaPlayer) {
synchronized(this){
isPrepared = false;
}
}
public void play() {
if(mediaPlayer.isPlaying()){
return;
}
try{
synchronized(this){
if(!isPrepared){
mediaPlayer.prepare();
}
mediaPlayer.start();
}
} catch(IllegalStateException ex){
ex.printStackTrace();
} catch(IOException ex){
ex.printStackTrace();
}
}
public void stop() {
mediaPlayer.stop();
synchronized(this){
isPrepared = false;
}
}
public void switchTracks(){
mediaPlayer.seekTo(0);
mediaPlayer.pause();
}
public void pause() {
mediaPlayer.pause();
}
public boolean isPlaying() {
return mediaPlayer.isPlaying();
}
public boolean isLooping() {
return mediaPlayer.isLooping();
}
public void setLooping(boolean isLooping) {
mediaPlayer.setLooping(isLooping);
}
public void setVolume(float volumeLeft, float volumeRight) {
mediaPlayer.setVolume(volumeLeft, volumeRight);
}
public void dispose() {
if(mediaPlayer.isPlaying()){
stop();
}
mediaPlayer.release();
}
}
I hope this will help you. This Code is used in our project
public class MusicPlayer extends Activity
implements OnCompletionListener, SeekBar.OnSeekBarChangeListener {
private ImageButton btnPlay;
private ImageButton btnForward;
private ImageButton btnBackward;
private ImageButton btnPlaylist;
private ImageButton btnRepeat;
private ImageButton btnShuffle;
private SeekBar songProgressBar;
private TextView songTitleLabel;
private TextView songCurrentDurationLabel;
private TextView songTotalDurationLabel;
// Media Player
private MediaPlayer mp;
// Handler to update UI timer, progress bar etc,.
private Handler mHandler = new Handler();;
private SongsManager songManager;
private Utilities utils;
private int seekForwardTime = 5000; // 5000 milliseconds
private int seekBackwardTime = 5000; // 5000 milliseconds
private int currentSongIndex = 0;
private boolean isShuffle = false;
private boolean isRepeat = false;
private ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.player);
// All player buttons
btnPlay = (ImageButton) findViewById(R.id.btnPlay);
btnForward = (ImageButton) findViewById(R.id.btnForward);
btnBackward = (ImageButton) findViewById(R.id.btnBackward);
btnPlaylist = (ImageButton) findViewById(R.id.btnPlaylist);
btnRepeat = (ImageButton) findViewById(R.id.btnRepeat);
btnShuffle = (ImageButton) findViewById(R.id.btnShuffle);
songProgressBar = (SeekBar) findViewById(R.id.songProgressBar);
songTitleLabel = (TextView) findViewById(R.id.songTitle);
songCurrentDurationLabel = (TextView) findViewById(R.id.songCurrentDurationLabel);
songTotalDurationLabel = (TextView) findViewById(R.id.songTotalDurationLabel);
// Mediaplayer
mp = new MediaPlayer();
songManager = new SongsManager();
utils = new Utilities();
// Listeners
songProgressBar.setOnSeekBarChangeListener(this); // Important
mp.setOnCompletionListener(this); // Important
// Getting all songs list
songsList = songManager.getPlayList();
// By default play first song
playSong(0);
/**
* Play button click event plays a song and changes button to pause
* image pauses a song and changes button to play image
* */
btnPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// check for already playing
if (mp.isPlaying()) {
if (mp != null) {
mp.pause();
// Changing button image to play button
btnPlay.setImageResource(R.drawable.btn_play);
}
} else {
// Resume song
if (mp != null) {
mp.start();
// Changing button image to pause button
btnPlay.setImageResource(R.drawable.btn_pause);
}
}
}
});
btnForward.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
// get current song position
int currentPosition = mp.getCurrentPosition();
// check if seekForward time is lesser than song duration
if (currentPosition + seekForwardTime <= mp.getDuration()) {
// forward song
mp.seekTo(currentPosition + seekForwardTime);
} else {
// forward to end position
mp.seekTo(mp.getDuration());
}
return false;
}
});
/**
* Forward button click event Forwards song specified seconds
* */
btnForward.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// get current song position
// check if next song is there or not
if (currentSongIndex < (songsList.size() - 1)) {
playSong(currentSongIndex + 1);
currentSongIndex = currentSongIndex + 1;
} else {
// play first song
playSong(0);
currentSongIndex = 0;
}
}
});
btnBackward.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
int currentPosition = mp.getCurrentPosition();
// check if seekBackward time is greater than 0 sec
if (currentPosition - seekBackwardTime >= 0) {
// forward song
mp.seekTo(currentPosition - seekBackwardTime);
} else {
// backward to starting position
mp.seekTo(0);
}
return false;
}
});
/**
* Backward button click event Backward song to specified seconds
* */
btnBackward.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
if (currentSongIndex > 0) {
playSong(currentSongIndex - 1);
currentSongIndex = currentSongIndex - 1;
} else {
// play last song
playSong(songsList.size() - 1);
currentSongIndex = songsList.size() - 1;
}
}
});
/**
* Button Click event for Repeat button Enables repeat flag to true
* */
btnRepeat.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
if (isRepeat) {
isRepeat = false;
Toast.makeText(getApplicationContext(), "Repeat is OFF",
Toast.LENGTH_SHORT).show();
btnRepeat.setImageResource(R.drawable.btn_repeat);
} else {
// make repeat to true
isRepeat = true;
Toast.makeText(getApplicationContext(), "Repeat is ON",
Toast.LENGTH_SHORT).show();
// make shuffle to false
isShuffle = false;
btnRepeat.setImageResource(R.drawable.btn_repeat_focused);
btnShuffle.setImageResource(R.drawable.btn_shuffle);
}
}
});
/**
* Button Click event for Shuffle button Enables shuffle flag to true
* */
btnShuffle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
if (isShuffle) {
isShuffle = false;
Toast.makeText(getApplicationContext(), "Shuffle is OFF",
Toast.LENGTH_SHORT).show();
btnShuffle.setImageResource(R.drawable.btn_shuffle);
} else {
// make repeat to true
isShuffle = true;
Toast.makeText(getApplicationContext(), "Shuffle is ON",
Toast.LENGTH_SHORT).show();
// make shuffle to false
isRepeat = false;
btnShuffle.setImageResource(R.drawable.btn_shuffle_focused);
btnRepeat.setImageResource(R.drawable.btn_repeat);
}
}
});
/**
* Button Click event for Play list click event Launches list activity
* which displays list of songs
* */
btnPlaylist.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Intent i = new Intent(getApplicationContext(),
PlayListActivity.class);
startActivityForResult(i, 100);
}
});
}
/**
* Receiving song index from playlist view and play the song
* */
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == 100) {
currentSongIndex = data.getExtras().getInt("songIndex");
// play selected song
playSong(currentSongIndex);
}
}
/**
* Function to play a song
*
* #param songIndex
* - index of song
* */
public void playSong(int songIndex) {
// Play song
try {
mp.reset();
mp.setDataSource(songsList.get(songIndex).get("songPath"));
mp.prepare();
mp.start();
// Displaying Song title
String songTitle = songsList.get(songIndex).get("songTitle");
songTitleLabel.setText(songTitle);
// Changing Button Image to pause image
btnPlay.setImageResource(R.drawable.btn_pause);
// set Progress bar values
songProgressBar.setProgress(0);
songProgressBar.setMax(100);
// Updating progress bar
updateProgressBar();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Update timer on seekbar
* */
public void updateProgressBar() {
mHandler.postDelayed(mUpdateTimeTask, 100);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if (keyCode == KeyEvent.KEYCODE_BACK) {
mHandler.removeCallbacks(mUpdateTimeTask);
mp.release();
}
return super.onKeyDown(keyCode, event);
}
/**
* Background Runnable thread
* */
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
long totalDuration = mp.getDuration();
long currentDuration = mp.getCurrentPosition();
// Displaying Total Duration time
songTotalDurationLabel.setText(""
+ utils.milliSecondsToTimer(totalDuration));
// Displaying time completed playing
songCurrentDurationLabel.setText(""
+ utils.milliSecondsToTimer(currentDuration));
// Updating progress bar
int progress = (int) (utils.getProgressPercentage(currentDuration,
totalDuration));
// System.out.println("Progress : "+progress);
songProgressBar.setProgress(progress);
// Running this thread after 100 milliseconds
mHandler.postDelayed(this, 100);
}
};
/**
*
* */
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromTouch) {
}
/**
* When user starts moving the progress handler
* */
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// remove message Handler from updating progress bar
mHandler.removeCallbacks(mUpdateTimeTask);
}
/**
* When user stops moving the progress hanlder
* */
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
mHandler.removeCallbacks(mUpdateTimeTask);
int totalDuration = mp.getDuration();
int currentPosition = utils.progressToTimer(seekBar.getProgress(),
totalDuration);
// forward or backward to certain seconds
mp.seekTo(currentPosition);
// update timer progress again
updateProgressBar();
}
/**
* On Song Playing completed if repeat is ON play same song again if shuffle
* is ON play random song
* */
#Override
public void onCompletion(MediaPlayer arg0) {
// check for repeat is ON or OFF
if (isRepeat) {
// repeat is on play same song again
playSong(currentSongIndex);
} else if (isShuffle) {
// shuffle is on - play a random song
Random rand = new Random();
currentSongIndex = rand.nextInt((songsList.size() - 1) - 0 + 1) + 0;
playSong(currentSongIndex);
} else {
// no repeat or shuffle ON - play next song
if (currentSongIndex < (songsList.size() - 1)) {
playSong(currentSongIndex + 1);
currentSongIndex = currentSongIndex + 1;
} else {
// play first song
playSong(0);
currentSongIndex = 0;
}
}
}
#Override
public void onDestroy() {
super.onDestroy();
mp.release();
}
}