Pause the changing Images when Audio paused - java

I am building an application in which images starts changing when audio is played.
When audio is play (starts) onclick button, the images also start changing with different delays and i can pause my audio as well. The problem which i am facing and getting confuse is that, when i paused my audio,
How can i pause my images as well ,so that when i click the button again,my audio resumes and images starts changing next from where they were paused.
private Button btn_play;
MediaPlayer mp;
int duration;
private ImageView imageView;
Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_names);
int resID = getResources().getIdentifier("audio", "raw", getPackageName());
mp = MediaPlayer.create(NamesOfALLAH.this, resID);
duration = mp.getDuration();
btn_play = (Button) findViewById(R.id.btn_play);
imageView = (ImageView) findViewById(R.id.imageView_Names);
btn_play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mp.isPlaying()) {
mp.pause();
btn_play.setText("Play");
} else {
mp.start();
btn_play.setText("Pause");
changeImage1();
changeImage2();
changeImage3();
changeImage4();
changeImage5();
}
}
});
}
public void changeImage1() {
handler.postDelayed(new Runnable() {
#Override
public void run() {
imageView.setImageResource(R.drawable.a1);
}
}, 6000);
}
public void changeImage2() {
handler.postDelayed(new Runnable() {
#Override
public void run() {
imageView.setImageResource(R.drawable.a2);
}
}, 8000);
}
public void changeImage3() {
handler.postDelayed(new Runnable() {
#Override
public void run() {
imageView.setImageResource(R.drawable.a3);
}
}, 10000);
}
public void changeImage4() {
handler.postDelayed(new Runnable() {
#Override
public void run() {
imageView.setImageResource(R.drawable.a4);
}
}, 11000);
}
public void changeImage5() {
handler.postDelayed(new Runnable() {
#Override
public void run() {
imageView.setImageResource(R.drawable.a5);
}
}, 12000);
}
`

Use an ImageSwitcher, it does some of the work for you. In any case, if you want to create the animation yourself, you must consider all the changes as a whole. For example, you can repost the runnable to the handler. Pseudo-code:
handler.postDelayed(new Runnable() {
#Override
public void run() {
// set the image you want
if (mustContinue)
handler.postDelayed(this, time);
}
}, 10000);
Toggle the boolean mustContinue every time you press the play/pause button.
EDIT:
Check this as an example.

Related

How to display different image after another with Glide?

I want to display an other image after a delay. Here is my code:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView imageView=findViewById(R.id.imageView);
ArrayList<String> test = new ArrayList<String>();
test.add("e");
test.add("a");
if (test.get(0) == "e") {
Glide.with(this)
.load("https://something.something/something.jpg")
.into(imageView);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (test.get(1) == "a") {
Glide.with(this)
.load("https://something.something/something2.jpg")
.into(imageView);
}
}
}
But only the 2nd image apppears if i do that. Any solution?
Create a new method
private void loadImage(String imageLink){
Glide.with(this).load(imageLink).into(imageView);
}
now simply call this where you want to load first image and second image in the same imageView
loadImage("imageLink");
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//Do something after 3sec
loadImage("next ImageLink");
}
}, 3000);
Something like this, you can also modify loadImage method so it can also accept ImageView as a parameter if you want to load images in different ImageView with delay
if (test.get(0) == "e") {
loadImage("https://something.something/something.jpg");
}
if (test.get(1) == "a") {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//Do something after 3sec (3000 = 3 sec)
loadImage("https://something.something/something2.jpg");
}
}, 3000);
}
Hope this will help!
Edit 1:
if you want to load both pics with delay use
if (test.get(0) == "e") {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//Do something after 3sec (3000 = 3 sec)
loadImage("https://something.something/something.jpg"); // image 1
}
}, 3000);
}
if (test.get(1) == "a") {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//Do something after 3sec (3000 = 3 sec)
loadImage("https://something.something/something2.jpg"); // image 2
}
}, 3000);
}

How do I loop threw my mediaPlayer on a delay without having sounds playing over one another?

I am trying to make an app that will tell the user "Ready Go" it will give the user two seconds to get set up and then a random amount of time after that it will say ready and a random amount of time after that it will say go. I got this part to work but now I want to loop it to where the user only has to press the button once and it'll keep playing. However, when I put it in a loop it'll run through it all at once and it ends up playing all the "Ready Go's" at the same time. Is there something I can do to prevent this?
public class MainActivity extends AppCompatActivity {
public Context context;
MediaPlayer mediaPlayer;
MediaPlayer mediaPlayer1;
public void start (View view) {
play();
}
public void play() {
//When I put a loop here I will get the audio playing over each other, I
//also tried to put it in the start method but I get the same result. Is
//there another way I should be going about this? Thanks for the help!
long range = 2000L;
Random r = new Random();
long number = (long) (r.nextDouble() * range);
long range1 = 1500L;
Random rand = new Random();
long number1 = (long) (r.nextDouble() * range);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
Log.i("Info", "Ready");
mediaPlayer.start();
}
}, 2000 + number);
Handler handler3 = new Handler();
handler3.postDelayed(new Runnable() {
#Override
public void run() {
Log.i("Info", "Go");
mediaPlayer1.start();
}
}, 2200 + number + number1);
}
}
Use CompletionListener instead of loop, First Call playAudio1 method in play(). code is below,
mediaPlayer1.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
playAudio2();
}
});
mediaPlayer2.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
playAudio1();
}
});
playAudio1 and playAudio2 methods,
private void playAudio2() {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Log.i("Info", "Go");
mediaPlayer1.start();
}
}, 2200 + number + number1);
}
private void playAudio1() {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Log.i("Info", "Ready");
mediaPlayer1.start();
}
}, 2000 + number);
}
Use mediaPlayer.prepare() or mediaPlayer.prepareAsync() before mediaPlayer.start().
Just put this in onCreate method
mediaPlayer1.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
play();
}
});
This will call the play method again once it completes the mediaPlayer1. playing.

Show x Imageviews sequentially for y seconds

Trying to get the following ;
ImageView x is shown for y seconds. Then, x is Invisible again and a different ImageView (z) is shown for y seconds. And so on..
I've got :
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.series_onthouden);
hideAllImages();
showImage(3, 2000);
showImage(4, 1000);
}
public void showImage(int color, final int sec) {
Thread thread = new Thread() {
#Override
public void run() {
try {
Thread.sleep(sec);
} catch (InterruptedException e) {
}
runOnUiThread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < myImagebtns.length; i++) {
((ImageView) findViewById(myImagebtns[i]))
.setVisibility(View.INVISIBLE);
}
}
});
}
};
if (!thread.isAlive()){
((ImageView) findViewById(myImagebtns[color])).setVisibility(View.VISIBLE);
thread.start();
}
}
It works for the first color.. But also shows the second simultaniously. The second color should be shown when the first turns invisible (after x seconds).
ty
You could try using a Handler like the example below:
Handler handler = new Handler();
im1.setVisibility(View.VISIBLE);
handler.postDelayed(new Runnable() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
im1.setVisibility(View.INVISIBLE);
im2.setVisibility(View.VISIBLE);
}
});
}
},500);
where 500 is the delay between events.
Repeat postDelayed calls for as many images as necessary.
Hope this helps!

Calling from wrong thread exception

I am trying to develop an application, that uses threads to implement slideshow. I am retrieving the image path from SQLite and displaying them on the ImageView. The problem, where I got struck is, I got confused and so I am unable to understand, from which thread I am calling images() method, where I am actually implementing the slideshow.
I got the Logcat as follows -
09-03 13:47:00.248: E/AndroidRuntime(10642): FATAL EXCEPTION: Thread-151
09-03 13:47:00.248: E/AndroidRuntime(10642): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
09-03 13:47:00.248: E/AndroidRuntime(10642): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:5908)
09-03 13:47:00.248: E/AndroidRuntime(10642): at com.example.fromstart.MainActivity.images(MainActivity.java:90)
09-03 13:47:00.248: E/AndroidRuntime(10642): at com.example.fromstart.MainActivity$2.run(MainActivity.java:59)
09-03 13:47:00.248: E/AndroidRuntime(10642): at java.lang.Thread.run(Thread.java:841)
MainActivity.java:
public class MainActivity extends Activity
{
ImageView jpgView;
TextView tv;
//adapter mDbAdapter;
adapter info = new adapter(this);
String path;
Handler smHandler = new Handler()
{
public void handleMessage(Message msg)
{
TextView myTextView =
(TextView)findViewById(R.id.textView1);
myTextView.setText("Button Pressed");
}
};
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
jpgView = (ImageView)findViewById(R.id.imageView1);
tv = (TextView) findViewById(R.id.textView1);
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
final Runnable runnable = new Runnable()
{
public void run()
{
images();
}
};
int delay = 1000; // delay for 1 sec.
int period = 15000; // repeat every 4 sec.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
smHandler.post(runnable);
}
}, delay, period);
Thread mythread = new Thread(runnable);
mythread.start();
return true;
}
public void handleMessage(Message msg)
{
String string = "sample";
TextView myTextView = (TextView)findViewById(R.id.textView1);
myTextView.setText(string);
}
public void images()
{
try
{
for(int i=0;i<=20;i++)
{
path = info.getpath();
Bitmap bitmap = BitmapFactory.decodeFile(path);
jpgView.setImageBitmap(bitmap);
}
}
catch(NullPointerException er)
{
String ht=er.toString();
Toast.makeText(getApplicationContext(), ht, Toast.LENGTH_LONG).show();
}
}
}
I am a newbie to android, just now started working on Threads. If you find any mistakes in my code, please point out those and please suggest me, the right way to deal with this problem.
Thanks in advance.
UPDATE:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Handler mHandler = new Handler();
// Create runnable for posting
runOnUiThread(new Runnable()
{
public void run()
{
images();
}
});
int delay = 1000; // delay for 1 sec.
int period = 15000; // repeat every 4 sec.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
images();
}
}, delay, period);
}
public void images()
{
try
{
Toast.makeText(getApplicationContext(), "1", Toast.LENGTH_LONG).show();
path = info.getpath();
Toast.makeText(getApplicationContext(), "2", Toast.LENGTH_LONG).show();
Bitmap bitmap = BitmapFactory.decodeFile(path);
Toast.makeText(getApplicationContext(), "3", Toast.LENGTH_LONG).show();
jpgView.setImageBitmap(bitmap);
Toast.makeText(getApplicationContext(), "4", Toast.LENGTH_LONG).show();
}
catch(NullPointerException er)
{
String ht=er.toString();
Toast.makeText(getApplicationContext(), ht, Toast.LENGTH_LONG).show();
}
}
}
You cannot update/access ui from from a thread.
You have this
public void run()
{
images();
}
And in images you have
jpgView.setImageBitmap(bitmap);
You need to use runOnUiThread for updating ui.
runOnUiThread(new Runnable() {
#Override
public void run() {
// do something
}
});
TimerTask also runs on a different thread. So you have use a Handler for updati ui.
You can use a handler.
Edit:
Handler m_handler;
Runnable m_handlerTask ;
m_handler = new Handler();
m_handlerTask = new Runnable()
{
#Override
public void run() {
// do something. call images()
m_handler.postDelayed(m_handlerTask, 1000);
}
};
m_handlerTask.run();
If you still wish to use a timer task use runOnUiThread
timer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
runOnUiThread(new Runnable() {
#Override
public void run() {
images();
}
});
}
}, delay, period);
To update UI from any other Thread you must use
runOnUiThread(<Runnable>);
which will update your UI.
Example:
runOnUiThread(
new Runnable()
{
// do something on UI thread Update UI
});

Use timertask to update clock each X seconds?

I'm trying to update my digital clock using timertask. I have created a function called updateClock() which sets the hours and minutes to the current time but I haven't been able to get it to run periodically. From what I've read in other answers one of the best options is to use timertask however I haven't been able to make any example I found online work inside an Android activity.
This is what I've written so far:
public class MainActivity extends Activity {
TextView hours;
TextView minutes;
Calendar c;
int cur_hours;
int cur_minutes;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.clock_home);
hours = (TextView) findViewById(R.id.hours);
minutes = (TextView) findViewById(R.id.minutes);
updateClock();
}
public void updateClock() {
c = Calendar.getInstance();
hours.setText("" + c.get(Calendar.HOUR));
minutes.setText("" + c.get(Calendar.MINUTE));
}
public static void init() throws Exception {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
updateClock(); // ERROR
}
}, 0, 1 * 5000);
}
}
How can I make it work?
Use runOnUiThread for updating Ui from Timer Thread
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
MainActivity.this.runOnUiThread (new Runnable() {
public void run() {
updateClock(); // call UI update method here
}
}));
}
}, 0, 1 * 5000);
}
if you just need updates every minute, you can also listen to the ACTION_TIME_TICK broadcast event.
private boolean timeReceiverAttached;
private final BroadcastReceiver timeReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateClock();
}
};
private Handler handler = new Handler();
#Override
protected void onResume() {
super.onResume();
updateClock();
if (!timeReceiverAttached) {
timeReceiverAttached = true;
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
registerReceiver(timeReceiver, filter, null, handler);
}
}
#Override
protected void onPause() {
super.onPause();
if (timeReceiverAttached) {
unregisterReceiver(timeReceiver);
timeReceiverAttached = false;
}
}
OR, periodically post the Runnable to the Handler of UI thread. Also, pause and resume tasks to save battery.
public class MyActivity extends Activity {
private final Handler mHandler = new Handler();
private final Timer mTimer = new Timer();
#Override
protected void onResume() {
super.onResume();
mTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
mHandler.post(new Runnable() {
#Override
public void run() {
//---update UI---
}
});
}
},0,5000);
}
#Override
protected void onPause() {
super.onPause();
mTimer.cancel();
}
}

Categories

Resources