I defined a splashscreen the following way:
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ExceptionHandler.register(this);
setFullscreen();
splashScreen();
}
private void splashScreen() {
runOnUiThread(new Runnable() {
#Override
public void run() {
setContentView(R.layout.splashscreen);
splash = (ImageView) findViewById(R.id.splashscreenLayer);
startSplashTime = new Date();
}
});
new LoadingThread().start();
}
private class LoadingThread extends Thread {
#Override
public void run() {
checkNetwork();
}
}
Somewhere at specific conditions in the checkNetwork() method, the stopSplash method is called:
public void stopSplash() {
Message msg = new Message();
msg.what = STOPSPLASH;
Date endSplashTime = new Date();
long time = endSplashTime.getTime() - startSplashTime.getTime();
System.out.println("Time Splashscreen was displayed: " + time);
if (time < SPLASH_MIN_TIME) {
long delay = SPLASH_MIN_TIME - time;
System.out.println("Delay Splashscreen for: " + delay);
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
splashHandler.sendMessage(msg);
} else {
System.out.print("Show Splashscreen now");
splashHandler.sendMessage(msg);
}
}
private Handler splashHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case STOPSPLASH:
splash.setVisibility(View.GONE);
break;
}
super.handleMessage(msg);
}
};
The problem is, sometimes (maybe 1 of 10) if I started the app directly from Eclipse, the Splashscreen isn't showed, but instead just a black screen.
Other problem: if i restart the app, e.g. after onDestroy() was called after clicking the back button on the device, the Splashscreen is almost never shown.
Any hints why?
My assumption: could it be, that the LoadingThread starts "faster" than the Runnable, and so the network staff is done before the Splashscreen is set?
You might try using a CountdownTimer in your implementation. On your first activity, start a CountdownTimer that checks in onTick() every so often for a synchronized boolean finishedLoading with some kind of timeout in onFinish() (15 seconds or something), while your loading is done in another thread that sets finishedLoading to true when it is finished.
Maybe the splash screen isnt being terminated before the v=next activity starts.. just a thought..
Related
I need that a button can run automatically every 1-2 seconds, and, when the if condition (that i have in the method which is used by the button) is fulfilled, this function must be stopped.
I've tried this but it wasn't what i wanted because with this code the button only runs one time:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Consulta.performClick();
}
}, 1000);
onClick of my button:
public void consultaBD(View view)
{
DB db = new DB(getApplicationContext(),null,null,1);
String buscar = text_view.getText().toString();
String[] datos;
datos=db.buscar_reg(buscar.trim());
db.infraccion(buscar.trim());
if(datos[2] =="Encontrado")
{
App.matricula=buscar;
startActivity(new Intent(getApplicationContext(), MatriculasActivity.class));
Toast.makeText(getApplicationContext(),datos[2],Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(getApplicationContext(),datos[2],Toast.LENGTH_SHORT).show();
}
}
Another method would be to use Timers to initiate the button click every x seconds. However, in this answer I'll stick with the method you're using. Your handler appears to be incorrect, try something like this instead:
Replace your handler with:
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
#Override
public void run() {
Consulta.performClick();
handler.postDelayed(this, 1000);
}
};
And initiate it with: (where 1000 is the time (in milliseconds) between each execution)
handler.postDelayed(runnable, 1000);
UPDATE:
You have also requested that the event is fired when the text inside of a textbox is changed. To do this, you need to create a new event listener (make sure you replace field1 with the actual reference to your textbox):
field1.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
/* Add the Handler Call here */
handler.postDelayed(runnable, 1000);
}
});
whatever context I understood, here is the raw code which may help you.
Handler handler = new Handler();
//initialize this method once by either clicking on button or as the activity starts
void checkAndPerformClick(boolean conditionFulfilled) {
if (conditionFulfilled) {
handler.removeCallbacksAndMessages(null);
return;
}
handler.postDelayed(new Runnable() {
#Override
public void run() {
Consulta.performClick();
checkAndPerformClick(datosEqualsEncontrado());
}
}, 1000);
}
boolean datosEqualsEncontrado() {
// apply your logic here as the name suggests
return false;
}
Is there any option to put a delay to make a call in Android?
Once the user clicks the call button below method is called.
public class DialBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.v("DileBroadCastReceiver","In onReceive()");
if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Log.v("DialBroadcast Receiver","Number is: "+number);
}
}
}
Then opponent user receiving call.
What I need is when user clicks the call button I should put delay for a second or two second, Is there any option to do like that.
I am a new developer. Can you please help me?
try {
//set time in mili
Thread.sleep(3000);
}catch (Exception e){
e.printStackTrace();
}
or
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//do something
}
}, 3000//time in milisecond
);
Inside your onReceive function
Handler mHandler = new Handler();
mHandler.postDelayed(new Runnable(){
#Override
public void run() {
if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Log.v("DialBroadcast Receiver","Number is: "+number);
}
}
}, 2000); // 2000 for two seconds in milis
I have a Button in my Activity which, if not clicked within 5 seconds from creating the Activity, I want to crash the App. I tried the following but found out from logging that the OnClickListener code is executed after all other code in onCreate(Bundle) is run. So the boolean is always false when it is checked. How can I fix this?
private Boolean isClicked = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e("0-isClicked", String.valueOf(isClicked));
setContentView(R.layout.activity_main_map);
ImageView iv = (ImageView) findViewById(R.id.myBTN);
iv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(getApplicationContext(), MainActivity.class);
isClicked = true;
Log.e("1-isClicked", String.valueOf(isClicked));
startActivity(i);
}
});
Log.e("2-isClicked", String.valueOf(isClicked));
//let app crashes after 5 seconds (5000 milliseconds) if user didn't take action
if (!isClicked) {
Log.e("3-isClicked", String.valueOf(isClicked));
Thread timer = new Thread() {
public void run() {
try {
sleep(5000);
} catch (Exception e) {
e.printStackTrace();
} finally {
throw null;
}
}
};
timer.start();
}
}
And this is what LogCat gives:
E/0-isClicked﹕ false
E/2-isClicked﹕ false
E/3-isClicked﹕ false
E/1-isClicked﹕ true
I would do it the other way around: you crash your app anyway if in the 5 seconds, the user didn't click.
To ease the pain you can use CountdownTimer and do something those lines:
public void onCreate(){
new CountDownTimer(5000, 1000) {
public void onTick(long millisUntilFinished) {
Log.e("isClicked", String.valueOf(isClicked));
}
public void onFinish() {
if(!isClicked) throw null;
}
}.start();
}
You can use a Timer for setting a task to be executed 5 seconds later and in that task you can finish the activity. Create the timer on onCreate()
timer = new Timer(); // Keep the timer (of type Timer) as a member of the activity class so you can access it later
timer.scheduleTask(timerTaskInstance, 5000); // timerTaskInstance is an instance of TimerTask for which you should override the run() method
Now if the button is clicked before the timer times out just cancel the timer on the button's listener method:
timer.cancel();
More info about TimerTask
I think you have to understand when oncreate is runned. Your three first log statments is from onCreate and should be:
E/0-onCreate﹕ false
E/2-onCreate﹕ false
E/3-onCreate﹕ false
See http://www.codelearn.org/android-tutorial/android-activity
I'm trying to make a simple little program that will increment a number once a second. In this case, I'm implementing a thread that should loop once per second and add 1 to "potato" each time it loops. This works fine until it gets back to the display method potatoDisp(). For some reason this causes my app to crash. Removing potatoDisp() from run() fixes the problem, but the display is not updated as "potato" increases.
public int potato = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
potatoDisp();
start();
}
public void potatoDisp() {
TextView text = (TextView) findViewById(R.id.textView1);
text.setText("You currently have " + potato + " potatoes");
}
public void start() {
Thread thread = new Thread(this);
thread.start();
}
#Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
return;
}
potato++;
potatoDisp();
}
}
I'm doing this for an Android app, if that helps. I've tried searching for an answer but I'm pretty lost when it comes to the proper way to work threads.
You need a runnable / handler like this:
private Runnable potatoRun = new Runnable() {
#Override
public void run () {
potatoDisp();
}
};
then change
potatoDisp();
to:
runOnUiThread(potatoRun);
You can't update the views when you're not on the UI thread.
You are probably getting an exception for updating the UI in the background. Since, potatoDisp(); is called from a background Thread but that function updates the UI it will give you problems. You need to call it with runOnUiThread().
#Override
public void run() {
while (true) {
try
{
Thread.sleep(1000);
} catch (InterruptedException e) {
return;
}
potato++;
runOnUiThread(new Runnable()
{
#Override
public void run()
{
potatoDisp();
}
});
}
}
Something like this should work.
The issue is that you are trying to update the UI (calling text.setText(...)) on a thread other than the main UI thread.
While I would suggest using a TimerTask instead of calling Thread.sleep(...), there are two main ways to edit your current code to work as expected.
-- Use a Handler
Define a Handler class that will accept messages and update your UI as needed. For example:
private final String POTATO_COUNT = "num_potatoes";
Handler handler = new Handler() {
public void handleMessage(Message msg) {
int numPotatoes = msg.getData.getInt(POTATO_COUNT);
mText.setText("You currently have " + numPotatoes + " potatoes");
}
}
Then in your code where you want to call your handler to update your text view, whether or not you are on the main UI thread, do the following:
Bundle bundle = new Bundle();
bundle.putInt(POTATO_COUNT, potato);
Message msg = new Message();
msg.setData(bundle);
handler.sendMessage(msg);
-- Call runOnUiThread(...)
#Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
return;
}
potato++;
runOnUiThread(new Runnable()
{
public void run()
{
potatoDisp();
}
}
}
}
I think you should be using Async Task to update the UI from a thread: http://developer.android.com/reference/android/os/AsyncTask.html
Halo, the first i want to know the idle time at my android application. after that, i will do something if it is a idle time mode.
I follow this link.
Application idle time
my program work properly, but suddenly the problem show up. I can't move to the other page (for example to the login page) or pop up a message using alertdialog because its in a thread. Do you have any solutions?
public class ControlActivity extends Activity {
private static final String TAG=ControlActivity.class.getName();
/**
* Gets reference to global Application
* #return must always be type of ControlApplication! See AndroidManifest.xml
*/
public ControlApplication getApp()
{
return (ControlApplication )this.getApplication();
}
#Override
public void onUserInteraction()
{
super.onUserInteraction();
getApp().touch();
Log.d(TAG, "User interaction to "+this.toString());
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}}
here is my ControlApplication.java
public class ControlApplication extends Application {
private static final String TAG=ControlApplication.class.getName();
private Waiter waiter;
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "Starting application"+this.toString());
//setContentView(R.layout.activity_main);
waiter=new Waiter(5*60*1000); //5 mins
waiter.start();
Toast.makeText(ControlApplication.this, "start", Toast.LENGTH_LONG).show();
}
public void touch()
{
waiter.touch();
Toast.makeText(ControlApplication.this, "touch", Toast.LENGTH_LONG).show();
} }
here is the Waiter.java
public class Waiter extends Thread implements Runnable{
private static final String TAG=Waiter.class.getName();
private long lastUsed;
private long period;
private boolean stop;
Context activity;
public Waiter(long period)
{
this.period=period;
stop=false;
}
#SuppressLint("ParserError")
public void run()
{
long idle=0;
this.touch();
do
{
idle=System.currentTimeMillis()-lastUsed;
Log.d(TAG, "Application is idle for "+idle +" ms");
try
{
Thread.sleep(5000); //check every 5 seconds
}
catch (InterruptedException e)
{
Log.d(TAG, "Waiter interrupted!");
}
if(idle > period)
{
idle=0;
//do something here - e.g. call popup or so
//Toast.makeText(activity, "Hello", Toast.LENGTH_LONG).show();
stopCounter();
}
}
while(!stop);
Log.d(TAG, "Finishing Waiter thread");
}
public synchronized void touch()
{
lastUsed=System.currentTimeMillis();
}
public synchronized void forceInterrupt()
{
this.interrupt();
}
//soft stopping of thread
public synchronized void stopCounter()
{
stop=true;
}
public synchronized void setPeriod(long period)
{
this.period=period;
}}
I tried to create a new class and call a method to intent. Its also fail. tried to pop up a message from that method its also fail.
do you guys have any other solutions for idle time? thanks.
Regards,
Alfred Angkasa
In you active activity, instead of this thread, do:
public class Graph extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
while(idle = 0) {
idle = System.currentTimeMillis()-lastUsed;
if(idle != period) {
Intent goNextActivity = new Intent(com.package.theactivity);
else {
idle == 0;
}
}
}
}
I just found by myself the answer by search on google and try for 5 hours.. :D
I hope my answer will help you too.
First, I mix the ControlApplication and Waiter with ControlActivity. Thats mean I don't need both files. My ControlActivity will extends the activity (its use for me to intent to the other page if in idle mode), and i will implements runnable(its use for me to run the thread).
after that i have a method called onUserInteraction(), this method help me to get the user interaction, whenever the user touch or click something.
in the onCreate, i initiate all the variable including lastUsed, period, and stop.
why should I initiate that? because you need to know how many seconds to know that your apps is on idle mode or not. that was period use. Stop variable is use for me to iterate and searching every 5 seconds(you can also make it every second to check idle or not) my apps is idle or not. I initiate lastUsed by calling method touch. I copied touch method from ControlApplication into my ControlActivity. By calling touch method, I can know when is my lastused. After that I start my thread.
in my run method, i set idle = 0. and do some looping to check. i check every 5 seconds to know my apps is on idle mode or not.
idle = System.System.currentTimeMillis()-lastUsed -> i used this to know if the idle is already suite with the period or not using if method.
if the idle is greater than period, my apps must be in idle mode. after that i stop the iteration and using handler to manage it.
i set handler.sendEmptyMessage(0), and create Handler. At handler i move to the other page.
this is my full code.
public class MainActivity extends Activity implements Runnable {
private static final String TAG= MainActivity.class.getName();
private long lastUsed;
private int period;
private boolean stop;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
period = 10000;
stop=false;
touch();
Thread currentThread = new Thread(this);
currentThread.start();
Toast.makeText(getApplicationContext(), "Start", Toast.LENGTH_SHORT).show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
#Override
public void onUserInteraction()
{
super.onUserInteraction();
touch();
Log.d(TAG, "User interaction to "+this.toString());
}
public synchronized void touch()
{
lastUsed=System.currentTimeMillis();
Toast.makeText(getApplicationContext(), "touch", Toast.LENGTH_SHORT).show();
}
public void moveIntent() {
Intent intent = new Intent(this, AfterIdle.class);
startActivity(intent);
}
public void validate(View view) {
switch (view.getId()) {
case R.id.button1 :
Intent intent = new Intent(this, AfterIdle.class);
startActivity(intent);
break;
}
}
#Override
public void run() {
// TODO Auto-generated method stub
long idle;
while (!stop) {
idle=System.currentTimeMillis()-lastUsed;
try
{
Thread.sleep(5000); //check every 5 seconds
}
catch (InterruptedException e)
{
Log.d(TAG, "Waiter interrupted!");
}
if (idle > period) {
idle = 0;
stop = true;
}
}
handler.sendEmptyMessage(0);
}
public Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
moveIntent();
}
};}
I hope this code will help another people if they have the same problem that i faced last time. I wish someone would correct the answer for me if my answer is wrong.
thanks.
Regards,
Alfred Angkasa