Can I show Toast from none-UI Service in android? - android

I have a service which is working in background.
How can I show Toast text message from Service that does not have UI?
No Activity,This is none-UI service.
Is it possible?

You can certainly do that. A service is a Context. So you can call
Toast.makeText(this, "My Information", Toast.LENGTH_SHORT).show();

Try this in your background thread.
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Toast.makeText(context, "Running background", Toast.LENGTH_SHORT).show();
}
});

I have been showing it from dummy classes by using the application class instance, basically what this means that you can show it anywhere within you application (includes service).
public class DemosApplication extends Application {
private static DemosApplication instance;
private Toast toast;
public static DemosApplication getInstance() {
return instance;
}
#Override
public void onCreate() {
super.onCreate();
if (instance == null) {
instance = this;
}
}
public void showToast(int resID) {
showToast(getString(resID));
}
public void showToast(String text) {
if (toast != null) {
toast.cancel();
}
toast = Toast.makeText(this, text, Toast.LENGTH_SHORT);
toast.show();
}
}
Usage from anywhere
DemosApplication.getInstance().showToast("Lalalala");

Related

How to kill Toast after exit app?

Need some help. I used double click on back button for exit app with Toast with next code:
#Override
public void onBackPressed() {
if (back_pressed + 2000 > System.currentTimeMillis()) {
super.onBackPressed();
} else {
Toast.makeText(getBaseContext(), "Нажмите еще раз для выхода", Toast.LENGTH_SHORT).show();
}
back_pressed = System.currentTimeMillis();
}
Found that fragment code here at stackoverflow. I guess this is the best solution for issue. But there is one ecxeption - toast is still on screen after exiting app. How to kill the toast when user click back button twice and application closed?
We can't kill toast when application closes. We can use toast like below code. Toast.LENGTH_SHORT).show(); less duration of toast when your app closes.
Toast.makeText(this, "Press again to exit.. ", Toast.LENGTH_SHORT).show();
Or, you can set Duration of Toast by code below:
Toast toast = Toast.makeText(getApplicationContext(), "Press again to exit..", Toast.LENGTH_SHORT);
toast.show();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
toast.cancel();
}
}, 500);
Or, you can use this :
private Toast toast = null;
toast = Toast.makeText(getApplicationContext(), "", Toast.LENGTH_SHORT);
#Override
public void onBackPressed() {
if (doubleBackToExitPressedOnce) {
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
//Toast.makeText(this, "Press again to exit..", Toast.LENGTH_SHORT).show();
toast.setText("Press again to exit..");
toast.show();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
doubleBackToExitPressedOnce=false;
}
}, 2000);
}
#Override
protected void onStop () {
super.onStop();
toast.cancel();
}
You should be able to reach your goal by Using an helper class. In my applications I call this ToastManager.
In this class, you will manage every toast of your application and you can decide whether to dismiss or show them.
I did it to avoid the Toast queue, I'm dismissing the Toast when another one is shown.
You can implement it like below and call the dismissToast method in your custom application or Activity.
public class ToastManager {
private static Toast m_currentToast;
public static void showToast(Context ctx, String text)
{
try {
if (m_currentToast != null) {
m_currentToast.cancel();
}
m_currentToast = Toast.makeText(ctx, text, Toast.LENGTH_LONG);
m_currentToast.show();
}catch(Exception ex){
ex.printStackTrace();
}
}
public static void dismissToast(){
if(m_currentToast != null){
m_currentToast.cancel();
}
}
}
Obv you will have to create each tost by calling the showToast method.
hope this helps
Next code erase toast immediately after closing application:
#Override
protected void onStop () {
toast.cancel();
super.onStop();
}
I guess this is enough for my app, it's looking great.
Tnx Abhishek kumar )

Android: Toast is not showing before system.exit()

