package com.example.progressdialog;
import com.example.progressdialog.R;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.view.Menu;
import android.view.View;
public class MainActivity extends Activity {
private ProgressDialog progress;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progress = new ProgressDialog(this);
}
public void open(View view){
progress.setMessage("Start This Baby Up!");
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progress.setIndeterminate(false);
progress.show();
final int totalProgressTime = 100;
final Thread t = new Thread(){
#Override
public void run(){
int jumpTime = 0;
while(jumpTime < totalProgressTime){
try {
sleep(500);
jumpTime += 1;
progress.setProgress(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t.start();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
I cannot seem to get my progress bar to actually progress forward. It simply displays a static 0/100 bar. I am trying to get it to move forward in a smooth manner taking approximately 30-45 seconds to complete. Could someone tell me what I am doing wrong? I am very new to java! Thanks!
Citation:
progress.setProgress(0);
this should be
progress.setProgress(jumpTime);
I suppose?
Also I guess, this will lead to a problem. You cannot access UI-Components from background Threads. You need to use a Handler. See this Example.
Related
I have designed an app that displays text when tapped once and displays it differently on a Long Press and on a Double Tap. However, I observe that the methods are called once. That is once I either long press or tap once or double tap, the corresponding method is called and then on subsequent tapping or press does not do anything. What can be done to make the app work not just once?
package com.example.hello;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.view.Gravity;
import android.view.MenuItem;
import android.view.GestureDetector;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;
import android.view.ViewGroup.LayoutParams;
import android.view.View.OnTouchListener;
import android.view.View.OnLongClickListener;
import android.view.View.OnClickListener;
public class MainActivity extends ActionBarActivity implements OnTouchListener {
private TextView shownamecenter;
private TextView shownamecustom;
private RelativeLayout myimage;
int x, y;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
shownamecenter = (TextView)findViewById(R.id.shownamecenter);
shownamecustom = (TextView)findViewById(R.id.shownamecustom);
myimage = (RelativeLayout)findViewById(R.id.myimage);
shownamecenter.setText("");
shownamecustom.setText("");
myimage.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
showNameOnSingleTap();
return;
}
});;
myimage.setOnTouchListener(this); //{
myimage.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
showNameInCustomPosition(shownamecustom, x, y);// TODO Auto-generated method stub
return true;
}
});
return;
}
private void showNameOnSingleTap() {
Timer countdown = new Timer(false);
countdown.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
shownamecenter.setVisibility(View.INVISIBLE);
}
});
}
},3000);
shownamecustom.setText("");
shownamecenter.setText("My Text");
shownamecenter.setTextColor(0xff00ff00);
RelativeLayout.LayoutParams layoutparameters = (RelativeLayout.LayoutParams)shownamecenter.getLayoutParams();
layoutparameters.addRule(RelativeLayout.CENTER_IN_PARENT, -1);
shownamecenter.setLayoutParams(layoutparameters);
findViewById(R.id.myimage).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
shownamecenter.setText("");
return;
}
});
return;
}
private void showNameInCustomPosition(TextView customview, int x, int y) {
Timer countdown = new Timer(false);
countdown.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
shownamecustom.setVisibility(View.INVISIBLE);
}
});
}
},3000);
RelativeLayout.LayoutParams relout = (RelativeLayout.LayoutParams) customview.getLayoutParams();
relout.leftMargin = x-50;
relout.topMargin = y-50;
customview.setLayoutParams(relout);
shownamecenter.setText("");
shownamecustom.setText("My Text");
shownamecustom.setTextColor(0xff00ff00);
class GestureListener extends GestureDetector.SimpleOnGestureListener {
#Override
public boolean onDoubleTap(MotionEvent e) {
shownamecustom.setText("");
showNameOnSingleTap();
return true;
}
}
return;
}
//}
#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);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
x = (int)event.getRawX();
y = (int)event.getRawY();
return false;
}
}
The problem is because you are redefining what happens when you click on the image, which isn't terribly good practice because it makes it difficult to keep track of what should be going on. A View can only ever have one Listener of each type, so when you do
private void showNameOnSingleTap() {
//...
findViewById(R.id.myimage).setOnClickListener (new View.OnClickListener() {
#Override public void onClick(View v) {
shownamecenter.setText(""); return;
}
});
}
You are changing what happens every time that you click the image after that. Rather than calling your method showNameOnSingleTap() when it's clicked, it is only setting the text and not calling your method. Instead of reassigning the onClickListener, just keep a boolean variable to determine what you want to do.
boolean textIsVisible = false;
private void showNameOnSingleTap() {
if(textIsVisible) {
//hide text
textIsVisible = false;
shownamecenter.setText(View.INVISIBLE);
}
else {
Timer countdown = new Timer(false);
countdown.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
shownamecenter.setVisibility(View.INVISIBLE);
textIsVisible = false;
}
});
}
},3000);
//show text
textIsVisible = true;
}
}
I am making a simple Android app just to become familiar with the concept. I have an app with two activities, the first should just be a splash screen that displays for one second, the second is a canvas w/ a black square that turns cyan when you click it. When I run it, it stops with an error in the log saying "performing stop of activity that is not resumed".
Main Activity:
package com.example.test;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try{
Thread.sleep(1000);
}catch(Exception e){}
Intent in = new Intent(this, Afspl.class);
startActivity(in);
}
#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);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Next Activity:
package com.example.test;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
public class Afspl extends Activity {
public DrawView vi;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
vi = new DrawView(this);
}
class DrawView extends View{
Paint paint = new Paint();
public DrawView(Context context){
super(context);
}
public void onDraw(Canvas c){
paint.setColor(col);
c.drawRect(40, 40, 200, 200, paint);
}
private int col = Color.BLACK;
public void setToColor(int c){
col=c;
}
}
public boolean onTouchEvent(MotionEvent me){
if(me.getX()>=30 && me.getX() <= 320 && me.getY() >=30 && me.getY() <= 320)vi.setToColor(Color.CYAN);
return super.onTouchEvent(me);
}
}
Do you have any idea why I'm getting this error or what it means or how I can fix this? All help is appreciated.
Insted of using:
try{
Thread.sleep(1000);
}catch(Exception e){}
Intent in = new Intent(this, Afspl.class);
startActivity(in);
You could try using new
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent in = new Intent(getApplicationContext(), Afspl.class);
startActivity(in);
}
}, 1000);
You should never put to sleep the main thread. If you want to do something in the future use a Handler and a Runnable.
Also, you should declare a View on both Activities, not just the first one. Create a View and set it with "setContentView()" on your second activity.
I am using the following code with IOIO to act as a motion detector, the problem is the IOIO is disconnected whenever my phone screen goes off! I do not want the screen to stay on all the time to keep the IOIO connected!
any solution please?
package com.LookHin.ioio_pir_motion_sensor;
import ioio.lib.api.AnalogInput;
import ioio.lib.api.DigitalOutput;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import ioio.lib.util.android.IOIOActivity;
import android.content.Intent;
import android.graphics.Color;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
public class MainActivity extends IOIOActivity {
private ToggleButton toggleButton1;
private TextView textView1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView1 = (TextView) findViewById(R.id.textView1);
toggleButton1 = (ToggleButton) findViewById(R.id.toggleButton1);
}
#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);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.action_about:
//Toast.makeText(getApplicationContext(), "Show About", Toast.LENGTH_SHORT).show();
Intent about = new Intent(this, AboutActivity.class);
startActivity(about);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
class Looper extends BaseIOIOLooper {
private DigitalOutput digital_led0;
private AnalogInput deigital_input;
int i = 0;
private float InputStatus;
#Override
protected void setup() throws ConnectionLostException {
digital_led0 = ioio_.openDigitalOutput(0,true);
deigital_input = ioio_.openAnalogInput(45);
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "IOIO Connect", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void loop() throws ConnectionLostException {
try{
digital_led0.write(!toggleButton1.isChecked());
InputStatus = deigital_input.getVoltage();
runOnUiThread(new Runnable() {
#Override
public void run() {
textView1.setText(String.format("%.02f",InputStatus)+" v.");
if(InputStatus >= 3.0){
textView1.setBackgroundColor(Color.RED);
if (i == 0){
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
r.play();
i = 1;
};
}else{
textView1.setBackgroundColor(Color.TRANSPARENT);
i = 0;
}
}
});
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
#Override
protected IOIOLooper createIOIOLooper() {
return new Looper();
}
}
Option 1) Lock the screen so it always stays awake
public void onCreate(Bundle savedInstanceState) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
Option 2) Fix your response to onPause().
When the screen goes off the onPause() method is called and you should handle it as otherwise your activity will be closed.
#Override
protected void onPause() {
// Your code
super.onPause();
}
The onPause() normally calls the ioio.disconnect() so this should be overrode.
IOIOService let´s you run your code on the background even if application goes to the background.
Good afternoon,
I am looking to assign a generic variable that can be changed throughout the app and passed into CountDownTimer as my long
package com.rcd.learningactivities;
import java.text.DecimalFormat;
import java.util.concurrent.TimeUnit;
import android.app.Activity;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
protected CountDownTimer cd;
private long countTime = 0; // Variable for CountDownTimer
private Button lastPressedButton;
private Button red;
private Button blue;
private TextView blueTimer;
private TextView redTimer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
blueTimer = (TextView) findViewById(R.id.blueTimer);
blue = (Button) findViewById(R.id.button1);
redTimer = (TextView) findViewById(R.id.redTimer);
red = (Button) findViewById(R.id.button2);
cd = new CountDownTimer(countTime, 1000) { //<--- trying to use countTime here
public void onTick(long millisUntilFinished) {
DecimalFormat dfmin = new DecimalFormat("0");
DecimalFormat dfsec = new DecimalFormat("00");
double seconds = TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished)%60;
double min = TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished);
if (lastPressedButton == blue){
blueTimer.setText(String.valueOf(dfmin.format(min)) + ":" + String.valueOf(dfsec.format(seconds)));
}
else if (lastPressedButton == red) {
redTimer.setText(String.valueOf(dfmin.format(min)) + ":" + String.valueOf(dfsec.format(seconds)));
}
}
public void onFinish() {
if (lastPressedButton == blue){
blueTimer.setText("5:00");
}
else if (lastPressedButton == red){
redTimer.setText("5:00");
}
}
};
blue.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
lastPressedButton = blue;
countTime = 300000; // <-- setting countTime here
if (blueTimer.getText().toString().contains("5:00")){
cd.start();
} else {
cd.cancel();
cd.onFinish();
}
}
});
red.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
lastPressedButton = red;
countTime = 250000;
if (redTimer.getText().toString().contains("5:00")){
cd.start();
} else {
cd.cancel();
cd.onFinish();
}
}
});
}
#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);
return true;
}
}
For whatever reason, it stays with the initially declared number 0 (or if i change it to say 300000 then its always 300000) and its not changing the countTime below in my onClick.
Any help is greatly appreciated. If it can be accompanied by an explanation, that would be great!
Thanks everyone in advance!
EDIT: Im guessing its a scope issue that im overlooking??
EDIT2: If it is a scope issue, im a little confused as to how im able to reset the "lastPressedButton" variable set just about it, but not the countTime.
Java has pass by value semantics, not pass by reference, the value of countTime at construction is passed to CountDownTimer, CDT does not see any updates to countTime after it has been instantiated.
I am trying to create a simple Android stopwatch application. I was having trouble with the application freezing every time I would hit the start button. I learned from reading various things online that the reason it hangs is that I ran a while loop in the UI thread and in order for the application not to crash, that while loop had to be somewhere different. A post on the XDA forums suggested that someone encountering this problem should use an AsyncTask to accomplish this. I am having trouble understanding exactly how to use AsyncTask to do this.
TL;DR: I am trying to count time and then have it update a textview with the corresponding time
Original code with while loop in UI thread
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity
{
Button start, stop, reset;
TextView time;
boolean timeStopped = false;
long timeInNanoSeconds, startTimeInNanoSeconds;
double timer;
public double getTimeInSeconds()
{
timeInNanoSeconds = System.nanoTime() - startTimeInNanoSeconds;
double timeSeconds = (double) timeInNanoSeconds / 1000000000.0;
double roundOff = Math.round(timeSeconds * 100.0) / 100.0;
return roundOff;
}
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start = (Button) findViewById(R.id.startButton);
stop = (Button) findViewById(R.id.stopButton);
reset = (Button) findViewById(R.id.resetButton);
time = (TextView) findViewById(R.id.timeField);
start.setOnClickListener(new View.OnClickListener()
{
public void onClick(View arg0)
{
startTimeInNanoSeconds = System.nanoTime();
while(timeStopped == false)
{
double timer = getTimeInSeconds();
String stringTimer = Double.toString(timer);
CharSequence sequenceTimer = stringTimer;
time.setText(sequenceTimer);
}
}
});
stop.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
}
});
reset.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
time.setText("");
}
});
}
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);
return true;
}
}
EDIT: Working version using Handler
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
Button start, stop, reset;
TextView time;
Handler m_handler;
Runnable m_handlerTask;
int timeleft = 0;
boolean timeStopped;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start = (Button) findViewById(R.id.buttonStart);
stop = (Button) findViewById(R.id.buttonStop);
reset = (Button) findViewById(R.id.buttonReset);
time = (TextView) findViewById(R.id.textTime);
start.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
timeStopped = false;
m_handler = new Handler();
m_handlerTask = new Runnable()
{
public void run() {
if(timeStopped == false){
if(timeleft > -1) {
Log.i("timeleft","" + timeleft);
time.setText(String.valueOf(timeleft));
timeleft++;
}
else{
m_handler.removeCallbacks(m_handlerTask);
}
}
m_handler.postDelayed(m_handlerTask, 1000);
}
};
m_handlerTask.run();
}
});
stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
timeStopped = true;
m_handler.removeCallbacks(m_handlerTask);
}
});
reset.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
timeStopped = true;
m_handler.removeCallbacks(m_handlerTask);
timeleft = 0;
time.setText(String.valueOf(timeleft));
}
});
}
#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);
return true;
}
}
doInbackground is invoked on the background thread. you cannot update ui from a background
time.setText(sequenceTimer);
// should be in a ui thread.
Use runOnUithread or setText in onPostExecute.
You can use a Handler , a timer task or a CountDowntimer depending on your requirement.
Android Thread for a timer
Edit:
Using Handler
public class MainActivity extends Activity
{
Button start;
TextView time;
Handler m_handler;
Runnable m_handlerTask ;
int timeleft=100;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start = (Button) findViewById(R.id.button1);
time = (TextView)findViewById(R.id.textView1);
start.setOnClickListener(new View.OnClickListener()
{
public void onClick(View arg0)
{
m_handler = new Handler();
m_handlerTask = new Runnable()
{
#Override
public void run() {
if(timeleft>=0)
{
// do stuff
Log.i("timeleft",""+timeleft);
time.setText(String.valueOf(timeleft));
timeleft--;
}
else
{
m_handler.removeCallbacks(m_handlerTask); // cancel run
}
m_handler.postDelayed(m_handlerTask, 1000);
}
};
m_handlerTask.run();
}
});
}
}
In my opinion AsyncTask is not fit for you, as this in my mind is a single shot action.
I would suggest something like this:
private ScheduledExecutorService exec;
private void startExec() {
shutDownExec();
exec = Executors.newSingleThreadScheduledExecutor();
exec.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
// this starts immediately and is run once every minute
double timer = getTimeInSeconds();
String stringTimer = Double.toString(timer);
CharSequence sequenceTimer = stringTimer;
runOnUiThread(new UpdateUI(R.id.yourtime_textview, sequenceTimer));
}
}, 0, 1, TimeUnit.MINUTES); // adjust how often run() is executed here
}
private void shutDownExec() {
if (exec != null && !exec.isTerminated()) {
exec.shutdown();
}
}
private class UpdateUI implements Runnable {
private String mText;
private TextView mTv;
public UpdateUI(int textviewid, String text) {
this.mTv = (TextView) findViewById(textviewid);
this.mText = text;
}
#Override
public void run() {
mTv.setText(mText);
}
}
I had to do a similar task lately I used created a separate thread with the following code. It lets you update at set time intervals which I think would be suited to your task.
Hope it helps.
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
public class AutomationTreadClass {
Activity refToUIActivity;
//Declare the timer
Timer t = new Timer();
//pass UI activity so you can call update on it
AutomationTreadClass( Activity callingActivity ){
refToUIActivity = callingActivity;
startTimerTread();
}
private void startTimerTread(){
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
//do any updates to the time you need to do here
updateLevelMeter();
}
},
//Start Time of thread
0,
//interval of updates
30);
}
private void updateLevelMeter() {
refToUIActivity.runOnUiThread(new Runnable() {
public void run() {
//access what ever UI comment you need to here. like giving you textview a value.
}
});
}
}