I'm trying to show an alert dialog with my application from a non-activity.
So the hard thing here is that I want to do it not in an activity but in my general application class.
public class AppName extends com.github.droidfu.DroidFuApplication {
public static long TIME_CONTENT_UPDATE = 60; //half hour
Handler mHandler = new Handler();
#Override
public void onCreate() {
super.onCreate();
intent = new Intent(this, VSSyncController.class);
setupTimer();
}
private void setupCatalogTimer() {
final Context con = this;
//A handler runs on a separate thread
mHandler = new Handler(new Handler.Callback() {
public boolean handleMessage(Message msg) {
showMyAlertDialog(con)
mHandler.sendEmptyMessageDelayed(0, TIME_CONTENT_UPDATE);
return true;
}
});
}
}
Basically I want to show an alert dialog from there, but I need to have a way to figure out which and IF there is any activity in the foreground, so I can call it from there.
How can I possible do it?
Thanks!
Keep track of this yourself via onPause() and onResume() in each of your activities. There is nothing built in that provides this data to you.
Thinking out of the box what I did was send a notification (when the dialog was suppose to pop) that takes the user back to the activity and there it shows the dialog!
This way we don't deal with the problem to check which activity is not in front.
Related
I have a background thread that is started from a Timer. The thread runs every 60 seconds and may detect a fatal problem that requires the app to exit immediately. Before exiting I want to show an alert dialog. Because the thread runs every 60 seconds I have no way of knowing which activity is currently running. Without an activity I can't call runOnUiThread to show the alert dialog. Below is some code that should illustrate what I'm trying to do. Without knowing the current activity how do I get an AlertDialog to show on the UI thread?
public class Foo {
private Timer mTimer;
public void startRefresh() {
if (mTimer == null) {
mTimer = new Timer(true);
mTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
boolean succeeded = true;
// Do something that fails
succeeded = false;
if (!succeeded) {
// Display alert dialog on UI thread before exiting application
}
}
}, 60000, 60000);
}
}
}
Pass the activity context to the Foo constructor
public class Foo {
Context mContext;
// constructor
public Foo(Context context){
this.mContext = context;
}
...
if (!succeeded) {
// Display alert dialog on UI thread before exiting application
}
}
public void displayAlert(Context context){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
alertDialog.setTitle("Display alert");
alertDialog.setMessage("My Alerts");
// Showing Alert Message
alertDialog.show();
}
EDIT
Which activity? The whole problem is that the Activity that started
the timer may not be the current activity when the error is detected.
Then don't use the constructor just use getApplicationContext() instead:
public abstract Context getApplicationContext ()
Added in API level 1 Return the context of the single, global
Application object of the current process. This generally should only
be used if you need a Context whose lifecycle is separate from the
current context, that is tied to the lifetime of the process rather
than the current component.
runOnUiThread(new Runnable() {
#Override
public void run() {
// Your dialog code.
}
});
My app is loading the start page in 10 seconds. In that time of 10 sec android screen is blank.
In that time I want to add the loading screen. How to add it?
And tell me in app how to know the starting page is loading? And tell me how to do in my app?
use ProgressDialog.
ProgressDialog dialog=new ProgressDialog(context);
dialog.setMessage("message");
dialog.setCancelable(false);
dialog.setInverseBackgroundForced(false);
dialog.show();
hide it whenever your UI is ready with data. call :
dialog.hide();
You can use splash screen in your first loading Activity like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Thread welcomeThread = new Thread() {
#Override
public void run() {
try {
super.run();
sleep(10000); //Delay of 10 seconds
} catch (Exception e) {
} finally {
Intent i = new Intent(SplashActivity.this,
MainActivity.class);
startActivity(i);
finish();
}
}
};
welcomeThread.start();
}
Hope this code helps you.
Please read this article
Chris Stewart wrote there:
Splash screens just waste your time, right? As an Android developer,
when I see a splash screen, I know that some poor dev had to add a
three-second delay to the code.
Then, I have to stare at some picture for three seconds until I can
use the app. And I have to do this every time it’s launched. I know
which app I opened. I know what it does. Just let me use it!
Splash Screens the Right Way
I believe that Google isn’t contradicting itself; the old advice and
the new stand together. (That said, it’s still not a good idea to use
a splash screen that wastes a user’s time. Please don’t do that.)
However, Android apps do take some amount of time to start up,
especially on a cold start. There is a delay there that you may not be
able to avoid. Instead of leaving a blank screen during this time, why
not show the user something nice? This is the approach Google is
advocating. Don’t waste the user’s time, but don’t show them a blank,
unconfigured section of the app the first time they launch it, either.
If you look at recent updates to Google apps, you’ll see appropriate
uses of the splash screen. Take a look at the YouTube app, for
example.
You can create a custom loading screen instead of splash screen. if you show a splash screen for 10 sec, it's not a good idea for user experience. So it's better to add a custom loading screen. For a custom loading screen you may need some different images to make that feel like a gif. after that add the images in the res folder and make a class like this :-
public class LoadingScreen {private ImageView loading;
LoadingScreen(ImageView loading) {
this.loading = loading;
}
public void setLoadScreen(){
final Integer[] loadingImages = {R.mipmap.loading_1, R.mipmap.loading_2, R.mipmap.loading_3, R.mipmap.loading_4};
final Handler loadingHandler = new Handler();
Runnable runnable = new Runnable() {
int loadingImgIndex = 0;
public void run() {
loading.setImageResource(loadingImages[loadingImgIndex]);
loadingImgIndex++;
if (loadingImgIndex >= loadingImages.length)
loadingImgIndex = 0;
loadingHandler.postDelayed(this, 500);
}
};
loadingHandler.postDelayed(runnable, 500);
}}
In your MainActivity, you can pass a to the LoadingScreen class like this :-
private ImageView loadingImage;
Don't forget to add an ImageView in activity_main.
After that call the LoadingScreen class like this;
LoadingScreen loadingscreen = new LoadingScreen(loadingImage);
loadingscreen.setLoadScreen();
I hope this will help you
public class Splash extends Activity {
private final int SPLASH_DISPLAY_LENGHT = 3000; //set your time here......
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
new Handler().postDelayed(new Runnable(){
#Override
public void run() {
/* Create an Intent that will start the Menu-Activity. */
Intent mainIntent = new Intent(Splash.this,MainActivity.class);
Splash.this.startActivity(mainIntent);
Splash.this.finish();
}
}, SPLASH_DISPLAY_LENGHT);
}
}
If the application is not doing anything in that 10 seconds, this will form a bad design only to make the user wait for 10 seconds doing nothing.
If there is something going on in that, or if you wish to implement 10 seconds delay splash screen,Here is the Code :
ProgressDialog pd;
pd = ProgressDialog.show(this,"Please Wait...", "Loading Application..", false, true);
pd.setCanceledOnTouchOutside(false);
Thread t = new Thread()
{
#Override
public void run()
{
try
{
sleep(10000) //Delay of 10 seconds
}
catch (Exception e) {}
handler.sendEmptyMessage(0);
}
} ;
t.start();
//Handles the thread result of the Backup being executed.
private Handler handler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
pd.dismiss();
//Start the Next Activity here...
}
};
Write the code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Thread welcomeThread = new Thread() {
#Override
public void run() {
try {
super.run();
sleep(10000) //Delay of 10 seconds
} catch (Exception e) {
} finally {
Intent i = new Intent(SplashActivity.this,
MainActivity.class);
startActivity(i);
finish();
}
}
};
welcomeThread.start();
}
I'm not sure if this is the correct way to go about but I will try and explain what I want to do.
I have an Activity which creates a fragment called TemporaryFragment with a label. What I want to do is create and start a service with a Timer in it and that Timer then updates the time in that TextView.
The way I am thinking of going is somehow, when the Service is started, passing the TextView from the Activity to the Service and then the Service keeping a reference to it.
Another possible way is to make the Activity become a listener of the Service and then calling a method in the Service to update the TextView.
Any thoughts would be great and maybe some options.
Thanks in advance.
ADDITION
I'm sorry, I should also specify that I need this timer to run in the background. So when the application is sent to the background, I need the timer to carry on and only stop when I tell it to.
Service is not ideal for such minor task like this, moreover, Service can be run independently of activity. Also spawning new thread or using timer which introduces new thread into the application is not ideal for this relatively minor reason if you are thinking in the terms of mobile applications.
Instead use Handler in your fragment.
create handler in your fragment
private Handler mHandler = new Handler();
to execute your defined task call
mHandler.postDelayed(mUpdateTask, 1000);
or
mHandler.post(mUpdateTask);
and define your task in the fragment
private Runnable mUpdateTask = new Runnable() {
public void run() {
Toast.makeText(getActivity(), "hello world", Toast.LENGTH_SHORT).show();
mHandler.postDelayed(this, 1000);
}
};
If you are showing time-like information instead of countdown-like one, use
mHandler.removeCallbacks(mUpdateTimeTask);
in onPause() method to stop executing your task if the activity is not visible as updating UI isn't relevant and it saves battery (you start task again in onResume() method)
Basically, the idea behind the timer is eventually I am going to add some tracking into my application and therefore need it to continue running even if the application isn't in the foreground – Disco S2
Based on this comment I suggest you to use a local service which resides in the background, doing it's stuff (start a thread from Service#onStart), until it gets stopped by stopService(..).
Activities on the other hand may bind and unbind to that service (see: bindService(..)) to get notified about updates or to communicate with the service in any way.
I would use a more simple approach by using a Thread:
public class MainActivity extends Activity implements Callback {
private static final int MSG_UPDATE = 1;
private static final long INTERVAL = 1000; // in ms
private final Handler handler = new Handler(this);
private Thread worker;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case MSG_UPDATE:
updateView();
return true;
}
return false;
}
private void updateView() {
// TODO tbd
}
#Override
protected void onStart() {
super.onStart();
// start background thread
worker = new Thread(new Runnable() {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(INTERVAL);
} catch (InterruptedException e) {
break;
}
// send message to activity thread
handler.sendEmptyMessage(MSG_UPDATE);
}
}
});
worker.start();
}
#Override
protected void onStop() {
super.onStop();
// stop background thread
worker.interrupt();
try {
worker.join();
} catch (InterruptedException e) {
}
worker = null;
}
}
You can use the TimerTask Class for this. Override the TimerTask.run() method and then add that TimerTask to Timer class.
Also check this question: controlling a task with timer and timertask
I have an android application with different activities and they all pull data from a web source. This is done by implementing Runnable and creating a thread with the activity as object. The basic class looks like this:
public ActivityX extends Activity implements Runnable {
#Override
public onResume() {
super.onResume();
Thread someThread = new Thread(this);
someThread.start();
}
#Override
public run() {
try {
// pull web content
}
catch(TimeOutException e) {
// >>> create dialog here <<<
// go back to another activity
}
}
}
I tried to create a dialog helper class with a static method that returns the timeout dialog and then call show() like this:
HelperClass.getTimeOutDialog().show();
but the problem is, I can't call it from inside the run() method, as it's in a different thread. If I try to, I will get a runtime exception stating:
Can't create handler inside thread that has not called Looper.prepare()
I need to do this dialog for nearly a dozen of activities and I really want to get around using a Handler objects and sending a message to call the dialog every time. Isn't there an easier way to do this? I just can't think of any right now unfortunately.
My code would look something like this:
handler.handleEmptyMessage(1);
This is to call the handler. And the following would handle the message:
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
if(msg.what == 1) {
// show dialog here
}
}
};
Cheers
#Override
public run() {
try {
// pull web content
}
catch(TimeOutException e) {
runOnUiThread(new Runnable(){
#Override
public void run() {
// >>> create dialog here <<<
// go back to another activity
}
}
}
}
Try the one above if you don't want to use Handler.
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
if(msg.what == 1) {
// show dialog here
}
}
};
Is this code a part of your activity and not in a thread? If it is a part of your non Ui thread, it would give you the error message. Make sure the handler instance is created in your UI thread because a handler contains an implicit reference to the thread they get created in.
i developed an application which sends birthday wishes on facebook wall, but when i am calling someone at same time that i set for sending wishes, then wishes failed to post on facebook wall.
I used Alarm Manager first.
But i want to use timer class and in that timer class i want to check that message is posted to wall or not at defined time or if not then i want to reschedule the timer class to send post.
i have this code for timer class
private final Timer clockTimer;
private class Task extends TimerTask {
public void run() {
timerHandler.sendEmptyMessage(0);
}
}
private final Handler timerHandler = new Handler() {
public void handleMessage (Message msg) {
// runs in context of the main thread
timerSignal();
}
};
private List<SystemTimerListener> clockListener = new ArrayList<SystemTimerListener>();
public SystemTimerAndroid() {
clockTimer = new Timer();
clockTimer.schedule(new Task(), 1000, 1000);
}
private void timerSignal() {
for(SystemTimerListener listener : clockListener)
listener.onSystemTimeSignal();
}
public void killTimer() {
clockTimer.cancel();
}
#Override
public void addListener(SystemTimerListener listener) {
clockListener.add(listener);
}
this code is repeating after every second so i want to check if it runned for first time then stop the timer and reschedule for next day and so on...
Please help me.
you can check it by putting System.out.println() or any Logcat. you can also check is by putting Toast in Timer Run Method. So Everytime when Run Method executes , the Toast will be appear on the screen for notification.