I have nested nested class where I am trying to display a toast for the outer most class before I exit the app. The toast works just fine if I comment out exit statement, so I know I'm accessing the context correctly. I have also tried putting the toast in a thread where it sleeps for 2000 ms (and vice versa for the exit statement), but that still does not work.
All I want to do display a toast and exit the program. (It would be nice to do it simultaneously, if possible...)
public class A extends Service {
private Context context;
//...
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
context = this;
//...
return START_STICKY;
}
Handler disToast = new Handler(new Callback() {
#Override
public boolean handleMessage(Message msg) {
Toast.makeText(context, "see ya", Toast.LENGTH_SHORT).show();
return true;//also tried false, but that did not work...
}
});
private Runnable r = new Runnable() {
public void run() {
new CountDownTimer(3000, 1000) {
public void onFinish() {
Message msg=disToast.obtainMessage();
msg.obj="my message";
disToast.sendMessage(msg);
handler.removeCallbacks(updateTimerThread);
System.exit(0);
}
}.start();//end of inner most class
};//end of first inner class
}//outermost class
I'm not working with any Activities (outer most class is a Service, and the two inner are normal Java classes) so some of the answers do not work.
USE getApplicationConext() INSTEAD OF CONTEXT
Toast.makeText(getApplicationConext(), "Timer up. Existing app...", Toast.LENGTH_SHORT).show();
Handler disToast= new Handler(new Callback() {
#Override
public void handleMessage(Message msg) {
String mString=(String)msg.obj;
Toast.makeText(this, mString, Toast.LENGTH_SHORT).show();
}
});
private Runnable r = new Runnable() {
public void run() {
new CountDownTimer(3000, 1000) {
public void onFinish() {
Message msg=disToast.obtainMessage();
msg.obj="your message";
disToast.sendMessage(msg);
handler.removeCallbacks(updateTimerThread);
System.exit(0);
}
}.start();
};
More details Refer Here
please use
Toast.LENGTH_LONG instead of
Toast.LENGTH_SHORT
Toast.makeText(context, "Timer up. Existing app...", Toast.LENGTH_LONG).show();
Now your toast will be display after System.exit();

Is it normal to show a single Toast multiple times on Android?

I'm using Toast to show some informations to the user, because I want to show the newest message without delay regardless of the previous messages, I do it like this (learned from old projects):
public class MainActivity extends Activity {
private Toast mToast;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mToast = Toast.makeText(this, "", Toast.LENGTH_SHORT);
}
private void toast(final String message) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mToast.setText(message);
mToast.show();
}
});
}
}
That is, the single Toast object is reused and showed multiple times, whenever I need show a new message, I just setText and show it again. It seems working fine, but after I did some searching on Google, I found most people will do it like this:
private void toast(final String message) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mToast.cancel();
mToast = Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT);
mToast.show();
}
});
}
Which cancel the previous Toast then make a new one by Toast.makeText.
Are there any differences? Which one should I prefer?
You can cache current Toast in Activity's variable, and then cancel it just before showing next toast. Here is an example:
Toast m_currentToast;
void showToast(String text)
{
if(m_currentToast != null)
{
m_currentToast.cancel();
}
m_currentToast = Toast.makeText(this, text, Toast.LENGTH_LONG);
m_currentToast.show();
}
Another way to instantly update Toast message:
void showToast(String text)
{
if(m_currentToast == null)
{
m_currentToast = Toast.makeText(this, text, Toast.LENGTH_LONG);
}
m_currentToast.setText(text);
m_currentToast.setDuration(Toast.LENGTH_LONG);
m_currentToast.show();
}
Reference : How to immediately replace the current toast with a second one without waiting for the current one to finish?
You should try code something like this to avoid visibility of multiple toast at a time.
private void toast(final String message) {
try{ mToast.getView().isShown(); // true if visible
mToast.setText(message);
} catch (Exception e) { // invisible if exception
mToast = Toast.makeText(theContext, message, toastDuration);
}
mToast.show(); //finally display it
}
code help me is here

IntentService won't show Toast

