I am trying to send email using async method as shown below and everything is working fine..
Now I would like to display a dialog on successfull email.
This is my async code:
public void sending(View v) {
try {
LongOperation l=new LongOperation();
l.execute();
Toast.makeText(this, l.get(), Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Log.e("SendMail", e.getMessage(), e);
}
}
public class LongOperation extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
try{GMailSender sender = new GMailSender("XXX#gmail.com","Pwd");
sender.sendMail("Sub",
"body",
"sender",
"recepient");
}
catch(Exception e){Log.e("error",e.getMessage(),e);return "Email Not Sent";}
return "Email Sent";
}
#Override
protected void onPostExecute(String result)
{
}
#Override
protected void onPreExecute()
{
}
#Override
protected void onProgressUpdate(Void... values)
{
}
In the above code if the mail is not sent I'm getting a toast as "Email Sent" and If not send the email I would get "Email Not Sent"
1)In the place of toasts I would like to display a dialog.
2)I have done it in onPostExecute and it worked fine.
But here comes the problem.Suppose if there is no internet connection and user clicks the button both the toast "Email Not sent" and the dialog is displaying after onPostExecute method.
I would only like to display the dialog.
So how do I modify the above code inorder to remove the toasts and only get the dialog for successfull and unsuccessfull email.
Here is my dialog code:
new AlertDialog.Builder(MainActivity.this)
.setTitle("Info")
.setMessage("Sample message.")
.setPositiveButton("OK",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
Log.d("AlertDialog","Positive");
}}).show();
Still not completely sure I understand the problem but maybe this is what you want.
public void sending(View v) {
try {
LongOperation l=new LongOperation();
l.execute();
} catch (Exception e) {
Log.e("SendMail", e.getMessage(), e);
}
}
public class LongOperation extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
try{GMailSender sender = new GMailSender("XXX#gmail.com","Pwd");
sender.sendMail("Sub",
"body",
"sender",
"recepient");
}
catch(Exception e){Log.e("error",e.getMessage(),e);return "Email Not Sent";}
return "Email Sent";
}
#Override
protected void onPostExecute(String result)
{
if ("Email Sent".equals(result))
{
new AlertDialog.Builder(MainActivity.this)
.setTitle("Info")
.setMessage("Sample message.")
.setPositiveButton("OK",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
Log.d("AlertDialog","Positive");
}}).show();
}
#Override
protected void onPreExecute()
{
}
#Override
protected void onProgressUpdate(Void... values)
{
}
I simply removed the Toast since you don't want that at all. Then I placed the Dialog code in onPostExecute() and checked the result passed to it from doInBackground(). I only showed it if the result is "Email Sent". You can change that to pass back a different result from doInBackground() if it isn't sent and show a different message in your Dialog.
Edit
I almost forgot to mention, you almost never want to use .get() on an AsyncTask. It is a blocking call which means everything will halt until your task is finished. You update the UI in any task method besides doInBackground() or you use an interface with a callback.
See this answer if you need an interface
Related
I'm having some problems running a thread in my android application, It should show a dialog asking the user something and if the user clicks yes, a loading dialog should appear while it's doing something in the background, I created a thread but when I click the yes button, the UI still locks up until the process is done.
Code:
Dialog:
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("LOGO.bin Was Not Found, Would You Like To Extract It?")
.setTitle("LOGO Not Found!");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
getAndExtract();
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
System.exit(0);
}
});
AlertDialog dialog = builder.create();
dialog.show();
getAndExtract:
public void getAndExtract()
{
new Thread(new Runnable() {
#Override
public void run() {
try {
showLoad("Grabbing Logo...");
getLogo();
Thread.sleep(2000);
progressDialog.cancel();
showLoad("Extracting Images...");
extractImages();
Thread.sleep(2000);
progressDialog.cancel();
}catch (InterruptedException iE)
{
iE.printStackTrace();
}
}
}).run();
}
showLoad:
progressDialog.setMessage(msg);
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.show();
basics of extractImages:
Command cmd = new Command(0, "LogoInjector -i " + getFilesDir() + "/LOGO.bin -d -g " + getFilesDir() + "/");
RootTools.getShell(true).add(cmd);
basics of getLogo:
Command cmd = new Command(0, "dd if=/dev/block/mmcblk0p" + partitionIndex + " of=" + getFilesDir() + "/LOGO.bin");
RootTools.getShell(true).add(cmd);
I also tried putting showLoad in runOnUiThread but there was no change... if I remove progressDialog.cancel(); it does show the loading dialog but after the extract is already complete. I press Yes and it just hangs until getLogo() and extractImages() both completed
Can anyone help me find out why this isn't working?
Thanks!
Try using AsyncTask:
final AsyncTask<Void,Void,Void> asyncTask = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
// do whatever you need to do in background
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute( aVoid);
// do after finished
}
};
asyncTask.execute();
Hope that helps =]
I have to display different messages in progress dialog, when running in async task.
First I need to the display the message "Please wait", then "Downloading from server", then "Please wait for sometime".
I have tried with publishProgress but when I run the application, on my ProgressDialog, only the last message "Please wait for sometime" is displayed. How can I display the three messages?
private class Sample extends AsyncTask<String, String, String> {
ProgressDialog testdialog;
#Override
protected void onPreExecute() {
testdialog = new ProgressDialog(test.this);
testdialog.setTitle("Title");
testdialog.setMessage("Please wait ");
testdialog.setIndeterminate(false);
testdialog.setCancelable(false);
testdialog.setCanceledOnTouchOutside(false);
testdialog.show();
}
#Override
protected String doInBackground(String... urls) {
publishProgress("Downloading from server");
publishProgress("Please wait for sometime");
/* here I code the background downloading process*/
}
#Override
protected void onProgressUpdate(String... pro) {
testdialog.setMessage(pro[0]);
testdialog.setMessage(pro[1]);
}
#Override
protected void onPostExecute(String result) {
testdialog.dismiss();
}
}
try this code in doInBackground() it should display all messages with 2 seconds delay for each
except last one will remain on the dialog until dialog is dismissed or hidden
#Override
protected String doInBackground(String... urls) {
try {//this should let "Please wait " appears for 2 secs
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress("Downloading from server");
try {////this should let "Downloading from server" appears for 2 secs
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress("Please wait for sometime");
try {////this should let "Please wait for sometime" appears for 2 secs
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
/* here i code the background downloading process*/
}
also for onProgressUpdate() the method is prepared to receive multi params, but you are sending only one, so no need to use pro[1], remove second setMessage() call
#Override
protected void onProgressUpdate(String... pro) {
testdialog.setMessage(pro[0]);
}
The application crashed suddenly. The logcat says that there is an error in doInBackground(). Please help.
Code
private class regjson extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(getApplicationContext(), "in prExecute", Toast.LENGTH_SHORT).show();
}
#Override
protected String doInBackground(String... params) {
try{
Toast.makeText(getApplicationContext(), "in Background", Toast.LENGTH_SHORT).show();
}
catch(Exception e)
{
e.printStackTrace();
Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_SHORT).show() ;
}
return "All Done!";
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Toast.makeText(getApplicationContext(), "in Post Execute", Toast.LENGTH_SHORT).show();
}
}
and here is how i executed it
try{
new regjson().execute("hello");
}
catch(Exception e)
{
Toast.makeText(getApplicationContext(), e.toString(),Toast.LENGTH_LONG);
}
You cant show a Toast in doInBackground().YOu cant update the UI from doInBackground(), instaed you have to do it in onPostExecute().
Read more about it in the docs
So, you have to remove
Toast.makeText(getApplicationContext(), "in Background", Toast.LENGTH_SHORT).show();
from your code.
If you are using this Toast for debugging purposes you can use Log.d() like,
Log.d("Key","in Background");
And you can see this Log message in your Logcat.
For some reason my call to AsyncTask.cancel only works once, i.e. for the first instance of the task, and never again. The first task cancels beautifully and hits the onCancelled method. All the others seem to ignore the cancel() call and end up in onPostExecute.
The task is executed from a service:
public class ZitFtpService extends Service implements ZitFtpServiceInterface
{
//Blah blah
public void connect(String server, int port)
{
if(!isConnecting){
isConnecting = true;
ConnectTask task = new ConnectTask();
task.execute(server, String.valueOf(port));
}
}
//Blah blah blah
As you can see it is a new instance every time. I can't see why the first one would behave differently from the subsequent ones. The AsyncTask is a private inner class:
private class ConnectTask extends AsyncTask<String, String, Boolean> {
#Override
protected Boolean doInBackground(String... params) {
boolean result = false;
try {
publishProgress(
"start", "Connecting to "+ params[0] + ":" + params[1]);
Log.v("ZIT", params[0] + " " + params[1] + " " + params.length);
conn.connect(params[0], Integer.valueOf(params[1]), 1000);
result = true;
} catch (NumberFormatException e) {
Log.e("ZIT", e.getMessage());
} catch (IOException e) {
failMessage = e.getMessage();
e.printStackTrace();
}
return Boolean.valueOf(result);
}
private void cancelConnect() {
try {
conn.disconnect();
} catch (IOException e) {
e.printStackTrace();
} finally {
conn = new ZMobileFTPImpl();
}
if(!(dialog==null)) {
dialog.dismiss();
}
}
#Override
protected void onCancelled() {
Log.v("ZIT", "I was cancelled.");
isConnecting = false;
}
#Override
protected void onProgressUpdate(String... values) {
if(dialog == null) {
dialog = new ProgressDialog(progressActivity);
dialog.setCancelable(true);
dialog.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
ConnectTask.this.cancel(true);
cancelConnect();
dialog.dismiss();
}
});
dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
}
dialog.setMessage(values[1]);
dialog.setCancelable(true);
dialog.show();
}
#Override
protected void onPostExecute(Boolean result) {
dialog.dismiss();
if(!result) {
AlertDialog.Builder builder =
new AlertDialog.Builder(progressActivity);
builder.setMessage(failMessage).setTitle("Error");
failMessage = "";
builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
AlertDialog failDialog = builder.create();
failDialog.show();
}
isConnecting = false;
}
}
From Doc's
There are a few threading rules that must be followed for this class to work properly:
The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.
The task instance must be created on the UI thread.
execute(Params...) must be invoked on the UI thread.
Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) manually.
The task can be executed only once (an exception will be thrown if a second execution is attempted.)
So, you can call an AsyncTask multiple times by creating new instance every time like
new ConnectTask().execute(params);
This is intentional as you can only execute an AsyncTask instance once, you can run task.execute multiple times though...
Anyhow, I believe you forgot to add the super.onCancelled in following override:
#Override
public void onCancelled() {
//...
super.onCancelled();
}
Try if that helped, and otherwise you should share the error or log so we can troubleshoot that :)
progressDialog = ProgressDialog.show(GetResponse.this, "", "Loading...");
new Thread()
{
public void run()
{
try
{
// inside i have written code for making connection to the server using SSL connection.
}catch (Exception e)
{
progressDialog.dismiss();
exception(e.getMessage())
}.start();
}
private void exception(String msg)
{
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
this.finish();
Intent i = new Intent(getBaseContext(), LoginPage.class);
startActivity(i);
}
my LoginPage.java is previous activity.
If the connection is successfull it goes to the next activity ot doesnt give any error,
But if der is any prob with connection then i want progress bar should be stopped and go back to the LoginPage activity and also i want the error msg to be displayed.
From the above im getting some error.. Please help me out on this
Pass in and use the context from LoginPage. Also, use the 101010 button to format your code as code in your posts.
you can go up by using try catch mechanism where in your catch place your toast message and u can do it also by asynchronous task,
here simple code
private class Task_News_ArticleView extends AsyncTask<Void, Void, Void> {
private final ProgressDialog dialog = new ProgressDialog(
Bru_Sports_View.this);
// can use UI thread here
protected void onPreExecute() {
this.dialog.setMessage("Loading...");
this.dialog.setCancelable(false);
this.dialog.show();
}
#Override
protected Void doInBackground(Void... params) {
try {
//here the condition to check login details
}
} catch (Exception e) {
}
return null;
}
protected void onPostExecute(Void result) {
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
}
}
and u can also use try,catch in catch block you can place your toast message
with finsih() method