I was wondering how I can change the position of an ImageButton every second. I want the position to be random each time. I do not know where to start to accomplish this. Any suggestions?
Maybe this will give you some idea
activity_main.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageButton
android:id="#+id/button"
android:layout_width="50dp"
android:layout_height="50dp"
android:text="I am button"/>
</RelativeLayout>
MainActivity.java
package com.com.randombutton;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import java.util.Random;
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ImageButton button = (ImageButton) findViewById(R.id.button);
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
Random rand = new Random();
while (true) {
Log.e("TAG", "thread");
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) button.getLayoutParams();
params.setMargins(rand.nextInt(500), rand.nextInt(500), 0, 0);
try {
Thread.sleep(1000);
} catch (Exception e) {
}
button.post(new Runnable() {
#Override
public void run() {
button.requestLayout(); //has to be called in UI thread
}
});
}
}
});
thread.start();
}
}
The idea is pretty simple. Make a thread, move a view and put it to sleep for 1 second. Probably there are better ways to move the view itself.
Related
I am trying to stream mp3 file from the internet. App successfully started but showing unexpected behavior. The playback doesn't play sound, the play button doesn't changes its icon. The playback stops after showing "please wait message" when it is expected to play the file on clicking the play icon.
Here's my code:
MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.TextView;
import java.util.concurrent.TimeUnit;
import dyanamitechetan.vusikview.VusikView;
public class MainActivity extends AppCompatActivity implements MediaPlayer.OnBufferingUpdateListener, MediaPlayer.OnCompletionListener {
ImageButton imageButton;
SeekBar seekBar;
TextView textView;
VusikView musicView;
MediaPlayer mediaPlayer;
int mediaFileLength;
int realTimeLength;
final Handler handler = new Handler();
#SuppressLint("ClickableViewAccessibility")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
musicView = findViewById(R.id.musicView);
seekBar = findViewById(R.id.seekbar);
seekBar.setMax(99);
seekBar.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if(mediaPlayer.isPlaying()){
SeekBar seekBar = (SeekBar) view;
int playPosition = (mediaFileLength/100)*seekBar.getProgress();
mediaPlayer.seekTo(playPosition);
}
return false;
}
});
imageButton = findViewById(R.id.btn_play_pause);
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final ProgressDialog mDialog = new ProgressDialog(MainActivity.this);
AsyncTask<String,String,String>mp3Play = new AsyncTask<String, String, String>() {
#Override
protected void onPreExecute(){
mDialog.setMessage("Please wait");
mDialog.show();
}
#Override
protected String doInBackground(String... strings) {
try {
mediaPlayer.setDataSource(strings[0]);
mediaPlayer.prepare();
}
catch (Exception ex){
}
return "";
}
#Override
protected void onPostExecute(String s) {
mediaFileLength = mediaPlayer.getDuration();
realTimeLength = mediaFileLength;
if(!mediaPlayer.isPlaying()){
mediaPlayer.start();
imageButton.setImageResource(R.drawable.ic_pause);
} else {
mediaPlayer.pause();
imageButton.setImageResource(R.drawable.ic_play);
}
updateSeekBar();
mDialog.dismiss();
}
};
mp3Play.execute("https://soundcloud.com/theastonshuffle/nasa-feat-kanye-west-santogold-lykke-li-gifted-aston-shuffle-long-mix");
musicView.start();
}
});
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnCompletionListener(this);
}
private void updateSeekBar() {
seekBar.setProgress((int)((float)mediaPlayer.getCurrentPosition() / mediaFileLength*100));
if(mediaPlayer.isPlaying()){
Runnable updater = new Runnable() {
#Override
public void run() {
updateSeekBar();
realTimeLength-=1000;
textView.setText(String.format("%d:%d", TimeUnit.MILLISECONDS.toMinutes(realTimeLength),
TimeUnit.MILLISECONDS.toSeconds(realTimeLength) -
TimeUnit.MILLISECONDS.toSeconds(TimeUnit.MILLISECONDS.toMinutes(realTimeLength))));
}
};
handler.postDelayed(updater,1000);
}
}
#Override
public void onBufferingUpdate(MediaPlayer mediaPlayer, int i) {
seekBar.setSecondaryProgress(i);
}
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
imageButton.setImageResource(R.drawable.ic_play);
musicView.stopNotesFall();
}
}
activity_main.xml
<dyanamitechetan.vusikview.VusikView
android:id="#+id/musicView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<RelativeLayout
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/textTimer"
android:layout_centerHorizontal="true"
android:text="00:00"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageButton
android:layout_below="#id/textTimer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/btn_play_pause"
android:src="#drawable/ic_play"/>
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/btn_play_pause"
android:id="#+id/seekbar"/>
</RelativeLayout>
you APP connect Internet ?
please check manifest is add internet permission
You can use the mediaplay.setdataSource (url);method directly to load
And setmediaplay.prepareAsync (); use asynchronous method to load music
No need to use AsyncTask
This is a part of an app that I am trying to make. I am trying to make a delay that can be set by the user so after each +1 it delays with 500 milliseconds, but soon I figured that i don't even know how to add a simple build in delay, I tried with delay(1000); it gave me Can not resolve method delay(int) then with sleep(1000); same error, then with TimeUnit.SECONDS.sleep(1); and Thread.sleep(1); nothing worked I am missing something fundamental, maybe I need to import something ? this is the whole program
if (v == swt1){
while (counter<2100000000) {
counter++;
}
scoreText.setText(Integer.toString(counter));
scoreText.setBackgroundColor(Color.BLACK);
}
Activity:
package counter.test.my.simplecount;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Switch;
import android.widget.TextView;
import android.app.Activity;
import android.graphics.Color;
public class MainActivity extends Activity implements OnClickListener {
Button btn1;
Button btn2;
Button btn3;
Switch swt1;
TextView textTitle;
EditText scoreText;
int counter = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn1 = (Button)findViewById(R.id.button);
btn2 = (Button)findViewById(R.id.button2);
btn3 = (Button)findViewById(R.id.button3);
swt1 = (Switch)findViewById(R.id.switch1);
scoreText = (EditText)findViewById(R.id.editText);
textTitle = (TextView)findViewById(R.id.textView);
btn1.setOnClickListener(this);
btn2.setOnClickListener(this);
btn3.setOnClickListener(this);
textTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, 34);
}
#Override
public void onClick(View v) {
if (v == btn1){
counter++;
scoreText.setText(Integer.toString(counter));
scoreText.setBackgroundColor(Color.CYAN);
}
if (v == btn2){
counter--;
scoreText.setText(Integer.toString(counter));
scoreText.setBackgroundColor(Color.GREEN);
}
if (v == btn3){
counter = 0;
scoreText.setText(Integer.toString(counter));
scoreText.setBackgroundColor(Color.RED);
if (v == swt1){
while (counter<2100000000) {
counter++;
}
scoreText.setText(Integer.toString(counter));
scoreText.setBackgroundColor(Color.RED);
}
}
}
}
You can use Handler() for delay like
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//Your Aftre delay code
}
},500);
Remember to import this:
import android.os.Handler;
Use the "Handler" with "Runnable" to auto increment a value continuously at some time delay. Here i used "1sec" time dealy.
Find below code snippet for your requirement.
Runnable runnable;
Handler handler;
int delayTimeSec = 1000; //1 Sec
handler = new Handler();
runnable = new Runnable(){
#Override
public void run() {
// Your auto increment logic...
handler.postDelayed(runnable, delayTimeSec);
}
}
handler.postDelayed(runnable, delayTimeSec);
Use thread instead of handler if you have got background tasks.
new Thread(new Runnable() {
#Override
public void run() {
///background calculations
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
//main thread task to update user interface
}
});
}
}).start();
I try to refresh TextView in Android. I am using ExecutorService in my code. When I pushed the "Start refresh" button, after several seconds my app has been stopped by Android system. I have read several topics in stackoverflow.com, but I still cannot understand what I am doing wrong. Here is my code:
MainActivity.java:
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class MainActivity extends Activity {
private static ExecutorService exec;
private static TextView textView;
private static Calendar cal;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.text_field);
cal = new GregorianCalendar();
exec = Executors.newSingleThreadExecutor();
}
private static class Task implements Runnable {
#Override
public void run() {
try {
while(!Thread.currentThread().isInterrupted()) {
textView.setText(cal.getTime().toString());
TimeUnit.SECONDS.sleep(1);
}
}
catch (InterruptedException e) {
return;
}
}
}
public void finish_refresh(View view) {
exec.shutdownNow();
}
public void start_refresh(View view) {
exec.submit(new Task());
}
}
activity_main.xml:
<LinearLayout 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"
tools:context=".MainActivity"
android:orientation="vertical">
<Button android:layout_width="200dp"
android:layout_height="50dp"
android:text="#string/start_refresh"
android:onClick="start_refresh"/>
<Button android:layout_width="200dp"
android:layout_height="50dp"
android:text="#string/finish_refresh"
android:onClick="finish_refresh"/>
<TextView android:layout_height="200dp"
android:layout_width="200dp"
android:layout_marginTop="10dp"
android:id="#+id/text_field" />
</LinearLayout>
You need to use runOnUiThread()
Add following code in your onCreate() method:
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(1000);
runOnUiThread(new Runnable() {
#Override
public void run() {
// update TextView here!
textView.setText(cal.getTime().toString());
}
});
}
} catch (InterruptedException e) { }
}
};
t.start();
I am new to java and andriod and i think that i did something wrong with thread
Program starts without any errors.
I have inserted one button just for test and it shows without problem. Text view doesnt even displays "Hello world" default string.
Here is the code
package com.example.studentservis;
import android.R.string;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;
import java.net.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.io.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.w3c.dom.Text;
public class MainActivity extends Activity {
StringHandler stringHandler = new StringHandler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
thread.run();
TextView txtView = (TextView)this.findViewById(R.id.textView1);
txtView.setText(stringHandler.getString());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
Thread thread = new Thread(){
public void run(){
try {
stringHandler.setString(webRequest());
} catch (Exception e) {
// TODO Auto-generated catch block
stringHandler.setString(e.getMessage());
}
}
};
public String webRequest() throws Exception{
String servisURL = "http://www.sczg.unizg.hr/student-servis/";
Document doc = Jsoup.connect(servisURL).get();
Elements jobNode = doc.select("div.jobBox");
return jobNode.get(0).text();
}
public class StringHandler
{
public String str = "test";
public void setString(String s)
{
str = s;
}
public String getString()
{
return str;
}
}
}
When you start a new Thread, the UI thread won't wait until the new thread is complete. That is the purpose of the Threads.
Here :
thread.run();
When you a start the new thread to update the stringHandler, the UI thread tries to process the next command which is :
txtView.setText(stringHandler.getString());
When the UI thread gets to this, the stringHandler hasn't updated yet, so It's null and thus it will show nothing in the textview.
All you should do is to try to update the textview from the new Thread when it's finished.
Try this:
Thread thread = new Thread(){
public void run(){
try {
stringHandler.setString(webRequest());
} catch (Exception e) {
// TODO Auto-generated catch block
stringHandler.setString(e.getMessage());
}
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView txtView = (TextView)this.findViewById(R.id.textView1);
txtView.setText(stringHandler.getString());
}
});
}
};
You can use a handler or a asyctask for this purpose. Asynctask is easier.
http://developer.android.com/reference/android/os/AsyncTask.html
You can create your own thread but remember to update ui on the ui thread.
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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="166dp"
android:text="Loading..." />
</RelativeLayout>
MainActivity.java
Removed StringHandler cause i felt it was unnecessary in this context.
public class MainActivity extends Activity {
TextView txtView ;
String s;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtView = (TextView)this.findViewById(R.id.textView1); // initialize textview
//txtView.setText(stringHandler.getString());
new Thread(new Runnable() { // thread
#Override
public void run(){
try {
s = webRequest(); // get string
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
runOnUiThread(new Runnable() //run on ui threa
{
public void run()
{
txtView.setText(s); // update ui on the ui thread.
}
});
}
}).start();
}
public String webRequest() throws Exception{ // web request
String servisURL = "http://www.sczg.unizg.hr/student-servis/";
Document doc = Jsoup.connect(servisURL).get();
Elements jobNode = doc.select("div.jobBox");
return jobNode.get(0).text();
}
}
Resulting snap shot
This part of your code : txtView.setText(stringHandler.getString());
should be put after the thread finished.
thread.run(); <------ Start running thread in background
TextView txtView = (TextView)this.findViewById(R.id.textView1);
txtView.setText(stringHandler.getString());
// the textView was set without knowing whether the Thread is finished or not.
// thus, textView is shown as empty, because stringHandler.getString() still has empty string
My suggestion is that you implement it inside an asyncTask, so that you can set the text within onPostExecute()
Good luck ^^
EDIT :
here's some example AsyncTask
private class StringSet extends AsyncTask <Void,Void,Void> {
#Override
protected void doInBackground(Void... params) {
try {
stringHandler.setString(webRequest());
} catch (Exception e) {
stringHandler.setString(e.getMessage());
}
}
#Override
protected void onPostExecute(Void... results) {
txtView.setText(stringHandler.getString());
}
}
And replace your thread.run() with new StringSet().execute();
package com.aviyehuda.test.multithreading;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MultithreadingTest extends Activity {
Button btn;
private Handler myHandler;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.Button01);
}
public void buttonClicked(View v) {
myHandler = new Handler();
MyThread mThread = new MyThread();
mThread.start();
}
class MyThread extends Thread {
#Override
public void run() {
for (int i = 0; i < 30; i++) {
myHandler.post(new NewThreaad(i));
}
}
}
class NewThreaad implements Runnable{
int i;
public NewThreaad(int n) {
i=n;
}
#Override
public void run() {
((TextView) findViewById(R.id.TextView01)).setText("Hello:"+i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
I have code mentioned above but getting result Hello29 on TextView but i want Hello1,Hello2,hello3.................Hello29 one by one automatically
Please give me hint what I am doing wrong
A couple of things.
First, after changing the text, you should call invalidate on the TextView to force a refresh.
Second, to do operation on the UI, you should run that in the UI thread. Use runOnUiThread
Well, the main problem is that you're not appending you are overwriting. Instead of
((TextView) findViewById(R.id.TextView01)).setText("Hello:"+i);
do
TextView tv = ((TextView) findViewById(R.id.TextView01));
String text = tv.getText().toString();
tv.setText(text + " Hello:" + i);
You need to move the 500 ms delay to your for-loop, between posting of messages. I think you're expecting the messages to execute sequentially one after the other, but they don't, which is the reason you just see the result of the last one.