This IntentService I created will show Toasts in onStartCommand() and in onDestroy(), but not in onHandleIntent(). Am I missing something about the limitations of an IntentService?
public class MyService extends IntentService {
private static final String TAG = "MyService";
public MyService(){
super("MyService");
}
#Override
protected void onHandleIntent(Intent intent) {
cycle();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show(); //This happens!
return super.onStartCommand(intent,flags,startId);
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
Toast.makeText(this, "service stopping", Toast.LENGTH_SHORT).show(); //This happens!
super.onDestroy();
}
private void cycle(){
Toast.makeText(this, "cycle done", Toast.LENGTH_SHORT).show(); //This DOESN'T happen!
Log.d(TAG,"cycle completed"); //This happens!
}
}
The accepted answer is not correct.
Here is how you can show toast from onHandleIntent():
Create a DisplayToast class:
public class DisplayToast implements Runnable {
private final Context mContext;
String mText;
public DisplayToast(Context mContext, String text){
this.mContext = mContext;
mText = text;
}
public void run(){
Toast.makeText(mContext, mText, Toast.LENGTH_SHORT).show();
}
}
Instantiate a Handler in your service's constructor and call the post method with a DisplayToast object inside.
public class MyService extends IntentService {
Handler mHandler;
public MyService(){
super("MyService");
mHandler = new Handler();
}
#Override
protected void onHandleIntent(Intent intent) {
mHandler.post(new DisplayToast(this, "Hello World!"));
}
}
You should start the Toast on the main thread:
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
}
});
This is because otherwise the thread of the IntentService quits before the toast can be send out, causing a IllegalStateException:
java.lang.IllegalStateException: Handler (android.os.Handler) {12345678} sending message to a Handler on a dead thread
onHandleIntent() is called from a background thread (that is what IntentService is all about), so you shouldn't do UI from there.
Another option is RxJava, e.g.:
private void showToast(final String text) {
Observable.just(text)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<String>() {
#Override
public void call(String s) {
Toast.makeText(getApplicationContext(), s, Toast.LENGTH_LONG).show();
}
});
}
Caveat: I'm new to Android.

Toast created in an IntentService never goes away

I have an IntentService that downloads some files. The problem is that I create a Toast inside the IntentService like this
Toast.makeText(getApplicationContext(), "some message", Toast.LENGTH_SHORT).show();
The Toast will never disappear event if I exit the app. The only way to destroy it is to kill the process.
What am I doing wrong?
The problem is that IntentService is not running on the main application thread. you need to obtain a Handler for the main thread (in onCreate()) and post the Toast to it as a Runnable.
the following code should do the trick:
#Override
public void onCreate() {
super.onCreate();
mHandler = new Handler();
}
#Override
protected void onHandleIntent(Intent intent) {
mHandler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(MyIntentService.this, "Hello Toast!", Toast.LENGTH_LONG).show();
}
});
}
This works for me:
public void ShowToastInIntentService(final String sText) {
final Context MyContext = this;
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Toast toast1 = Toast.makeText(MyContext, sText, Toast.LENGTH_LONG);
toast1.show();
}
});
};
IntentService will create a thread to handle the new intent, and terminated it immediately once the task has done. So, the Toast will be out of controlled by a dead thread.
You should see some exceptions in the console when the toast showing on the screen.
For people developing in Xamarin studio, this is how its done there:
Handler handler = new Handler ();
handler.Post (() => {
Toast.MakeText (_Context, "Your text here.", ToastLength.Short).Show ();
});
To show a toast when the user is in one of the application activity.
Just need a reference of the current activity, and call it with this sample code:
public void showToast(final String msg) {
final Activity a = currentActivity;
if (a != null ) {
a.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(a, msg, Toast.LENGTH_SHORT).show();
}
});
}
}
There is a lot of options to get the current activity, check this question:
How to get current foreground activity context in android?
But I use this approach:
The application must have:
private Activity currentActivity = null;
public Activity getCurrentActivity() {
return currentActivity;
}
public void setCurrentActivity(Activity mCurrentActivity) {
this.currentActivity = mCurrentActivity;
}
Each activity must have:
#Override
protected void onResume() {
super.onResume();
((MyApplication) getApplication()).setCurrentActivity(this);
}
#Override
protected void onPause() {
super.onPause();
((MyApplication) getApplication()).setCurrentActivity(null);
}
You shouldn't create Toasts from a Service. You should use a Notification instead.

Categories

Resources