I'm implementing Simon Says in Android for a uni project, as part of an Audiogames suite application. I'm trying to generate a random sequence of 5 (just as a starting test) buttons playing and it's all going well except one thing: the buttons don't light up when they should (when their seed in the sequence is generated) but instead they do light up all together at the end of the generation.
Following the full code of my Java and XML (it's kind of a mess and incomplete so i'll point out to the parts that for me are troubling after)
Java Source
package it.unimi.di.lim.audiogames;
import android.content.Intent;
import android.graphics.drawable.ColorDrawable;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import java.util.LinkedList;
import java.util.Random;
public class Game2PlayActivity extends AppCompatActivity {
private int mScore = 0;
private LinkedList<Integer> temp = new LinkedList<>();
private MediaPlayer mCMediaPlayer;
private MediaPlayer mDMediaPlayer;
private MediaPlayer mEMediaPlayer;
private MediaPlayer mFMediaPlayer;
private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
releaseMediaPlayer(mp);
turnOffButton(mp);
}
};
private void releaseMediaPlayer(MediaPlayer mediaPlayer) {
if (mediaPlayer != null) {
mediaPlayer.release();
}
}
private void turnOffButton(MediaPlayer mp) {
Button mc_button = (Button) findViewById(R.id.c_button);
Button md_button = (Button) findViewById(R.id.d_button);
Button me_button = (Button) findViewById(R.id.e_button);
Button mf_button = (Button) findViewById(R.id.f_button);
if(mp == mCMediaPlayer) {
mc_button.setBackgroundColor(getResources().getColor(R.color.game2_c_off));
} else if (mp == mDMediaPlayer) {
md_button.setBackgroundColor(getResources().getColor(R.color.game2_d_off));
} else if (mp == mEMediaPlayer) {
me_button.setBackgroundColor(getResources().getColor(R.color.game2_e_off));
} else {
mf_button.setBackgroundColor(getResources().getColor(R.color.game2_f_off));
}
}
private void playButton(int i) {
char j;
if(i==0)
j='0';
else if(i==1)
j='1';
else if(i==2)
j='2';
else
j='3';
Button mc_button = (Button) findViewById(R.id.c_button);
Button md_button = (Button) findViewById(R.id.d_button);
Button me_button = (Button) findViewById(R.id.e_button);
Button mf_button = (Button) findViewById(R.id.f_button);
switch(j) {
case '0':
mc_button.setBackgroundResource(R.color.game2_c_on);
//mCMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.c_sound);
//mCMediaPlayer.start();
//mCMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
// #Override
// public void onCompletion(MediaPlayer mp) {
// mCMediaPlayer.release();
// }
//});
break;
case '1':
md_button.setBackgroundResource(R.color.game2_d_on);
//mDMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.d_sound);
//mDMediaPlayer.start();
//mDMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
// #Override
// public void onCompletion(MediaPlayer mp) {
// mDMediaPlayer.release();
// }
//});
break;
case '2':
me_button.setBackgroundResource(R.color.game2_e_on);
//mEMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.e_sound);
//mEMediaPlayer.start();
//mEMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
// #Override
// public void onCompletion(MediaPlayer mp) {
// mEMediaPlayer.release();
// }
//});
break;
case '3':
mf_button.setBackgroundResource(R.color.game2_f_on);
//mFMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.f_sound);
//mFMediaPlayer.start();
//mFMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
// #Override
// public void onCompletion(MediaPlayer mp) {
// mFMediaPlayer.release();
// }
//});
break;
}
}
private void createSequence(int i) {
Random rand = new Random();
for(int j = 0; j < i; j++) {
int seed = rand.nextInt(4);
temp.add(seed);
playButton(seed);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
protected void onStop() {
super.onStop();
releaseMediaPlayer(mCMediaPlayer);
releaseMediaPlayer(mDMediaPlayer);
releaseMediaPlayer(mEMediaPlayer);
releaseMediaPlayer(mFMediaPlayer);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game2_play);
Button mc_button = (Button) findViewById(R.id.c_button);
Button md_button = (Button) findViewById(R.id.d_button);
Button me_button = (Button) findViewById(R.id.e_button);
Button mf_button = (Button) findViewById(R.id.f_button);
if (Build.VERSION.SDK_INT >= 21) {
Window window = this.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.setStatusBarColor(this.getResources().getColor(R.color.game2Dark));
window.setNavigationBarColor(this.getResources().getColor(R.color.game2Primary));
}
android.support.v7.app.ActionBar bar = getSupportActionBar();
bar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.game2Primary)));
mc_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
playButton(0);
int check = temp.poll();
if(check!=0) {
Intent gameOver = new Intent(Game2PlayActivity.this, Game2Activity.class);
gameOver.putExtra("score", mScore);
startActivity(gameOver);
}
if(temp.size() == 0) {
mScore++;
TextView score = (TextView) findViewById(R.id.game2_score);
score.setText(Integer.toString(mScore));
}
}
});
md_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
playButton(1);
int check = temp.poll();
if(check!=1) {
Intent gameOver = new Intent(Game2PlayActivity.this, Game2Activity.class);
gameOver.putExtra("score", mScore);
startActivity(gameOver);
}
if(temp.size() == 0) {
mScore++;
TextView score = (TextView) findViewById(R.id.game2_score);
score.setText(Integer.toString(mScore));
}
}
});
me_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
playButton(2);
int check = temp.poll();
if(check!=2) {
Intent gameOver = new Intent(Game2PlayActivity.this, Game2Activity.class);
gameOver.putExtra("score", mScore);
startActivity(gameOver);
}
if(temp.size() == 0) {
mScore++;
TextView score = (TextView) findViewById(R.id.game2_score);
score.setText(Integer.toString(mScore));
}
}
});
mf_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
playButton(3);
int check = temp.poll();
if(check!=3) {
Intent gameOver = new Intent(Game2PlayActivity.this, Game2Activity.class);
gameOver.putExtra("score", mScore);
startActivity(gameOver);
}
if(temp.size() == 0) {
mScore++;
TextView score = (TextView) findViewById(R.id.game2_score);
score.setText(Integer.toString(mScore));
}
}
});
Button start_button = (Button) findViewById(R.id.game2_start_button);
start_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
createSequence(5);
}
});
}
}
XML Source
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical"
tools:context=".Game1PlayActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="#string/game2_score"
android:textSize="16sp"
android:padding="16dp"
android:gravity="bottom"
android:textAlignment="center" />
<TextView
android:id="#+id/game2_score"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.2"
android:text="0"
android:textSize="48sp"
android:padding="16dp"
android:gravity="top"
android:textAlignment="center" />
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.8"
android:text="#string/game2_criteria"
android:textSize="16sp"
android:padding="16dp"
android:gravity="bottom"
android:textAlignment="center" />
<Button
android:id="#+id/game2_start_button"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="#string/game2_start"
android:layout_marginTop="8dp"
android:layout_marginLeft="64dp"
android:layout_marginRight="64dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2">
<Button
android:id="#+id/c_button"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#color/game2_c_off"
android:layout_margin="16dp"
android:text="#string/game2_c" />
<Button
android:id="#+id/d_button"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#color/game2_d_off"
android:layout_margin="16dp"
android:text="#string/game2_d" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2">
<Button
android:id="#+id/e_button"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#color/game2_e_off"
android:layout_margin="16dp"
android:text="#string/game2_e" />
<Button
android:id="#+id/f_button"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#color/game2_f_off"
android:layout_margin="16dp"
android:text="#string/game2_f" />
</LinearLayout>
</LinearLayout>
-------------------------------------------------------------------------------
So basically what I'm trying to do is generating the sequence by clicking the button "Start" and here's the onClickListener (5 is just for testing purposes)
Button start_button = (Button) findViewById(R.id.game2_start_button);
start_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
createSequence(5);
}
});
This triggers the createSequence() method as follows
private void createSequence(int i) {
Random rand = new Random();
for(int j = 0; j < i; j++) {
int seed = rand.nextInt(4);
temp.add(seed);
playButton(seed);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
And so far all good. What I think is failing in my bad programming experience is the PlayButton() method
private void playButton(int i) {
char j;
if(i==0)
j='0';
else if(i==1)
j='1';
else if(i==2)
j='2';
else
j='3';
Button mc_button = (Button) findViewById(R.id.c_button);
Button md_button = (Button) findViewById(R.id.d_button);
Button me_button = (Button) findViewById(R.id.e_button);
Button mf_button = (Button) findViewById(R.id.f_button);
switch(j) {
case '0':
mc_button.setBackgroundResource(R.color.game2_c_on);
//mCMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.c_sound);
//mCMediaPlayer.start();
//mCMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
// #Override
// public void onCompletion(MediaPlayer mp) {
// mCMediaPlayer.release();
// }
//});
break;
case '1':
md_button.setBackgroundResource(R.color.game2_d_on);
//mDMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.d_sound);
//mDMediaPlayer.start();
//mDMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
// #Override
// public void onCompletion(MediaPlayer mp) {
// mDMediaPlayer.release();
// }
//});
break;
case '2':
me_button.setBackgroundResource(R.color.game2_e_on);
//mEMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.e_sound);
//mEMediaPlayer.start();
//mEMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
// #Override
// public void onCompletion(MediaPlayer mp) {
// mEMediaPlayer.release();
// }
//});
break;
case '3':
mf_button.setBackgroundResource(R.color.game2_f_on);
//mFMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.f_sound);
//mFMediaPlayer.start();
//mFMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
// #Override
// public void onCompletion(MediaPlayer mp) {
// mFMediaPlayer.release();
// }
//});
break;
}
}
The Audio Playback is commented but used to work just fine. It's really all about those SetBackgroundResource calls, they don't execute right away but only at the end of the for loop in the CreateSequence method.
If anyone wants to implement the whole project in Android Studio (unrecommended as it's probably very buggy), here it is (25 MB): http://www.mediafire.com/file/2c86sbe3rkb231d/AudiogamesSuite.zip
Thanks in advance
-------------------------------------------------------------------------------
EDIT - Managed to solve it thanks to Martin Pfeffer and some googling. Here's the updated code
private void createSequence(final int i) {
Thread t = new Thread(new Runnable() {
public void run() {
Random rand = new Random();
for (int j = 0; j < i; j++) {
final int seed = rand.nextInt(4);
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
temp.add(seed);
playButton(seed);
}
});
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.setDaemon(true);
t.start();
}
Add the synchronized specifier to the method.
private synchronized void createSequence(int i) {
// allow only one thread to be executed
}
Edit:
Just saw you do not use separate threads.. So run this code to get the delay:
new Handler().postDelayed(new Runnable(){
public void run() {
// do stuff
}}, 1000 * DELAY_IN_SECONDS);
Edit 2:
I think you are searching for something like this:
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
import java.util.concurrent.Callable;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new MyThread((TextView) findViewById(R.id.textView)).start();
}
class MyThread extends Thread implements Runnable {
TextView textView;
MyThread(TextView textView) {
this.textView = textView;
}
#Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnMainUiThread(new Callable() {
#Override
public Object call() throws Exception {
textView.setText("" + System.currentTimeMillis());
return null;
}
});
}
}
void runOnMainUiThread(final Callable callable) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
try {
callable.call();
} catch (Exception e) {
Log.e("MyThread", "runOnMainUiThread: ", e);
}
}
});
}
}
}
If you have any question, feel free to ask :)
Related
I have an audiobook app that I'm currently working on. If the book has audio, the controller will be shown. If not, it'll only show the text. I want to switch the chapters just by swiping at the text. I'm currently using a RelativeLayout and the text is wrapped in a ScrollView. I read that I should use ViewPager. But I was wondering if I could just keep using the RelativeLayout and ScrollView.
player.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/mainbg">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/m_tab_color"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<LinearLayout
android:id="#+id/player_footer_bg"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#FFFFFF"
android:gravity="center"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/linearButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp">
<ImageButton
android:id="#+id/btnRepeat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:background="#null"
android:src="#drawable/btn_repeat"
tools:ignore="ContentDescription" />
<ImageButton
android:id="#+id/btnShuffle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:background="#null"
android:src="#drawable/btn_shuffle"
tools:ignore="ContentDescription" />
<ImageButton
android:id="#+id/btnNext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerVertical="true"
android:layout_toEndOf="#+id/btnPlay"
android:background="#null"
android:src="#drawable/btn_next"
tools:ignore="ContentDescription" />
<ImageButton
android:id="#+id/btnPlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_margin="5dp"
android:background="#drawable/btn_play"
android:src="#drawable/pause"
tools:ignore="ContentDescription" />
<ImageButton
android:id="#+id/btnPrevious"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toStartOf="#+id/btnPlay"
android:background="#null"
android:src="#drawable/btn_prev"
tools:ignore="ContentDescription" />
</RelativeLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout
android:id="#+id/ad_view_container"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<RelativeLayout
android:id="#+id/ads_startapp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone">
</RelativeLayout>
</LinearLayout>
</LinearLayout>
<RelativeLayout
android:id="#+id/sec_ssekbar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#id/player_footer_bg"
android:layout_centerVertical="true"
android:background="#00ffffff"
android:paddingLeft="7dp"
android:paddingRight="7dp">
<SeekBar
android:id="#+id/songProgressBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:progressTint="#E94C3D"
android:thumb="#drawable/pointer"
android:thumbTint="#E94C3D"
android:thumbOffset="8dp"/>
<TextView
android:id="#+id/songCurrentDurationLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/songProgressBar"
android:gravity="start"
android:text="#string/current_duration"
android:textColor="#color/black"
android:textStyle="bold" />
<TextView
android:id="#+id/songTotalDurationLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_below="#+id/songProgressBar"
android:gravity="end"
android:text="#string/total_duration"
android:textColor="#color/black"
android:textStyle="bold" />
</RelativeLayout>
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#+id/sec_ssekbar"
android:layout_below="#+id/toolbar"
android:layout_centerInParent="true"
android:layout_marginStart="3dp"
android:layout_marginTop="3dp"
android:layout_marginEnd="3dp"
android:layout_marginBottom="3dp"
android:background="#B3FFFFFF">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/text_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="3dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="3dp"
android:gravity="center"
android:text="#string/app_name"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#color/black"
android:textStyle="bold" />
<TextView
android:id="#+id/text_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="5dp"
android:text="#string/app_name"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#color/black" />
</LinearLayout>
</ScrollView>
</RelativeLayout>
MusicPlayActivity.java
public class MusicPlayActivity extends AppCompatActivity implements OnCompletionListener, SeekBar.OnSeekBarChangeListener {
Toolbar toolbar;
private ImageButton btnPlay;
private ImageButton btnRepeat;
private ImageButton btnShuffle;
private MediaPlayer mp;
ImageView img_song;
private int currentSongIndex = 0;
private boolean isShuffle = false;
private boolean isRepeat = false;
String[] allArrayImage, allArrayMusicCatName, allArrayMusicShare;
String[] allArrayMusicId, allArrayMusicCatId, allArrayMusicurl, allArrayMusicName, allArrayMusicDuration, allArrayMusicDesc;
int position = currentSongIndex;
int music_id;
private SeekBar songProgressBar;
private TextView songCurrentDurationLabel;
private TextView songTotalDurationLabel;
private Utilities utils;
private Handler mHandler = new Handler();
private Menu menu;
DatabaseHandler db;
String mp3id, mp3catid, mp3name, mp3url, mp3duration, mp3desc, mp3shareurl, mp3image, mp3catname;
private ActionClickItem actionClickItem;
private InterstitialAd mInterstitialAd;
private int btNextClicked = 1;
private AdsObj adsObj;
private StartAppAd startAppAd;
private boolean runClickExecuted;
private AdView adView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.player);
MobileAds.initialize(this, new OnInitializationCompleteListener() {
#Override
public void onInitializationComplete(InitializationStatus initializationStatus) {}
});
btnPlay = findViewById(R.id.btnPlay);
ImageButton btnNext = findViewById(R.id.btnNext);
ImageButton btnPrevious = findViewById(R.id.btnPrevious);
btnRepeat = findViewById(R.id.btnRepeat);
btnShuffle = findViewById(R.id.btnShuffle);
TextView songTitleLabel = findViewById(R.id.text_title);
TextView songDesc = findViewById(R.id.text_description);
img_song = findViewById(R.id.image);
songProgressBar = findViewById(R.id.songProgressBar);
songCurrentDurationLabel = findViewById(R.id.songCurrentDurationLabel);
songTotalDurationLabel = findViewById(R.id.songTotalDurationLabel);
//imageView = (ImageView)findViewById(R.id.full_image);
// imageLoader=new ImageLoader(this);
db = new DatabaseHandler(this);
toolbar = this.findViewById(R.id.toolbar);
toolbar.setTitle(Constant.MUSIC_NAME);
this.setSupportActionBar(toolbar);
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
utils = new Utilities();
mp = new MediaPlayer();
Intent i = getIntent();
music_id = i.getIntExtra("POSITION", 0);
allArrayImage = i.getStringArrayExtra("MP3_IMAGE");
allArrayMusicCatName = i.getStringArrayExtra("MP3_CATNAME");
allArrayMusicShare = i.getStringArrayExtra("MP3_SHARE");
allArrayMusicId = i.getStringArrayExtra("MP3_CID");
allArrayMusicCatId = i.getStringArrayExtra("MP3_CATID");
allArrayMusicurl = i.getStringArrayExtra("MP3_URL");
allArrayMusicName = i.getStringArrayExtra("MP3_NAME");
allArrayMusicDuration = i.getStringArrayExtra("MP3_DURATION");
allArrayMusicDesc = i.getStringArrayExtra("MP3_DISCRIPTION");
position = getPositionFromArray(String.valueOf(music_id));
Log.e("POSITIO", "" + position);
playSong(position);
songProgressBar.setOnSeekBarChangeListener(this);
mp.setOnCompletionListener(this);
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_paush);
}
}
}
});
btnNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
btNextClicked++;
if ((btNextClicked % 3 == 0)) {
actionItemClicked(new ActionClickItem() {
#Override
public void runClick() {
// check if next song is there or not
if (position < (allArrayMusicurl.length - 1)) {
playSong(position + 1);
position = position + 1;
} else {
// play first song
playSong(0);
position = 0;
}
}
});
} else {
// check if next song is there or not
if (position < (allArrayMusicurl.length - 1)) {
position = position + 1;
playSong(position + 1);
} else {
// play first song
playSong(0);
position = 0;
}
}
}
});
btnPrevious.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
if (position > 0) {
playSong(position - 1);
position = position - 1;
} else {
// play last song
playSong(allArrayMusicurl.length - 1);
position = allArrayMusicurl.length - 1;
}
}
});
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);
}
}
});
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);
}
}
});
//int songIndex = i.getIntExtra("songIndex", 0);
// Displaying Song title
String songTitle = allArrayMusicName[position];
songTitleLabel.setText(songTitle);
toolbar.setTitle(songTitle);
String musicUrl = allArrayMusicurl[position];
if(musicUrl.equals(".")){
songProgressBar.setVisibility(View.GONE);
songCurrentDurationLabel.setVisibility(View.GONE);
songTotalDurationLabel.setVisibility(View.GONE);
RelativeLayout linearButton = findViewById(R.id.linearButton);
linearButton.setVisibility(View.GONE);
}
#SuppressLint("CutPasteId") FrameLayout frameAds1 = findViewById(R.id.ad_view_container);
AdsAssistants adsAssistants = new AdsAssistants(this);
adsObj = adsAssistants.getSessionAdsObj();
if (adsObj != null) {
if (adsObj.getCurrentActivatedAds().equals(AdsConfig.ADS_ADMOB)) {
frameAds1.setVisibility(View.VISIBLE);
adsAssistants.createAdmobBanner(frameAds1, adsObj.getADS_ADMOB_BANNER());
} else {
startAppAd = new StartAppAd(this);
#SuppressLint("CutPasteId") FrameLayout frameAds = findViewById(R.id.ad_view_container);
frameAds.setVisibility(View.VISIBLE);
adsAssistants.createStartAppBanner(frameAds);
}
}
}
public void actionItemClicked(ActionClickItem actionClickItemParam) {
actionClickItem = actionClickItemParam;
if (adsObj == null) {
actionClickItem.runClick();
} else {
if (adsObj.getCurrentActivatedAds().equals(AdsConfig.ADS_ADMOB)) {
if (mInterstitialAd != null && mInterstitialAd.isLoaded()) {
mInterstitialAd.show();
} else {
actionClickItem.runClick();
generateInterstitialAd();
}
} else {
startAppAd.loadAd(new AdEventListener() {
#Override
public void onReceiveAd(Ad ad) {
}
#Override
public void onFailedToReceiveAd(Ad ad) {
// actionClickItem.runClick();
}
});
StartAppAd.disableAutoInterstitial();
startAppAd.showAd(new AdDisplayListener() {
#Override
public void adHidden(Ad ad) {
if(!runClickExecuted){
runClickExecuted = true;
actionClickItem.runClick();
}
Log.d("YWV", "Action clicked");
}
#Override
public void adDisplayed(Ad ad) {
}
#Override
public void adClicked(Ad ad) {
}
#Override
public void adNotDisplayed(Ad ad) {
}
});
}
}
}
private void generateInterstitialAd() {
mInterstitialAd = new InterstitialAd(this);
mInterstitialAd.setAdUnitId(adsObj.getADS_ADMOB_INTERSTITIALS());
mInterstitialAd.setAdListener(new AdListener() {
#Override
public void onAdLoaded() {
// mNextLevelButton.setEnabled(true);
}
#Override
public void onAdFailedToLoad(int errorCode) {
// mNextLevelButton.setEnabled(true);
}
#Override
public void onAdClosed() {
// Proceed to the next level.
//finish();
//showDialogApp();
actionClickItem.runClick();
generateInterstitialAd();
}
});
AdRequest adRequestIn = new AdRequest.Builder().build();
mInterstitialAd.loadAd(adRequestIn);
}
#Override
protected void onActivityResult(int requestCode,
int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == 100) {
position = Objects.requireNonNull(data.getExtras()).getInt("songIndex");
// play selected song
playSong(position);
}else if(resultCode == 11){
runClickExecuted = false;
}
}
public void playSong(int songIndex) {
// Play song
try {
// if(needResetFirst){
mp.reset();
// }
mp.setDataSource(allArrayMusicurl[songIndex]);
mp.prepare();
mp.start();
// // Displaying Song title
TextView songTitleLabel = findViewById(R.id.text_title);
String songTitle = allArrayMusicName[songIndex];
songTitleLabel.setText(songTitle);
toolbar.setTitle(songTitle);
TextView songDesc = findViewById(R.id.text_description);
String songDescd = allArrayMusicDesc[songIndex];
songDesc.setText(songDescd);
// Toast.makeText(getApplicationContext(), img_name,Toast.LENGTH_SHORT).show();
// imageLoader.DisplayImage(Constant.SERVER_IMAGE_UPFOLDER1+img_name, imageView);
// Log.e("IMAGEPATH", ""+Constant.SERVER_IMAGE_UPFOLDER1+img_name);
// Toast.makeText(getApplicationContext(), Constant.SERVER_IMAGE_UPFOLDER1+img_name,Toast.LENGTH_SHORT).show();
// Changing Button Image to pause image
btnPlay.setImageResource(R.drawable.btn_paush);
songProgressBar.setProgress(0);
songProgressBar.setMax(100);
// Updating progress bar
updateProgressBar();
// set Progress bar values
} catch (IllegalArgumentException | IllegalStateException | IOException e) {
e.printStackTrace();
}
}
#Override
public void onCompletion(MediaPlayer arg0) {
// check for repeat is ON or OFF
if (isRepeat) {
// repeat is on play same song again
playSong(position);
} else if (isShuffle) {
// shuffle is on - play a random song
Random rand = new Random();
position = rand.nextInt((allArrayMusicurl.length - 1) + 1);
playSong(position);
} else {
// no repeat or shuffle ON - play next song
if (position < (allArrayMusicurl.length - 1)) {
playSong(position + 1);
position = position + 1;
} else {
// play first song
playSong(0);
position = 0;
}
}
}
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
if (mp != null) {
mp.reset();
mp.release();
mp = null;
mHandler.removeCallbacks(mUpdateTimeTask);
}
setResult(RESULT_OK);
finish();
}
public void updateProgressBar() {
mHandler.postDelayed(mUpdateTimeTask, 100);
}
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 = utils.getProgressPercentage(currentDuration, totalDuration);
//Log.d("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) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// remove message Handler from updating progress bar
mHandler.removeCallbacks(mUpdateTimeTask);
}
#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();
}
public void AddtoFav(int position) {
mp3id = allArrayMusicId[position];
// mp3catid=allArrayMusicCatId[position];
mp3catname = allArrayMusicCatName[position];
mp3url = allArrayMusicurl[position];
mp3image = allArrayImage[position];
mp3name = allArrayMusicName[position];
mp3duration = allArrayMusicDuration[position];
mp3desc = allArrayMusicDesc[position];
// mp3shareurl=allArrayMusicShare[position];
db.AddtoFavorite(new Pojo(mp3id, mp3catid, mp3catname, mp3url, mp3image, mp3name, mp3duration, mp3desc, mp3shareurl));
Toast.makeText(getApplicationContext(), "Added to Favorite", Toast.LENGTH_SHORT).show();
// fabfav.setImageDrawable(getResources().getDrawable(R.drawable.fav_hover));
}
//remove from favorite
public void RemoveFav(int position) {
mp3id = allArrayMusicId[position];
db.RemoveFav(new Pojo(mp3id));
Toast.makeText(getApplicationContext(), "Removed from Favorite", Toast.LENGTH_SHORT).show();
// fabfav.setImageDrawable(getResources().getDrawable(R.drawable.fav_hover));
}
public void FirstFav() {
mp3id = allArrayMusicId[position];
List<Pojo> pojolist = db.getFavRow(mp3id);
if (pojolist.size() == 0) {
menu.getItem(0).setIcon(getResources().getDrawable(R.drawable.fav));
} else {
if (pojolist.get(0).getMp3Id().equals(mp3id)) {
menu.getItem(0).setIcon(getResources().getDrawable(R.drawable.fav_hover));
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_mp3, menu);
this.menu = menu;
//for when 1st item of view pager is favorite mode
FirstFav();
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
case R.id.menu_fav:
mp3id = allArrayMusicId[position];
List<Pojo> pojolist = db.getFavRow(mp3id);
if (pojolist.size() == 0) {
AddtoFav(position);//if size is zero i.e means that record not in database show add to favorite
menu.getItem(0).setIcon(getResources().getDrawable(R.drawable.fav_hover));
} else {
if (pojolist.get(0).getMp3Id().equals(mp3id)) {
RemoveFav(position);
}
menu.getItem(0).setIcon(getResources().getDrawable(R.drawable.fav));
}
return true;
case R.id.menu_share:
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.putExtra(Intent.EXTRA_TEXT, "Listen to this verse from " + Constant.APP_NAME + "\n" + "http://play.google.com/store/apps/details?id=" + getPackageName());
sharingIntent.setType("text/plain");
startActivity(Intent.createChooser(sharingIntent, "Share Link"));
return true;
default:
return super.onOptionsItemSelected(menuItem);
}
}
public int getPositionFromArray(String id) {
return Arrays.asList(allArrayMusicId).indexOf(id);
}
#Override
public void onResume() {
super.onResume();
if (adView != null) {
adView.resume();
}
}
/** Called when leaving the activity */
#Override
public void onPause() {
if (adView != null) {
adView.pause();
}
super.onPause();
}
/** Called before the activity is destroyed */
#Override
public void onDestroy() {
super.onDestroy();
if (mp != null) {
mp.reset();
mp.release();
mHandler.removeCallbacks(mUpdateTimeTask);
mp = null;
}
finish();
if (adView != null) {
adView.destroy();
}
}
}
Thank you in advance !
You can detect gestures on any View by attaching an onTouchListener to it.
In your case however, you are trying to detect swiping gestures, therefore the best solution is to create a gesture detector class by extending an onTouchListener like in this tutorial (step 4):
https://www.tutorialspoint.com/how-to-handle-right-to-left-and-left-to-right-swipe-gestures-on-android
After doing this, you can easily attach the swipe-detector class to any of your views as:
textView.setOnTouchListener(new OnSwipeTouchListener(MainActivity.this) {
#Override
public void onSwipeLeft() {
super.onSwipeLeft();
// do something
}
#Override
public void onSwipeRight() {
super.onSwipeRight();
// do something
}
});
Have you tried to add and OnSwipeTouchListener like here https://stackoverflow.com/a/12938787/4330467?
Relativelayout should not be the issue
I have 5 audio files a,b,c,d,e
When the user clicks the play button it should play audio files from a to e one after another.
public class MainActivity extends AppCompatActivity {
Button play,stop;
MediaPlayer mp;
MediaPlayer mp2;
MediaPlayer mp3;
MediaPlayer mp4;
MediaPlayer mp5;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
play = findViewById(R.id.play);
stop = findViewById(R.id.stop);
}
public void Play(View view){
StopPlaying();
mp= MediaPlayer.create(MainActivity.this,R.raw.a);
mp2= MediaPlayer.create(MainActivity.this,R.raw.b);
mp3= MediaPlayer.create(MainActivity.this,R.raw.c);
mp4= MediaPlayer.create(MainActivity.this,R.raw.d);
mp5= MediaPlayer.create(MainActivity.this,R.raw.e);
int i = 0;
while (i<10){
i++;
mp.start();
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp2.start();
mp2.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp3.start();
mp3.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp4.start();
mp4.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp5.start();
mp5.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
}
});
}
});
}
});
}
});
}
});
}
}
private void StopPlaying(){
if (mp != null) {
mp.stop();
mp.release();
mp = null;
}
if (mp2 != null) {
mp2.stop();
mp2.release();
mp2 = null;
}
if (mp3 != null) {
mp3.stop();
mp3.release();
mp3 = null;
}
if (mp4 != null) {
mp4.stop();
mp4.release();
mp4 = null;
}
if (mp5 != null) {
mp5.stop();
mp5.release();
mp5 = null;
}
}
public void Stop(View viw){
mp.stop();
mp2.stop();
mp3.stop();
mp4.stop();
mp5.stop();
}
}
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#afc3d7"
xmlns:android="http://schemas.android.com/apk/res/android">
<EditText
android:id="#+id/from"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:textStyle="bold"
android:ems="10"
android:inputType="number"
/>
<EditText
android:id="#+id/to"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:textStyle="bold"
android:ems="10"
android:inputType="number"
/>
<EditText
android:id="#+id/times"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:ems="10"
android:textStyle="bold"
android:inputType="number"
/>
<Button
android:id="#+id/play"
android:layout_width="175dp"
android:layout_height="50dp"
android:onClick="Play"
android:text="Play" />
<Button
android:id="#+id/stop"
android:layout_width="175dp"
android:onClick="Stop"
android:layout_height="50dp"
android:text="Stop" />
</LinearLayout>
But what I want is it should play them like 10 times,
(after e is played, it should again start from a toe)
like from a toe and then again from a toe and then again.....repeat this 10 times
It's like repeating a song in a music player once it is finished, the only difference is I am repeating multiple audio files in a sequence.
I have tried using for loop and while loop but none of them seem to work...
Here is my code
Use media player in the below format
Uri myUri = ....; // initialize Uri here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(getApplicationContext(), myUri);
mediaPlayer.prepare();
mediaPlayer.start();
Doing this way you won't have to create 5 different media players. When your first audio file finishes, then in your onCompleteListener, just change the DataSource of the media player and start it again
create an array like this :
private final int[] resID = { R.raw.chimes, R.raw.chord, R.raw.ding,
R.raw.notify, R.raw.recycle, R.raw.ringin, R.raw.ringout,
R.raw.tada };
int from,to,times,songPosition,timesPosition=0;
and then on click
songPosition = from;
play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
playSong(songPosition);
}
});
private void playSong(int position) {
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer.release();
}
}
mediaPlayer = new MediaPlayer();
mediaPlayer = MediaPlayer.create(getApplicationContext(), resID[position]);
mediaPlayer.start();
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
if(timesPosition<times){
if(songsPosition<=to){
songsPosition = songsPosition + 1;
playSong(songsPosition)
}else{
songPosition = from;
timesPosition + timesPosition+1;
playSong(songsPosition)
}
}
}
});
}
I am trying to use a for loop inside of an onClickListener for a button. But if I use the cursorCountvariable as condition it does not execute any of the code in the onClick() method. If I exchange cursorCount with a fixed value like 5it works perfectly fine. I can also access the value of cursorCountat any given point before the for loop. cursorCountis increased every time a specific event occurs, which works fine. Button definition:
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="Previous"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/button"
app:layout_constraintHorizontal_bias="0.181"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/activity_main_webview"
app:layout_constraintVertical_bias="0.556" />
Activity/onCreate:
public class MainActivity extends AppCompatActivity {
private WebView webView;
private static final int MY_PERMISSIONS_RECORD_AUDIO = 693;
TextView noteText;
TextView pitchText;
String midiString;
int osmdMidiValue = 1;
int playedMidiValue = 1;
public int cursorCount;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
noteText = findViewById(R.id.noteText);
pitchText = findViewById(R.id.textView);
// Check if permission is not granted
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.RECORD_AUDIO)
!= PackageManager.PERMISSION_GRANTED) {
// Shows Pop-up
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.RECORD_AUDIO},
MY_PERMISSIONS_RECORD_AUDIO);
}
else{
AudioDispatcher dispatcher =
AudioDispatcherFactory.fromDefaultMicrophone(22050, 1024, 0);
PitchDetectionHandler pdh = new PitchDetectionHandler() {
#Override
public void handlePitch(PitchDetectionResult res, AudioEvent e) {
final float pitchInHz = res.getPitch();
runOnUiThread(new Runnable() {
#Override
public void run() {
processPitch(pitchInHz);
if(pitchInHz!=-1) {
pitchText.setText(String.valueOf(pitchInHz));
}
}
});
}
};
AudioProcessor pitchProcessor =
new PitchProcessor(PitchProcessor.PitchEstimationAlgorithm.FFT_YIN, 22050, 1024, pdh);
dispatcher.addAudioProcessor(pitchProcessor);
Thread audioThread = new Thread(dispatcher, "Audio Thread");
audioThread.start();
}
startDisplay();
final Button startbtn = findViewById(R.id.button);
startbtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
getMidiValue();
}
});
final Button resetbtn = findViewById(R.id.button2);
resetbtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
webView = findViewById(R.id.activity_main_webview);
webView.loadUrl("javascript:resetCursor()");
cursorCount=0;
}
});
final Button prevbtn = findViewById(R.id.button3);
prevbtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
int test = cursorCount;
webView = findViewById(R.id.activity_main_webview);
webView.loadUrl("javascript:resetCursor()");
for(int prevCount=0; prevCount<test; prevCount++){
webView.loadUrl("javascript:nextValue()");
}
}
});
}
cursorCountValue is changed here:
public void checkValue(){
if(osmdMidiValue == playedMidiValue){
webView.loadUrl("javascript:nextValue()");
cursorCount++;
getMidiValue();
}
else if(osmdMidiValue == 0){
webView.loadUrl("javascript:nextValue()");
cursorCount++;
getMidiValue();
}
}
Use local variable and not a field, so that every block starts with desired count.
After searching in life cycle I have found that my application needs to use the destroy(); method. However, when I implement this the application doesn't close. I am trying to apply this to the button exitButton. If someone could direct me in the right direction then that would be great.
MainActivity.java
package com.webcraftbd.radio;
import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
static String radioTitle = "Android Live Radio";
static String radioStreamURL = "http://stream.infowars.com:80";
Button playButton;
Button pauseButton;
Button stopButton;
Button exitbutton;
TextView statusTextView, bufferValueTextView;
NotificationCompat.Builder notifyBuilder;
private RadioUpdateReceiver radioUpdateReceiver;
private RadioService radioServiceBinder;
//Notification
private static final int NOTIFY_ME_ID=12345;
private NotificationManager notifyMgr=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView titleTextView = (TextView) this.findViewById(R.id.titleTextView);
titleTextView.setText(radioTitle);
playButton = (Button) this.findViewById(R.id.PlayButton);
pauseButton = (Button) this.findViewById(R.id.PauseButton);
stopButton = (Button) this.findViewById(R.id.StopButton);
playButton.setEnabled(true);
pauseButton.setEnabled(false);
stopButton.setEnabled(false);
pauseButton.setVisibility(View.INVISIBLE);
statusTextView = (TextView) this.findViewById(R.id.StatusDisplayTextView);
notifyMgr=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
showNotification();
// Bind to the service
Intent bindIntent = new Intent(this, RadioService.class);
bindService(bindIntent, radioConnection, Context.BIND_AUTO_CREATE);
startService(new Intent(this, RadioService.class));
}
public void onClickPlayButton(View view) {
radioServiceBinder.play();
}
public void onClickPauseButton(View view) {
radioServiceBinder.pause();
}
public void onClickStopButton(View view) {
radioServiceBinder.stop();
}
public void onClicexitbutton(View view) {
super.finish();
super.onDestroy();
radioServiceBinder.onDestroy();
radioServiceBinder.stop();
radioServiceBinder.stopService(getParentActivityIntent());
}
#Override
protected void onPause() {
super.onPause();
if (radioUpdateReceiver != null)
unregisterReceiver(radioUpdateReceiver);
}
#Override
protected void onResume() {
super.onResume();
/* Register for receiving broadcast messages */
if (radioUpdateReceiver == null) radioUpdateReceiver = new RadioUpdateReceiver();
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_CREATED));
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_DESTROYED));
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_STARTED));
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_PREPARED));
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_PLAYING));
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_PAUSED));
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_STOPPED));
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_COMPLETED));
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_ERROR));
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_BUFFERING_START));
registerReceiver(radioUpdateReceiver, new IntentFilter(RadioService.MODE_BUFFERING_END));
}
protected void onDestroy(){
super.onDestroy();
}
/* Receive Broadcast Messages from RadioService */
private class RadioUpdateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(RadioService.MODE_CREATED)) {
showNotification();
}
else if (intent.getAction().equals(RadioService.MODE_DESTROYED)) {
clearNotification();
}
else if (intent.getAction().equals(RadioService.MODE_STARTED)) {
playButton.setEnabled(false);
pauseButton.setEnabled(false);
stopButton.setEnabled(true);
playButton.setVisibility(View.VISIBLE);
pauseButton.setVisibility(View.INVISIBLE);
updateStatus("Buffering...");
}
else if (intent.getAction().equals(RadioService.MODE_PREPARED)) {
playButton.setEnabled(true);
pauseButton.setEnabled(false);
stopButton.setEnabled(false);
playButton.setVisibility(View.VISIBLE);
pauseButton.setVisibility(View.INVISIBLE);
updateStatus("Rady");
}
else if (intent.getAction().equals(RadioService.MODE_BUFFERING_START)) {
updateStatus("Buffering...");
}
else if (intent.getAction().equals(RadioService.MODE_BUFFERING_END)) {
updateStatus("Playing");
}
else if (intent.getAction().equals(RadioService.MODE_PLAYING)) {
playButton.setEnabled(false);
pauseButton.setEnabled(true);
stopButton.setEnabled(true);
playButton.setVisibility(View.INVISIBLE);
pauseButton.setVisibility(View.VISIBLE);
showNotification();
updateStatus("Playing");
}
else if(intent.getAction().equals(RadioService.MODE_PAUSED)) {
playButton.setEnabled(true);
pauseButton.setEnabled(false);
stopButton.setEnabled(true);
playButton.setVisibility(View.VISIBLE);
pauseButton.setVisibility(View.INVISIBLE);
updateStatus("Paused");
}
else if(intent.getAction().equals(RadioService.MODE_STOPPED)) {
playButton.setEnabled(true);
pauseButton.setEnabled(false);
stopButton.setEnabled(false);
playButton.setVisibility(View.VISIBLE);
pauseButton.setVisibility(View.INVISIBLE);
updateStatus("Stopped");
clearNotification();
}
else if(intent.getAction().equals(RadioService.MODE_COMPLETED)) {
playButton.setEnabled(true);
pauseButton.setEnabled(false);
stopButton.setEnabled(false);
playButton.setVisibility(View.VISIBLE);
pauseButton.setVisibility(View.INVISIBLE);
updateStatus("Stopped");
}
else if(intent.getAction().equals(RadioService.MODE_ERROR)) {
playButton.setEnabled(true);
pauseButton.setEnabled(false);
stopButton.setEnabled(false);
playButton.setVisibility(View.VISIBLE);
pauseButton.setVisibility(View.INVISIBLE);
updateStatus("Error");
}
}
}
public void updateStatus(String status) {
try {
if(notifyBuilder!=null && notifyMgr!=null) {
notifyBuilder.setContentText(status).setWhen(0);
notifyMgr.notify(NOTIFY_ME_ID,notifyBuilder.build());
}
statusTextView.setText(status);
}
catch(Exception e) {
e.printStackTrace();
}
}
public void showNotification() {
notifyBuilder = new NotificationCompat.Builder(this).setSmallIcon(R.drawable.ic_launcher).setContentTitle(radioTitle).setContentText("");
Intent resultIntent = new Intent(this, MainActivity.class);
resultIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
notifyBuilder.setContentIntent(resultPendingIntent);
notifyMgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notifyMgr.notify(NOTIFY_ME_ID, notifyBuilder.build());
}
public void clearNotification() {
notifyMgr.cancel(NOTIFY_ME_ID);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.about:
Intent i = new Intent(this, AboutActivity.class);
startActivity(i);
return true;
}
return super.onOptionsItemSelected(item);
}
// Handles the connection between the service and activity
private ServiceConnection radioConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
radioServiceBinder = ((RadioService.RadioBinder)service).getService();
}
public void onServiceDisconnected(ComponentName className) {
radioServiceBinder = null;
}
};
}
enter code here
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#4a4a4a"
tools:context=".MainActivity" >
<LinearLayout
android:id="#+id/player_header_bg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true" >
<TextView
android:id="#+id/titleTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="48dp"
android:gravity="center"
android:text="Classic Christmas Radio"
android:textAlignment="center"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#c0413b"
android:textSize="40sp" />
</LinearLayout>
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:layout_marginBottom="120dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="110dp"
android:src="#drawable/cover" />
<TextView
android:id="#+id/StatusDisplayTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/PauseButton"
android:layout_alignLeft="#+id/imageView1"
android:layout_alignRight="#+id/imageView1"
android:gravity="center"
android:text="Unknown" />
<Button
android:id="#+id/PauseButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#id/StatusDisplayTextView"
android:layout_alignParentBottom="true"
android:layout_marginBottom="0.0dip"
android:background="#drawable/btn_pause"
android:onClick="onClickPauseButton" />
<Button
android:id="#+id/PlayButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#id/StatusDisplayTextView"
android:layout_alignParentBottom="true"
android:layout_marginBottom="0.0dip"
android:background="#drawable/btn_play"
android:onClick="onClickPlayButton" />
<Button
android:id="#+id/StopButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignRight="#id/StatusDisplayTextView"
android:layout_marginBottom="0.0dip"
android:background="#drawable/btn_stop"
android:onClick="onClickStopButton" />
<Button
android:id="#+id/exitbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/StatusDisplayTextView"
android:layout_centerHorizontal="true"
android:text="Button" />
</RelativeLayout>
RadioService.java
package com.webcraftbd.radio;
import java.io.IOException;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnInfoListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class RadioService extends Service implements OnErrorListener, OnCompletionListener, OnPreparedListener, OnInfoListener {
private MediaPlayer mediaPlayer;
private String radioStreamURL = MainActivity.radioStreamURL;
public static final String MODE_CREATED = "CREATED";
public static final String MODE_DESTROYED = "DESTROYED";
public static final String MODE_PREPARED = "PREPARED";
public static final String MODE_STARTED = "STARTED";
public static final String MODE_PLAYING = "PLAYING";
public static final String MODE_PAUSED = "PAUSED";
public static final String MODE_STOPPED = "STOPPED";
public static final String MODE_COMPLETED = "COMPLETED";
public static final String MODE_ERROR = "ERROR";
public static final String MODE_BUFFERING_START = "BUFFERING_START";
public static final String MODE_BUFFERING_END = "BUFFERING_END";
private boolean isPrepared = false;
private final IBinder binder = new RadioBinder();
#Override
public void onCreate() {
/* Create MediaPlayer when it starts for first time */
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnInfoListener(this);
sendBroadcast(new Intent(MODE_CREATED));
}
#Override
public void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
mediaPlayer.reset();
isPrepared = false;
sendBroadcast(new Intent(MODE_DESTROYED));
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
sendBroadcast(new Intent(MODE_STARTED));
/* Starts playback at first time or resumes if it is restarted */
if(mediaPlayer.isPlaying())
sendBroadcast(new Intent(MODE_PLAYING));
else if(isPrepared) {
sendBroadcast(new Intent(MODE_PAUSED));
}
else
prepare();
return Service.START_STICKY;
}
#Override
public void onPrepared(MediaPlayer _mediaPlayer) {
/* If radio is prepared then start playback */
sendBroadcast(new Intent(MODE_PREPARED));
isPrepared = true;
play();
}
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
/* When no stream found then complete the playback */
mediaPlayer.stop();
mediaPlayer.reset();
isPrepared = false;
sendBroadcast(new Intent(MODE_COMPLETED));
}
public void prepare() {
/* Prepare Async Task - starts buffering */
try {
mediaPlayer.setDataSource(radioStreamURL);
mediaPlayer.prepareAsync();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void play() {
if(isPrepared) {
mediaPlayer.start();
System.out.println("RadioService: play");
sendBroadcast(new Intent(MODE_PLAYING));
}
else
{
sendBroadcast(new Intent(MODE_STARTED));
prepare();
}
}
public void pause() {
mediaPlayer.pause();
System.out.println("RadioService: pause");
sendBroadcast(new Intent(MODE_PAUSED));
}
public void stop() {
mediaPlayer.stop();
mediaPlayer.reset();
isPrepared = false;
System.out.println("RadioService: stop");
sendBroadcast(new Intent(MODE_STOPPED));
}
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
/* Check when buffering is started or ended */
if(what == MediaPlayer.MEDIA_INFO_BUFFERING_START) {
sendBroadcast(new Intent(MODE_BUFFERING_START));
}
else if(what == MediaPlayer.MEDIA_INFO_BUFFERING_END) {
sendBroadcast(new Intent(MODE_BUFFERING_END));
}
return false;
}
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
sendBroadcast(new Intent(MODE_ERROR));
switch (what) {
case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
Log.v("ERROR","MEDIA ERROR NOT VALID FOR PROGRESSIVE PLAYBACK " + extra);
break;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
Log.v("ERROR","MEDIA ERROR SERVER DIED " + extra);
break;
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
Log.v("ERROR","MEDIA ERROR UNKNOWN " + extra);
break;
}
return false;
}
#Override
public IBinder onBind(Intent intent) {
return binder;
}
/* Allowing activity to access all methods of RadioService */
public class RadioBinder extends Binder {
RadioService getService() {
return RadioService.this;
}
}
}
Ok, after developing some pseudo and some logic, I have noticed that Andorid doesn't have an exit method in the way that you're hoping. When first reading the question I didn't realise that it was Android as I was multi-tasking. As you may notice, almost every android application doesn't have an exit button, and there is a reason for this. The reason being that Android is supposedly meant to load and unload applications through the OS, hence why you don't do it. If the user wanted to exit the application, they would do what they do with every other, enter the multi-tasking menu and swipe it off. Please read the following for more information: http://android.nextapp.com/site/fx/doc/exit
Recently, I uploaded simple Radio Application to the Google Play Store. And it has kinda a lot of downloaders. But it was really simple and I want to extend that Radio App to the next level. What it has for now is only ONE radio station to choose. No next, no previous buttons to choose from more Radio Stations. What I really want to do is to extend it so the user can listen for more Radio Stations(not one, but about 6 more or so). So maybe I need to add Previous and Next buttons to the app so the user can actually do that. But there is a problem - I don't know how to do this.
This is MainActivity.java class :
public class MainActivity extends Activity {
static String radioTitle = "RadioLink1";
static String radioStreamURL = "http://108.61.73.117:8124";
Button playButton;
Button pauseButton;
Button stopButton;
TextView statusTextView, bufferValueTextView;
NotificationCompat.Builder notifyBuilder;
private SeekBar volumeSeekbar;
private AudioManager audioManager = null;
private RadioUpdateReceiver radioUpdateReceiver;
private RadioService radioServiceBinder;
// Notification
private static final int NOTIFY_ME_ID = 12345;
private NotificationManager notifyMgr = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView titleTextView = (TextView) this
.findViewById(R.id.titleTextView);
titleTextView.setText(radioTitle);
playButton = (Button) this.findViewById(R.id.PlayButton);
pauseButton = (Button) this.findViewById(R.id.PauseButton);
stopButton = (Button) this.findViewById(R.id.StopButton);
playButton.setEnabled(true);
pauseButton.setEnabled(false);
stopButton.setEnabled(false);
pauseButton.setVisibility(View.INVISIBLE);
initControls();
statusTextView = (TextView) this
.findViewById(R.id.StatusDisplayTextView);
notifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
showNotification();
setFont();
// Bind to the service
Intent bindIntent = new Intent(this, RadioService.class);
bindService(bindIntent, radioConnection, Context.BIND_AUTO_CREATE);
startService(new Intent(this, RadioService.class));
}
private void initControls() {
try {
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
volumeSeekbar.setMax(audioManager
.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
volumeSeekbar.setProgress(audioManager
.getStreamVolume(AudioManager.STREAM_MUSIC));
volumeSeekbar
.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar arg0) {
}
#Override
public void onStartTrackingTouch(SeekBar arg0) {
}
#Override
public void onProgressChanged(SeekBar arg0,
int progress, boolean arg2) {
audioManager.setStreamVolume(
AudioManager.STREAM_MUSIC, progress, 0);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
public void setFont() {
// Font path
String fontPath = "fonts/Christmas Card.ttf";
// text view label
TextView txtGhost = (TextView) findViewById(R.id.titleTextView);
// Loading Font Face
Typeface tf = Typeface.createFromAsset(getAssets(), fontPath);
// Applying font
txtGhost.setTypeface(tf);
}
public void onClickPlayButton(View view) {
radioServiceBinder.play();
}
public void onClickPauseButton(View view) {
radioServiceBinder.pause();
}
public void onClickStopButton(View view) {
radioServiceBinder.stop();
}
#Override
protected void onPause() {
super.onPause();
if (radioUpdateReceiver != null)
unregisterReceiver(radioUpdateReceiver);
}
#Override
protected void onResume() {
super.onResume();
/* Register for receiving broadcast messages */
if (radioUpdateReceiver == null)
radioUpdateReceiver = new RadioUpdateReceiver();
registerReceiver(radioUpdateReceiver, new IntentFilter(
RadioService.MODE_CREATED));
registerReceiver(radioUpdateReceiver, new IntentFilter(
RadioService.MODE_DESTROYED));
registerReceiver(radioUpdateReceiver, new IntentFilter(
RadioService.MODE_STARTED));
registerReceiver(radioUpdateReceiver, new IntentFilter(
RadioService.MODE_PREPARED));
registerReceiver(radioUpdateReceiver, new IntentFilter(
RadioService.MODE_PLAYING));
registerReceiver(radioUpdateReceiver, new IntentFilter(
RadioService.MODE_PAUSED));
registerReceiver(radioUpdateReceiver, new IntentFilter(
RadioService.MODE_STOPPED));
registerReceiver(radioUpdateReceiver, new IntentFilter(
RadioService.MODE_COMPLETED));
registerReceiver(radioUpdateReceiver, new IntentFilter(
RadioService.MODE_ERROR));
registerReceiver(radioUpdateReceiver, new IntentFilter(
RadioService.MODE_BUFFERING_START));
registerReceiver(radioUpdateReceiver, new IntentFilter(
RadioService.MODE_BUFFERING_END));
}
/* Receive Broadcast Messages from RadioService */
private class RadioUpdateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(RadioService.MODE_CREATED)) {
showNotification();
} else if (intent.getAction().equals(RadioService.MODE_DESTROYED)) {
clearNotification();
} else if (intent.getAction().equals(RadioService.MODE_STARTED)) {
playButton.setEnabled(false);
pauseButton.setEnabled(false);
stopButton.setEnabled(true);
playButton.setVisibility(View.VISIBLE);
pauseButton.setVisibility(View.INVISIBLE);
updateStatus("Buffering...");
} else if (intent.getAction().equals(RadioService.MODE_PREPARED)) {
playButton.setEnabled(true);
pauseButton.setEnabled(false);
stopButton.setEnabled(false);
playButton.setVisibility(View.VISIBLE);
pauseButton.setVisibility(View.INVISIBLE);
updateStatus("Rady");
} else if (intent.getAction().equals(
RadioService.MODE_BUFFERING_START)) {
updateStatus("Buffering...");
} else if (intent.getAction().equals(
RadioService.MODE_BUFFERING_END)) {
updateStatus("Playing");
} else if (intent.getAction().equals(RadioService.MODE_PLAYING)) {
playButton.setEnabled(false);
pauseButton.setEnabled(true);
stopButton.setEnabled(true);
playButton.setVisibility(View.INVISIBLE);
pauseButton.setVisibility(View.VISIBLE);
showNotification();
updateStatus("Playing");
} else if (intent.getAction().equals(RadioService.MODE_PAUSED)) {
playButton.setEnabled(true);
pauseButton.setEnabled(false);
stopButton.setEnabled(true);
playButton.setVisibility(View.VISIBLE);
pauseButton.setVisibility(View.INVISIBLE);
updateStatus("Paused");
} else if (intent.getAction().equals(RadioService.MODE_STOPPED)) {
playButton.setEnabled(true);
pauseButton.setEnabled(false);
stopButton.setEnabled(false);
playButton.setVisibility(View.VISIBLE);
pauseButton.setVisibility(View.INVISIBLE);
updateStatus("Stopped");
clearNotification();
} else if (intent.getAction().equals(RadioService.MODE_COMPLETED)) {
playButton.setEnabled(true);
pauseButton.setEnabled(false);
stopButton.setEnabled(false);
playButton.setVisibility(View.VISIBLE);
pauseButton.setVisibility(View.INVISIBLE);
updateStatus("Stopped");
} else if (intent.getAction().equals(RadioService.MODE_ERROR)) {
playButton.setEnabled(true);
pauseButton.setEnabled(false);
stopButton.setEnabled(false);
playButton.setVisibility(View.VISIBLE);
pauseButton.setVisibility(View.INVISIBLE);
updateStatus("Error");
}
}
}
public void updateStatus(String status) {
try {
if (notifyBuilder != null && notifyMgr != null) {
notifyBuilder.setContentText(status).setWhen(0);
notifyMgr.notify(NOTIFY_ME_ID, notifyBuilder.build());
}
statusTextView.setText(status);
} catch (Exception e) {
e.printStackTrace();
}
}
public void showNotification() {
notifyBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(radioTitle).setContentText("");
Intent resultIntent = new Intent(this, MainActivity.class);
resultIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT);
notifyBuilder.setContentIntent(resultPendingIntent);
notifyMgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notifyMgr.notify(NOTIFY_ME_ID, notifyBuilder.build());
}
public void clearNotification() {
notifyMgr.cancel(NOTIFY_ME_ID);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.about:
Intent i = new Intent(this, AboutActivity.class);
startActivity(i);
return true;
}
return super.onOptionsItemSelected(item);
}
// Handles the connection between the service and activity
private ServiceConnection radioConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
radioServiceBinder = ((RadioService.RadioBinder) service)
.getService();
}
public void onServiceDisconnected(ComponentName className) {
radioServiceBinder = null;
}
};
}
and RadioService.java class:
public class RadioService extends Service implements OnErrorListener, OnCompletionListener, OnPreparedListener, OnInfoListener {
private MediaPlayer mediaPlayer;
private String radioStreamURL = MainActivity.radioStreamURL;
public static final String MODE_CREATED = "CREATED";
public static final String MODE_DESTROYED = "DESTROYED";
public static final String MODE_PREPARED = "PREPARED";
public static final String MODE_STARTED = "STARTED";
public static final String MODE_PLAYING = "PLAYING";
public static final String MODE_PAUSED = "PAUSED";
public static final String MODE_STOPPED = "STOPPED";
public static final String MODE_COMPLETED = "COMPLETED";
public static final String MODE_ERROR = "ERROR";
public static final String MODE_BUFFERING_START = "BUFFERING_START";
public static final String MODE_BUFFERING_END = "BUFFERING_END";
private boolean isPrepared = false;
private final IBinder binder = new RadioBinder();
#Override
public void onCreate() {
/* Create MediaPlayer when it starts for first time */
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnInfoListener(this);
sendBroadcast(new Intent(MODE_CREATED));
}
#Override
public void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
mediaPlayer.reset();
isPrepared = false;
sendBroadcast(new Intent(MODE_DESTROYED));
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
sendBroadcast(new Intent(MODE_STARTED));
/* Starts playback at first time or resumes if it is restarted */
if(mediaPlayer.isPlaying())
sendBroadcast(new Intent(MODE_PLAYING));
else if(isPrepared) {
sendBroadcast(new Intent(MODE_PAUSED));
}
else
prepare();
return Service.START_STICKY;
}
#Override
public void onPrepared(MediaPlayer _mediaPlayer) {
/* If radio is prepared then start playback */
sendBroadcast(new Intent(MODE_PREPARED));
isPrepared = true;
play();
}
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
/* When no stream found then complete the playback */
mediaPlayer.stop();
mediaPlayer.reset();
isPrepared = false;
sendBroadcast(new Intent(MODE_COMPLETED));
}
public void prepare() {
/* Prepare Async Task - starts buffering */
try {
mediaPlayer.setDataSource(radioStreamURL);
mediaPlayer.prepareAsync();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void play() {
if(isPrepared) {
mediaPlayer.start();
System.out.println("RadioService: play");
sendBroadcast(new Intent(MODE_PLAYING));
}
else
{
sendBroadcast(new Intent(MODE_STARTED));
prepare();
}
}
public void pause() {
mediaPlayer.pause();
System.out.println("RadioService: pause");
sendBroadcast(new Intent(MODE_PAUSED));
}
public void stop() {
mediaPlayer.stop();
mediaPlayer.reset();
isPrepared = false;
System.out.println("RadioService: stop");
sendBroadcast(new Intent(MODE_STOPPED));
}
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
/* Check when buffering is started or ended */
if(what == MediaPlayer.MEDIA_INFO_BUFFERING_START) {
sendBroadcast(new Intent(MODE_BUFFERING_START));
}
else if(what == MediaPlayer.MEDIA_INFO_BUFFERING_END) {
sendBroadcast(new Intent(MODE_BUFFERING_END));
}
return false;
}
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
sendBroadcast(new Intent(MODE_ERROR));
switch (what) {
case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
Log.v("ERROR","MEDIA ERROR NOT VALID FOR PROGRESSIVE PLAYBACK " + extra);
break;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
Log.v("ERROR","MEDIA ERROR SERVER DIED " + extra);
break;
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
Log.v("ERROR","MEDIA ERROR UNKNOWN " + extra);
break;
}
return false;
}
#Override
public IBinder onBind(Intent intent) {
return binder;
}
/* Allowing activity to access all methods of RadioService */
public class RadioBinder extends Binder {
RadioService getService() {
return RadioService.this;
}
}
}
And this layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#4a4a4a"
tools:context=".MainActivity" >
<LinearLayout
android:id="#+id/player_header_bg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true" >
<TextView
android:id="#+id/titleTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="48dp"
android:background="#color/bgcolor"
android:gravity="center"
android:text="Classic Christmas Radio"
android:textAlignment="center"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#c0413b"
android:textSize="40sp" />
</LinearLayout>
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:layout_marginBottom="120dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="110dp"
android:src="#drawable/cover" />
<TextView
android:id="#+id/StatusDisplayTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/PauseButton"
android:layout_alignLeft="#+id/imageView1"
android:layout_alignRight="#+id/imageView1"
android:gravity="center"
android:text="Unknown" />
<Button
android:id="#+id/PauseButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#id/StatusDisplayTextView"
android:layout_alignParentBottom="true"
android:layout_marginBottom="0.0dip"
android:background="#drawable/btn_pause"
android:onClick="onClickPauseButton" />
<Button
android:id="#+id/PlayButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#id/StatusDisplayTextView"
android:layout_alignParentBottom="true"
android:layout_marginBottom="0.0dip"
android:background="#drawable/btn_play"
android:onClick="onClickPlayButton" />
<Button
android:id="#+id/StopButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignRight="#id/StatusDisplayTextView"
android:layout_marginBottom="0.0dip"
android:background="#drawable/btn_stop"
android:onClick="onClickStopButton" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_toRightOf="#+id/PauseButton"
android:background="#drawable/btn_previous" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_toRightOf="#+id/button1"
android:background="#drawable/btn_next" />
</RelativeLayout>
I actually didn't write all the code and that's why I can't get my head straight to the problem solution. I just extended given code for my needs but now I don't really now how to implement Previous and Next buttons to navigate through different Radio Stations. What I want from you guys is to maybe give me some ideas or just set me on the road how can I add this functionality to this app. How can I get more than one stream (in this case from SHOUTcast) and add this navigation through them. I hope I didn't breaking the StackOverflow rules of asking this kind of question. Thank you and appreciate any help.
UPDATE:
In the MainActivity:
static String radioTitle = "RadioStation1";
static String radioStreamURL = "http://108.61.73.117:8124";
static String radioTitle2 = "RadioStation2";
static String radioStreamURL2 = "http://108.61.73.117:8124";
static String radioTitle3 = "RadioStation3";
static String radioStreamURL3 = "http://108.61.73.117:8124";
...........
nextButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
prevButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
And the RadioService class:
private String radioStreamURL = MainActivity.radioStreamURL;
private String radioStreamURL2 = MainActivity.radioStreamURL2;
private String radioStreamURL3 = MainActivity.radioStreamURL3;
...............
public void prepare() {
/* Prepare Async Task - starts buffering */
try {
mediaPlayer.setDataSource(radioStreamURL);
mediaPlayer.setDataSource(radioStreamURL2);
mediaPlayer.setDataSource(radioStreamURL3);
mediaPlayer.prepareAsync();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Look at your method at RadioService.java
public void prepare() {
/* Prepare Async Task - starts buffering */
try {
mediaPlayer.setDataSource(radioStreamURL);
mediaPlayer.prepareAsync();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Here you set the URL to your radio stream, the fast way to change your code without knowing all your code is to alter radioStreamURL variable.
private String radioStreamURL = MainActivity.radioStreamURL;
If you have some static information about the radios you want to use, just change this String to a List and add all the Radio's URL you want.
Add a Next and Preview button to your layout, set the listener to call your RadioService with this function, something like this:
MainActivity
private static int station = 0;//Not right, just to show
public void onNextStationClicked(){
radioServiceBinder.changeStation(++station);
}
RadioService
public static final String MODE_STATION_CHANGE = "STATION_CHANGE";
public void changeStation(int stationIndex){
radioStreamURL = MainActivity.radioStreamURL.get(stationIndex);
stop();
play();
}
This is just an idea, the code isn't the best but with a little work should work...
UPDATE
Try change your code to this:
RadioService
private List<String> radioStreamURL = new ArrayList<String>
private int radioStreamingIndex = 0;
then on your constructor add this
#Override
public void onCreate() {
radioStreamURL.add(radioStreamURL);
radioStreamURL.add(radioStreamURL2);
radioStreamURL.add(radioStreamURL3);
// etc
}
public void prepare() {
/* Prepare Async Task - starts buffering */
try {
mediaPlayer.setDataSource(radioStreamURL.get(radioStreamingIndex));
mediaPlayer.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
}
}
public void nextStation(){
changeStation(radioStreamingIndex+1);
}
public void prevStation(){
changeStation(radioStreamingIndex-1);
}
private void changeStation(int stationIndex){
if(stationIndex > 0 && stationIndex < radioStreamURL.size()){
radioStreamingIndex = stationIndex;
stop();
play();
}
}
MainActivity
nextButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
radioServiceBinder.nextStation();
}
});
prevButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
radioServiceBinder.prevStation();
}
});
I am not too experience in Android development, but you may need a complex algorithm developed if you would like to follow Spotify and Pandora's steps in the sense that the radio stations are created in relation to the listener's genre, etc.