I'm trying to make simple app on Android.
EDIT
New code:
package com.sirseni.simpleandroidwebviewexample;
/**
* Created by otsma on 26.05.2017.
*/
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class Hack extends Activity {
Button b1;
private ProgressDialog progress;
// Splash screen timer
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hack);
b1 = (Button) findViewById(R.id.button);
}
private int jumpTime = 0;
public void download() {
//initializing progress dialog
progress = new ProgressDialog(this);
progress.setMessage("Changing Files");
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progress.setProgress(0);
progress.show();
final int totalProgressTime = 100;
//creating a thread
final Thread t = new Thread() {
#Override
public void run() {
while(jumpTime < totalProgressTime) {
try {
jumpTime += 5;
// if we have to update the view, we have to execute the code in UI thread. runOnUiThread() gives us that functionality
runOnUiThread(new Runnable() {
#Override
public void run() {
// updating view in UI thread
progress.setProgress(jumpTime);
progress.setMessage("Hello" + jumpTime);
}
});
sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
t.start();
}}
Now it's working like that, user tap on button, the progressdialog is appearing but everytime it is 0% and 0/100. How to fix it? For example after 20 seconds will be 100% and how to make, that when it reach 100% the new activity is starting?
Thanks guys for help!
Please update the download method by the below code:
private int jumpTime = 0;
public void download() {
//initializing progress dialog
progress = new ProgressDialog(this);
progress.setMessage("Changing Files");
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progress.setProgress(0);
progress.show();
final int totalProgressTime = 100;
//creating a thread
final Thread t = new Thread() {
#Override
public void run() {
while(jumpTime < totalProgressTime) {
try {
jumpTime += 5;
// if we have to update the view, we have to execute the code in UI thread. runOnUiThread() gives us that functionality
runOnUiThread(new Runnable() {
#Override
public void run() {
// updating view in UI thread
progress.setProgress(jumpTime);
progress.setMessage("Hello" + jumpTime);
}
});
sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
t.start();
}
Try this.
progress = new ProgressDialog(this);
progress.setMessage("Changing Files");
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progress.setMax(100);
progress.setProgress(0);
progress.show();
int jumpTime = 0;
Handler ha = new Handler();
ha.post(new Runnable() {
#Override
public void run() {
//call function
jumpTime += 5;
progress.setProgress(jumpTime);
progress.setMessage("Hello" + jumpTime);
if(jumpTime < 100){
ha.postDelayed(this, 200);
}
else{
//do code
}
}
});
Related
I have a problem with a simple android application. It has a SurfaceView with simple drawing, but activity orientation sometimes seems not to be changed after a screen rotation.
This is how an activity looks in the portrait mode:
landscape mode:
but sometimes, when I rotate the screen, an activity looks like this in the portrait mode:
MainActivity.java:
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback
{
private Thread mGameThread;
private GameApp mGameApp;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SurfaceView mainView = (SurfaceView)findViewById(R.id.mainView);
SurfaceHolder holder = mainView.getHolder();
holder.addCallback(this);
mGameApp = new GameApp(getResources(), holder);
}
#Override
public void surfaceCreated(SurfaceHolder holder)
{
mGameThread = new Thread(new Runnable()
{
#Override
public void run()
{
mGameApp.run();
}
});
mGameThread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
mGameApp.setSurfaceSize(width, height);
}
#Override
public void surfaceDestroyed(SurfaceHolder holder)
{
boolean retry = true;
mGameApp.setRunning(false);
while (retry)
{
try
{
mGameThread.join();
retry = false;
}
catch (InterruptedException e)
{
}
}
}
}
GameApp.java:
package com.example.myapplication;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.view.SurfaceHolder;
public class GameApp
{
private Resources mResources;
private SurfaceHolder mSurfaceHolder;
private int mCanvasHeight = 1;
private int mCanvasWidth = 1;
private volatile boolean mRun = false;
public GameApp(Resources resources, SurfaceHolder surfaceHolder)
{
mResources = resources;
mSurfaceHolder = surfaceHolder;
}
public void setSurfaceSize(int width, int height)
{
synchronized (mSurfaceHolder)
{
mCanvasWidth = width;
mCanvasHeight = height;
}
}
public void run()
{
setRunning(true);
while (mRun)
{
Canvas canvas = null;
try
{
canvas = mSurfaceHolder.lockCanvas(null);
synchronized (mSurfaceHolder)
{
if (mRun && canvas != null)
{
draw(canvas);
}
}
}
finally
{
if (canvas != null)
{
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
public void setRunning(boolean b)
{
mRun = b;
}
private void draw(Canvas canvas)
{
canvas.drawColor(Color.GREEN);
Drawable cellImage = mResources.getDrawable(R.drawable.cell);
final float cellWidth = mCanvasWidth / 6;
final float cellHeight = mCanvasHeight / 6;
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 6; j++)
{
float x = i * cellWidth;
float y = j * cellHeight;
cellImage.setBounds(Math.round(x), Math.round(y), Math.round(x + cellWidth), Math.round(y + cellHeight));
cellImage.draw(canvas);
}
}
}
}
Eventual answer:
The problem is that you are doing a while loop in your GameApp's thread that locks the canvas and then unlocks without any long blocking or sleep in between.
The SurfaceHolder#lockCanvas documentation states:
If null is not returned, this function internally holds a lock until the corresponding unlockCanvasAndPost(Canvas) call, preventing SurfaceView from creating, destroying, or modifying the surface while it is being drawn.
So this means that the destroy code which is run from main thread needs to run between the unlockCanvasAndPost and the next lockCanvas. But since you have no sleep or even other code in between (except for the while condintion check), the chance of this happening is very small, and - depending on the device - could practically take forever.
To fix this, put a sleep in your game app to achieve the wanted framerate,
in it's most simple from this could look like this.
class GameApp
...
while (mRun)
{
Canvas canvas = null;
try
{
canvas = mSurfaceHolder.lockCanvas(null);
synchronized (mSurfaceHolder)
{
if (mRun && canvas != null)
{
draw(canvas);
}
}
}
finally
{
if (canvas != null)
{
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
// Add some sleep time depending on how fast you want to refresh
try {
Thread.sleep(1000/60); //~60 fps
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Original answer 1: What could have helped in case of handling orientation changes
Seems like the surface is not always re-drawn on a config change.
Try overriding the onConfigurationChanged method of the activity and then triggering a re-layout of the surface
in MainActivity.java:
...
#Override
public void onConfigurationChanged(Configuration newConfig) {
// You should save (SurfaceView)findViewById(R.id.mainView) in a field for better performance, but I'm putting it here for shorter code.
SurfaceView mainView = (SurfaceView)findViewById(R.id.mainView);
mainView.invalidate();
mainView.requestLayout();
}
...
More info on these methods nicely explained here:
Usage of forceLayout(), requestLayout() and invalidate()
Original answer 2: A way to check if your threads are blocked
Another possibility is that you have a thread lock issue on your main thread.
For checking that you could change your activity like this:
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
private Thread mGameThread;
private GameApp mGameApp;
private static View currMainView;
private static Thread logPosterThread = new Thread(new Runnable() {
volatile boolean mainLogDone = true;
#Override
public void run() {
Runnable mainThreadLogger = new Runnable() {
#Override
public void run() {
Log.d("THREAD_CHECK", "Main Thread is ok");
mainLogDone = true;
}
};
while (true) {
try {
int sleepTime = 1000;
Thread.sleep(sleepTime);
if (currMainView != null) {
if (mainLogDone) {
mainLogDone = false;
Log.d("THREAD_CHECK", "Main Thread doing post");
currMainView.post(mainThreadLogger);
} else {
Log.w("THREAD_CHECK", "Main Thread did not run the runnable within " + sleepTime + "ms");
mainLogDone = true;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
static {
logPosterThread.start();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final SurfaceView mainView = (SurfaceView) findViewById(R.id.mainView);
currMainView = mainView;
SurfaceHolder holder = mainView.getHolder();
holder.addCallback(this);
mGameApp = new GameApp(getResources(), holder);
}
#Override
public void onPause() {
...
And then see if those logs still get printed with 1000ms in between when the issue happens.
When you try this, you will see that actually the main thread is hanging when this happens.
"How do I make a CountDown show at the same moment my Button gets enabled ?"
Additional info regarding the button: the Buttons Job is it to click 5 times through a stringarray displayed in a Textview to then get disabled for 5 seconds to do the same task again.
so ..I would like a CountDown to visually show those 5 seconds(the time the button is enabled) count down for the User to see.
sadly I dont have an idea how to connect my Button with an CountDown to let it know its supposed to count down at that particular time the Button is enabled.
Also I would like for the CountDown to start everytime the Button gets enabled.
I looked into https://developer.android.com/reference/android/os/CountDownTimer
but it doesnt seem to have a solution for that particular case.
thats my Code for the Button as of now :
next_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (currentnumber == list.length) {
currentnumber = 0;
}
if (Curclicks == mod - 1) {
next_button.setEnabled(false);
display.setText(list[currentnumber]);
currentnumber++;
handler.postDelayed(new Runnable() {
#Override
public void run() {
//the button will unlock after the delay specified
next_button.setEnabled(true);
Curclicks = 0;
}
}, delay);
} else {
display.setText(list[currentnumber]);
currentnumber++;
}
Curclicks++;
}
});
UI Thread code can solve that ? :
private void runThread() {
new Thread() {
public void run() {
while (delay == 5000) { //delay = 5000 ( 5 secs)
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
timer.setText("" + delay);//timer=TxtView
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
Here is an example of how you can use the postDelayed() method of the Handler to create a count down. I have purposefully left the code a bit verbose so you can go through it step-by-step in order to see what is happening.
Create a few class variables and constants.
private static final long COUNT_DOWN_TICKS = 100l;
private static final long COUNT_DOWN_FINISH = 5000l;
private long countdownElapsed = 0l;
private Handler mCountDownHandler = new Handler();
COUNT_DOWN_FINISH is set to 5000 --> 5 sec. But can be changed to anything you need. Also I use COUNT_DOWN_TICKS set to 100 --> 0.1 sec, just in case you want to display a more precise count down.
From your OnClick() method just call startCountDown() to get the count down started.
private void startCountDown() {
try {
countdownElapsed = 0l;
next_button.setEnabled(false);
displayCountDown();
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private Runnable mCountDownRunnable = new Runnable() {
#Override
public void run() {
countdownElapsed = countdownElapsed + COUNT_DOWN_TICKS;
if(countdownElapsed >= COUNT_DOWN_FINISH){
releaseCountDownHandler();
next_button.setEnabled(true);
}
else{
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
long secFull = countdownElapsed % 1000;
if(secFull == 0){
runOnUiThread(new Runnable() {
#Override
public void run() {
displayCountDown();
}
});
}
}
};
private void releaseCountDownHandler() {
try {
if(mCountDownRunnable != null) {
mCountDownHandler.removeCallbacks(mCountDownRunnable);
}
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private void displayCountDown(){
long t = (COUNT_DOWN_FINISH - countdownElapsed)/1000;
String myTime = String.valueOf(t);
timer.setText(myTime);
}
In order to dispose of the Runnable properly you will want to call releaseCountDownHandler() from the onPause() method. This is just a short running Thread, but it should still not be ignored.
I prefer the Handler with the postDelay() method to the Thread.sleep() method--something about putting any thread to sleep is disconcerting. Also note that it is a good idea to get accustom to checking the elapsed time condition with ">=" RATHER than "==" depending on the implementation (e.g. you use SystemClock.elapsedRealtime() instead) the condition just might miss the exact value!
EDIT
Somewhere under the definition of your Activity class (for this example I will call it MainActivity) you will need to declare a few variables. Since they are being defined inside the class and NOT inside a method the are referred to as "class variables" and they have a scope of entire class when defined "private".
public class MainActivity extends AppCompatActivity {
//class variables
private static final long COUNT_DOWN_TICKS = 100l;
private static final long COUNT_DOWN_FINISH = 5000l;
private long countdownElapsed = 0l;
private Handler mCountDownHandler = new Handler();
private Button next_button;
private TextView timer;
....
}
You probably have declared the onClick() method inside the onCreate() method of the MainActivity class. So just add the following code:
next_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startCountDown();
}
Everything else I provide are method inside the MainActivity class...NOT inside any other method. So below the onCreate() method add all methods that I previously posted.
It will look something like this:
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
//class variables
private static final long COUNT_DOWN_TICKS = 100l;
private static final long COUNT_DOWN_FINISH = 5000l;
private long countdownElapsed = 0l;
private Handler mCountDownHandler = new Handler();
private Button next_button;
private TextView timer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// you must compensate for the actual layout for your activity
setContentView(R.layout.activity_main);
// you must compensate for the actual id of the TextView
timer = findViewById(R.id.tvTimer);
// you must compensate for the actual id of the Button
next_button = findViewById(R.id.btnNext);
next_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startCountDown();
}
});
}
private void startCountDown() {
try {
countdownElapsed = 0l;
next_button.setEnabled(false);
displayCountDown();
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private Runnable mCountDownRunnable = new Runnable() {
#Override
public void run() {
countdownElapsed = countdownElapsed + COUNT_DOWN_TICKS;
if(countdownElapsed >= COUNT_DOWN_FINISH){
releaseCountDownHandler();
next_button.setEnabled(true);
}
else{
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
long secFull = countdownElapsed % 1000;
if(secFull == 0){
runOnUiThread(new Runnable() {
#Override
public void run() {
displayCountDown();
}
});
}
}
};
private void releaseCountDownHandler() {
try {
if(mCountDownRunnable != null) {
mCountDownHandler.removeCallbacks(mCountDownRunnable);
}
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private void displayCountDown(){
long t = (COUNT_DOWN_FINISH - countdownElapsed)/1000;
String myTime = String.valueOf(t);
timer.setText(myTime);
}
}
This function should do what you want, just call it into OnClickListener
public void countDown(Button yourBtn) {
new Thread() {
public void run() {
try {
int second = 10;
for (int i = second; i >= 1; i--) {
int finalI = i;
yourBtn.post(new Runnable() {
#Override
public void run() {
yourBtn.setText(String.valueOf(finalI))
}
});
Thread.sleep(1000); // Change text every 1s
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
This code is like my code above except this code introduces a "click counter". I have introduced a new class variable to keep track of how many times the button is clicked. I have also introduced a new constant called "NUMBER_OF_BUTTON_CLICKS" which servers as the upper limit of clicks.
The user can now click on the button (in this case) 5 times. On the fifth click the condition to trigger the startCountDown method is met and the button is disabled for 5 seconds.
public class MainActivity extends AppCompatActivity {
//Constant values
private static final String TAG = MainActivity.class.getSimpleName();
private static final int NUMBER_OF_BUTTON_CLICKS = 5;
private static final long COUNT_DOWN_TICKS = 100l;
private static final long COUNT_DOWN_FINISH = 5000l;
//class variables
private int howManyClicks = 0;
private long countdownElapsed = 0l;
private Handler mCountDownHandler = new Handler();
private Button next_button;
private TextView timer;
private TextView clicks;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// you must compensate for the actual layout for your activity
setContentView(R.layout.activity_main);
// you must compensate for the actual id of the TextView
timer = findViewById(R.id.tvTimer);
// Use this only if you want to display the number of clicks
// you might need to add this TextView if you want to display the number of clicks
clicks = findViewById(R.id.tvClicks);
// you must compensate for the actual id of the Button
next_button = findViewById(R.id.btnNext);
next_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
howManyClicks++;
if(howManyClicks >= NUMBER_OF_BUTTON_CLICKS){
startCountDown();
}
//Add this only if you want to see how many clicks were made
String myClicks = String.valueOf(howManyClicks);
clicks.setText(myClicks)
}
});
}
private void startCountDown() {
try {
countdownElapsed = 0l;
next_button.setEnabled(false);
displayCountDown();
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private Runnable mCountDownRunnable = new Runnable() {
#Override
public void run() {
countdownElapsed = countdownElapsed + COUNT_DOWN_TICKS;
if(countdownElapsed >= COUNT_DOWN_FINISH){
releaseCountDownHandler();
next_button.setEnabled(true);
// reset the clicks counter
howManyClicks = 0;
}
else{
mCountDownHandler.postDelayed(mCountDownRunnable, COUNT_DOWN_TICKS);
}
long secFull = countdownElapsed % 1000;
if(secFull == 0){
runOnUiThread(new Runnable() {
#Override
public void run() {
displayCountDown();
}
});
}
}
};
private void releaseCountDownHandler() {
try {
if(mCountDownRunnable != null) {
mCountDownHandler.removeCallbacks(mCountDownRunnable);
}
}
catch (Exception ex){
Log.e(TAG, ex.getMessage());
}
}
private void displayCountDown(){
long t = (COUNT_DOWN_FINISH - countdownElapsed)/1000;
String myTime = String.valueOf(t);
timer.setText(myTime);
//Add this only if you want to see how many clicks were made
String myClicks = String.valueOf(howManyClicks);
clicks.setText(myClicks)
}
}
I'm making a "Simon says" game as my final project for highschool, and it's mostly done but I have one problem.
Currently, I'm trying to make the buttons light when I press them.
However, they don't seem to light up and the sleep function doesn't really work.
They only change color when the function that displays the next sequence of colors lights up.
Here's the code:
package com.gabie212.simonsays;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.MediaPlayer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.ArrayList;
public class GameActivity extends AppCompatActivity implements View.OnClickListener {
private int i = 0, pNum = 0, pIndex = 0,score;
private Thread t = new Thread();
private Thread bt = new Thread();
private Button greenButton;
private Button redButton;
private Button blueButton;
private Button yellowButton;
private Button startButton;
private TextView Score;
private boolean startActivated = false;
private MediaPlayer greenBeep;
private MediaPlayer redBeep;
private MediaPlayer blueBeep;
private MediaPlayer yellowBeep;
private ArrayList<Integer> userColors = new ArrayList<Integer>();
private GameManger gm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
Score = (TextView) findViewById(R.id.ScoreNum);
greenButton = (Button) findViewById(R.id.btnGreen);
redButton = (Button) findViewById(R.id.btnRed);
blueButton = (Button) findViewById(R.id.btnBlue);
yellowButton = (Button) findViewById(R.id.btnYellow);
startButton = (Button) findViewById(R.id.btnStart);
greenButton.setOnClickListener(this);
redButton.setOnClickListener(this);
blueButton.setOnClickListener(this);
yellowButton.setOnClickListener(this);
startButton.setOnClickListener(this);
greenBeep = MediaPlayer.create(this, R.raw.greenbeep);
redBeep = MediaPlayer.create(this, R.raw.redbeep);
blueBeep = MediaPlayer.create(this, R.raw.bluebeep);
yellowBeep = MediaPlayer.create(this, R.raw.yellowbeep);
/*
SharedPreferences sp = getSharedPreferences("score", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.clear();
editor.apply();
*/
}
public void start() {
startActivated=true;
gm = new GameManger(this);
Score.setText("0");
lightUp(0);
}
public void beepStop(){
greenBeep.stop();
redBeep.stop();
blueBeep.stop();
yellowBeep.stop();
}
public void lightUp(final int i) {
android.os.Handler handler = new android.os.Handler();
if (i < gm.getRandomColors().size()) //light up code
{
switch (gm.getRandomColors().get(i)) {
case 1:
greenButton.setBackgroundResource(R.drawable.greenlightup);
greenBeep.start();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
greenButton.setBackgroundResource(R.drawable.green);
lightUp(i+1);
}
}, 500);
break;
case 2:
redButton.setBackgroundResource(R.drawable.redlightup);
redBeep.start();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
redButton.setBackgroundResource(R.drawable.red);
lightUp(i+1);
}
}, 500);
break;
case 3:
blueButton.setBackgroundResource(R.drawable.bluelightup);
blueBeep.start();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
blueButton.setBackgroundResource(R.drawable.blue);
lightUp(i+1);
}
}, 500);
break;
case 4:
yellowButton.setBackgroundResource(R.drawable.yellowlightup);
yellowBeep.start();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
yellowButton.setBackgroundResource(R.drawable.yellow);
lightUp(i+1);
}
}, 500);
break;
}
}
pIndex = 0;
}
#Override
public void onClick(View v) {
if (v.getId() == startButton.getId()) {
start();
} else {
if (startActivated) {
if (v.getId() == greenButton.getId()) {//here is the part where i try to make the buttons change colors
greenBeep.start();
greenButton.setBackgroundResource(R.drawable.greenlightup);
try {
t.sleep(1000);
// Do some stuff
} catch (Exception e) {
e.getLocalizedMessage();
}
greenButton.setBackgroundResource(R.drawable.green);
pNum = 1;
}
if (v.getId() == redButton.getId()) { //here is the part where i try to make the buttons change colors
redBeep.start();
redButton.setBackgroundResource(R.drawable.redlightup);
try {
t.sleep(1000);
// Do some stuff
} catch (Exception e) {
e.getLocalizedMessage();
}
redButton.setBackgroundResource(R.drawable.red);
pNum = 2;
}
if (v.getId() == blueButton.getId()) { //here is the part where i try to make the buttons change colors
blueBeep.start();
blueButton.setBackgroundResource(R.drawable.bluelightup);
try {
t.sleep(1000);
// Do some stuff
} catch (Exception e) {
e.getLocalizedMessage();
}
blueButton.setBackgroundResource(R.drawable.blue);
pNum = 3;
}
if (v.getId() == yellowButton.getId()) {//here is the part where i try to make the buttons change colors
yellowBeep.start();
yellowButton.setBackgroundResource(R.drawable.yellowlightup);
try {
t.sleep(1000);
// Do some stuff
} catch (Exception e) {
e.getLocalizedMessage();
}
yellowButton.setBackgroundResource(R.drawable.yellow);
pNum = 4;
}
if (!gm.check(pNum, pIndex)) {
beepStop();
SharedPreferences sp = getSharedPreferences("score", Context.MODE_PRIVATE);
Intent i = null;
score = gm.getRandomColors().size()-1;
if(score > sp.getInt("scoreP3",0)) {
i = new Intent(GameActivity.this, InsertScoreActivity.class);
i.putExtra("score", gm.getRandomColors().size() - 1);
startActivity(i);
}
else {
i = new Intent(GameActivity.this, GameOverActivity.class);
i.putExtra("score", gm.getRandomColors().size() - 1);
startActivity(i);
}
}
pIndex++;
if (pIndex == gm.getRandomColors().size()) {
Score.setText("" + gm.getRandomColors().size() + "");
gm.addColor();
try {
t.sleep(1000);
// Do some stuff
} catch (Exception e) {
e.getLocalizedMessage();
}
lightUp(0);//it either performs the color change here beofre the lightup function or it just sleeps and doesn't perform the color change at all
}
}
}
}
}
here's the game helper class:
package com.gabie212.simonsays;
import java.util.ArrayList;
import java.util.Random;
/**
* Created by Ronit on 21/02/2018.
*/
public class GameManger {
private GameActivity gActivity;
static Random rnd = new Random();
private ArrayList<Integer> randomColors;
public GameManger(GameActivity mA)
{
randomColors = new ArrayList<Integer>();
this.gActivity =mA;
randomColors.add(getColor());
}
public void addColor()
{
randomColors.add(getColor());
}
public int getColor()
{
return rnd.nextInt(4)+1;
}
public ArrayList<Integer> getRandomColors()
{
return randomColors;
}
public boolean check(int num, int index)
{
return(randomColors.get(index)==num);
}
}
enter code here
I have some problems.
The sleep doesn't perform, does it have something to do with the way I did it in the if statements? Sleep just doesn't happen in the code I have written.
Color change doesn't happen for some reason and I don't know why it doesn't, maybe it has something to do with the thread.sleep.
Color change happens later in the program than its supposed to. Again, I think it has something to do with the sleep but when I removed the sleep, the color change still happens later in the code.
I'm trying to setup ProgressDialog to show to the user the progress of an InputStream of bytes. I'm able to show this in the console of the Android Studio by way of this below :
Log.d(TAG, "Progress, transferred " + Integer.toString(100 * bytesTransferred/osSize) + "%");
However, I'm not sure how to attach the bytesTransferred/osSize correctly to a ProgressDialog, I can use a thread to time how long the progress bar will take to fill up the progressBar with the code below:
update = new ProgressDialog(this);
update.setTitle("Transferring update");
update.setMessage("Please wait updating...");
update.setCanceledOnTouchOutside(false);
update.setProgress(0);
final int totalProgressTime = 100;
final Thread t = new Thread() {
#Override
public void run() {
int jumpTime = 0;
while(jumpTime < totalProgressTime) {
try {
sleep(1800);
jumpTime += 1;
update.setProgress(jumpTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t.start();
update.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
update.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
update.show();
}
But would be much better to show to the user the actual transfer of the bytes. This below is what I have to work with:
final int osSize;
final InputStream inputStream;
osSize = inputStream();
public void onProgress(int bytesTransferred) {
Log.d(TAG, "Progress, transferred " + Integer.toString(100 * bytesTransferred/osSize) + "%");
}
Any help would be appreciated, thanks in advance.
Extend this:
#Override
public void run() {
int jumpTime = 0;
while(jumpTime < totalProgressTime) {
try {
sleep(1800);
jumpTime += 1;
update.setProgress(jumpTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
With this:
#Override
public void run() {
int jumpTime = 0;
while(jumpTime < totalProgressTime) {
try {
sleep(1800);
jumpTime += 1;
final int fJumpTime = jumpTime;
runOnUiThread(new Runnable() {
#Override
public void run() {
update.setProgress(fJumpTime);
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I have two threads.One is for incrementing the value.For each increment i neet to be notified the main thread.
Below is my main Thread which is a activity
public class MainActivity extends Activity {
private ProgressBar progressBar;
private int progressStatus = 1;
private TextView textView;
private Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = (ProgressBar) findViewById(R.id.progressBar1);
textView = (TextView) findViewById(R.id.textView1);
ProgressUpdate b = new ProgressUpdate();
b.start();
Log.e("SAMEERA", "Satrting ProgressUpdate");
synchronized (b) {
try {
Log.e("SAMEERA", "synchronized synchronized");
Log.e("SAMEERA", "progressStatus is "+b.total);
b.wait();
Log.e("SAMEERA", "progressStatus is "+b.total);
progressBar.setProgress(progressStatus);
textView.setText(progressStatus + "/" + progressBar.getMax());
} catch (InterruptedException e) {
}
System.out.println("Total is: " + b.total);
}
}
}
Below is my increment thread.
package com.example.zwtouch;
import android.util.Log;
public class ProgressUpdate extends Thread {
int total;
public void run() {
total=0;
synchronized (this) {
for (int i = 0; i < 100; i++) {
total += i;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.e("SAMEERA", "run run total is "+i);
notify();
}
}
}
}
I need to notified each time if total is increased.But its not happening.After the for loop is finished it calls the main thread..where is the error ?
Option 1
Use Handler
Populate ProgressUpdate with ProgressBar and Handler objects.
On each progress use the Handler to update the ProgressBar
like this:
public class ProgressUpdate extends Thread {
int total;
ProgressBar mProgressBar;
Handler mHandler;
public ProgressUpdate(Handler h, ProgressBar pb) {
mHandler = h;
mProgressBar = pb;
}
public void run() {
total=0;
for (int i = 0; i < 100; i++) {
// Update the progress bar via a Handler
mHandler.post(new Runnable() {
public void run() {
mProgressBar.setProgress(i);
}
});
}
}
}
setup like this
new ProgressUpdate(handler, progressBar).start();
Option 2 (recommended)
This is another approach, You could use AsyncTask to achieve this aim. The advantage of this way is that both onProgressUpdate and onPostExecute runs on UI-Thread.
Make this class internal of MainActivity
private class ProgressUpdate extends AsyncTask<Void, Integer, Integer> {
protected Integer doInBackground(Void... dummy) {
int total = 0;
for (int i = 0; i < 100; i++) {
total += i;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.e("SAMEERA", "run run total is "+i);
// Notify UI Thread
publishProgress(i);
}
return total;
}
protected void onProgressUpdate(Integer... i) {
// do something with 'i' on UI Thread
progressBar.setProgress(i);
}
protected void onPostExecute(Integer total) {
// do something with 'total' on UI Thread
// for instance
progressBar.setVisibility(View.GONE);
}
}
Setup ProgressUpdate on onCreate like this
#Override
protected void onCreate(Bundle savedInstanceState) {
// ...
new ProgressUpdate().execute();
// ...
}