I have a method in my main activity that executes an async class which works fine, but when I put the alert box code inside it doesnt not work. I.E.
public void onGetStatus(View v) {
new AsyncClass().execute();
}
}
class AsyncClass extends AsyncTask < Void, Void, String > {
#
Override
protected String doInBackground(String...params) {
//TODO
}
}
protected void onPostExecute(String test) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setMessage(test);
alertDialogBuilder.show();
}
When I try to execute the AlertDialogBuilder in the onPostexecture method of class it doesnt work, but if I copy and paste into the the method thats calling the AsyncTask class it works fine.
this calls the current object which is Async. Do this :-
protected void onPostExecute(String test) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(MainActivity.this);//Put your activityname instead of MainActivity
alertDialogBuilder.setMessage(test);
alertDialogBuilder.show();
}
change new AlertDialog.Builder(this) to new AlertDialog.Builder(youractivity.this)
Related
I am trying to close progress dialog after exception occurred, but my current scenario is not allowing me to.
I have 3 classes:
MainActivity
SecondClass
ThirdClass
From MainActivity I am running a task using AsyncTask and shows a progress dialog, while a task is done in background.
#Override
public void onCreate(Bundle savedInstanceState)
{
// my code ...
BackgroundTask bt = new BackgroundTask();
bt.execute();
}
private class BackgroundTask extends AsyncTask<Void, Void, Void>
{
private ProgressDialog PD;
#Override
protected void onPreExecute()
{
PD = new ProgressDialog(getActivity());
PD.setMessage("Performing background tasks...");
PD.setCancelable(false);
PD.show();
}
#Override
protected Void doInBackground(Void... arg0)
{
// call SecondClass's getMyPhotos method to perform some tasks
// ...
return null;
}
protected void onPostExecute(Void... arg0)
{
Log.i("MainActivity", "--called--");
}
}
My SecondClass is simple Java class with some methods
public class SecondClass
{
// ....
public void getMyPhotos()
{
// from here I call ThirdClass's internetRelatedStuff method
}
}
And lastly in ThirdClass I am doing some internet related stuff in AsyncTask:
public class ThirdClass
{
// ....
public void internetRelatedStuff()
{
try
{
// again some other stuff...
// LoadImage asyncTask
LoadImage loadImg = new LoadImage();
loadImg.execute();
}
catch(Exception e)
{
if(e.getErrorCode() == 34)
{
// if I get an exception here, how am I suppose to close close Progress dialog
// of MainActivity
}
}
}
private class LoadImage extends AsyncTask<.......>
{
// .....
}
}
So in my ThirdClass's try/catch, is it possible if an exception occurred, I can close the Progress dialog which is showing from MainActivity?
Yes, there are multiple ways to do this. you can pass the ProgressDialog object in the MainActivity to the SecondClass's getMyPhotos() method then to the ThirdClass constructor then dismiss the dialog
There are couple of ways you can do this, let me point out two ....
You can pass your dialog from activity to SecondClass and then from SecondClass to third class, and use it there to close the dialog ... You will have define ProgressDialog in both second and thirdclass,
Create a static variable ProgressDialog in Activity and a static function closeDialogs()
where you can close your dialogs and you can call it using static ref. from third class,
I personally like this one ....
I have a splash screen that runs an asyncTask that downloads data from an API. On that task's OnPostExecute I run the next asyncTask to send stored emails. Once that is complete I need an AlertDialog to popup with an ok button so the user knows the downloads are complete. I used this SO question to get as far as I have:
Android AlertDialog inside AsyncTask
Now I'm getting a NullPointerException when I attempt to add properties to the dialog:
public class JSONParser extends AsyncTask<String, String, JSONObject> {
Context c;
public JSONParser(int api,Context c) {
this.api= api;
this.c = c;
}
...
protected void onPostExecute(JSONObject result) {
JSONObject output = new JSONEmailParser(c).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, new String[] {null,null,null,null}).get();
}
}
public class JSONEmailParser extends AsyncTask<String, String, JSONObject> {
Context c;
AlertDialog.Builder builder;
public JSONEmailParser(Context c){
this.c = c;
}
protected void onPreExecute(int api){
builder = new AlertDialog.Builder(SplashScreen.this);
}
...
protected void onPostExecute(JSONObject result) {
setLastUpdate();
builder.setTitle("Sales Toolkit");
builder.setCancelable(false);
builder.setMessage("Download Complete");
builder.setPositiveButton("Continue", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
dialog.dismiss();
endSplash();
}
});
builder.show();
}
}
The error is coming up on builder.setTitle("Sales Toolkit");
AsyncTask#onPreExecute() doesn't take an int argument. Since your method has the wrong signature, it is likely never being called, and therefore builder is never set. This is a classic example of why you should use #Override annotations.
Do not use a .get() to execute an AsyncTask as it will not be async anymore. And onPreExecute will not be called?
It seems like the onPreExecute() method is not being called. If you don't really need to use the builder anywhere before the onPostExecute() method, I would suggest just moving
builder = new AlertDialog.Builder(SplashScreen.this);
into the onPostExecute() method.
I am creating an application class to perform some version checks during application launch. Below is my class.
public class MyApp extends Application {
public MyApp() {
}
#Override
public void onCreate() {
super.onCreate();
new checkVersionTask().execute(getApplicationContext)
}
private class checkVersionTask extends AsyncTask<Context, Integer, Long> {
#Override
protected Long doInBackground(Context... contexts) {
TODO—version check code
}
protected void onPostExecute(Long result) {
AlertDialog alertDialog;
alertDialog = new AlertDialog.Builder(MyApp.this).create();
alertDialog.setMessage(("A new version of app is available. Would you like to upgrade now?"));
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, getResources().getString(R.string.Button_Text_Yes), new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which) {
Uri uri = Uri.parse("update URL");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
});
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE,getResources().getString(R.string.Button_Text_No), new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.show();
}
}
catch(Exception e){
Toast.makeText(getApplicationContext(), "ERROR:"+e.toString(), Toast.LENGTH_LONG).show();
}
}
}
}
here alertDialog.show is throwing error
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
As I understand this is because the context is not available. In the line
alertDialog = new AlertDialog.Builder(MyApp.this).create();
I tried getApplicationContext() instead of MyApp.this, still the same issue.
Can anyone suggest what's going wrong here. All the Toast statement are working fine.
You can not create a dialog within an application class since, the Dialog should be attached to a window, an Application is not UI class and has no window, so it can't show the dialog.
you can solve it by creating an activity which will show the dialog (you can pass the data as an extra with the intent), and when the data is ready fire and intent and show the dialog
There are two options for giving your AsyncTask the proper context:
1) Use getBaseContext()
I'm not positive if this will work, it seems to function in some situations rather than others.
2) If THAT doesn't work, you'll need to set up a constructor method for your checkVersionTask, as follows.
Context context; //member variable of the checkVersionTask class
public checkVersionTask(Context c) {
this.context = c;
}
Then, when you call the task in your onCreate method, or anywhere in your activity class for that matter, call it like so
new checkVersionTask(MyApp.this).execute();
Whenever you need to access context within the checkVersionTask, just say, for example
alertDialog = new AlertDialog.Builder(context).create();
I'm using a AsyncTask
I use parent to create the intent no errors.
The line to creat a dialog gives a
parent cannot be resolved to a ye.
new parent.AlertDialog.Builder(this)
The error I get is that parent does not exist, but I use parent in the same methed to call the intent
code block
private class SendTextOperation extends AsyncTask {
#Override
protected void onPreExecute() {
//Update UI here
}
#Override
protected String doInBackground(String... params) {
// Talk to server here to avoid Ui hanging
rt=TalkToServer("http://besttechsolutions.biz/projects/bookclub/login.php");
return(rt);
}
#Override
protected void onPostExecute(String result) {
if (rt.contains("ok"))
{
Intent i = new Intent(parent, cChat.class);
startActivity(i);
}
else
{
new parent.AlertDialog.Builder(this)
.setTitle("Game Over")
.setMessage("Your time is up, You saved "
+" Million more people!!")
.setNeutralButton("Try Again",new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dlg, int i)
{
}} ).show();
}
}
}
For showing AlertDialog from non Activity you will need to pass Current Activity Context to non Activity class in your case to SendTextOperation class.
Create an Constructor for SendTextOperation as :
public class SendTextOperation extends AsyncTask<String,Void,String>{
Context context;
public SendTextOperation(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
//Update UI here
}
#Override
protected String doInBackground(String... params) {
// Talk to server here to avoid Ui hanging
rt=TalkToServer("http://besttechsolutions.biz/projects/bookclub/login.php");
return(rt);
}
#Override
protected void onPostExecute(String result) {
if (rt.contains("ok"))
{
Intent i = new Intent(context, cChat.class);
startActivity(i);
}
else
{
new context.AlertDialog.Builder(context)
.setTitle("Game Over")
.setMessage("Your time is up, You saved "
+" Million more people!!")
.setNeutralButton("Try Again",new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dlg, int i)
{
}} ).show();
}
}
}
and start SendTextOperation AsyncTask as :
SendTextOperation sendtxtasyncTask = new SendTextOperation(CurrentActivity.this);
sendtxtasyncTask.execute("");
Lets say you have that class declared inside a class named MyActivity
Then use instead of this, MyActivity.this when creating the Dialog.
It looks like you should be calling it like this:
final AlertDialog.Builder builder = new AlertDialog.Builder(_context);
builder.setMessage(_context.getString(R.string.error) + ": " + _errorMessage)
.setTitle(_context.getString(R.string.loginError))
.setIcon(android.R.drawable.ic_dialog_alert)
.setCancelable(true)
.setPositiveButton(_context.getString(R.string.ok), null);
final AlertDialog alert = builder.create();
alert.show();
(My own sample code)
It looks like your error is trying to do parent.AlertDialog.Builder(this), where you need to use new AlertDialog.Builder(parent), if parent is your context.
I display an Alertbox with ok or cancel.
I want to implement an asynch task on the press of OK. Havent done asynch and been struggling with it for awhile. I dont understand where the asych class goes also. Does it go outside the method that is being executed or outside of it? Current code as follows:
private abstract class DoAsynchTask extends AsyncTask<Void,Void,Void>
{
protected void doInBackground()
{
Drawable drawable= getImage(imageSelect);
MakeWallPaper(drawable,1);
}
/* protected void onProgressUpdate(Integer... progress)
{
setProgress(progress[0]);
}*/
protected void onPostExecute()
{
Toast.makeText(getApplicationContext(), "Wallpaper Saved.",Toast.LENGTH_LONG).show();
AlertDialogProcessing=0;
}
}
public void getWallpaper(final View v)
{
if(AlertDialogProcessing==0)
{
final String title="Set Image to Wallpaper";
final String message="Press OK to set as Wallpaper or CANCEL.\nWait after pushing OK.";
final String ok="OK";
final String cancel="CANCEL";
final AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
alertbox.setCancelable(true);
alertbox.setIcon(android.R.drawable.ic_dialog_alert);
alertbox.setTitle(title);
alertbox.setMessage(message);
alertbox.setNegativeButton(cancel, null);
final AlertDialog dlg = alertbox.create();
alertbox.setPositiveButton(ok,new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dlg, int which)
{
DoAsynchTask.execute(null,null,null); //<<<<Wrong
dlg.dismiss();
Vibrate(ClickVibrate);
}
});
alertbox.setNegativeButton(cancel,new DialogInterface.OnClickListener(){ public void onClick(DialogInterface arg0, int arg1){AlertDialogProcessing=0;
Vibrate(ClickVibrate); } });
alertbox.show();
}
}
There's a couple problems in the code.
1) First of all, the compiler is probably giving you this message:
The type MyActivity.DoAsynchTask must implement the inherited abstract
method
AsyncTask.doInBackground(Void...) MyActivity.java
If you look closely at the error message, you'll realize that what you defined was this:
protected void doInBackground() {
which is not what is needed. Even though it might seem silly, when your AsyncTask subclass takes Void as the generic parameter types, that means that doInBackground() must look like this:
protected Void doInBackground(Void... arg0) {
The compiler complains because you haven't implemented that (exact) method. When you inherit from an abstract class, and fail to implement all of its required/abstract method(s), then you can only get it to compile by marking the subclass as abstract, too. But, that's not really what you want.
So, just change your code to (remove abstract from your class):
private class DoAsynchTask extends AsyncTask<Void,Void,Void>
and
protected Void doInBackground(Void... arg0) {
{
Drawable drawable= getImage(imageSelect);
MakeWallPaper(drawable,1);
return null;
}
2) And the second problem, as others have pointed out, is that you must start your task with:
new DoAsynchTask().execute();
not
DoAsynchTask.execute(null,null,null);
Your code would only be correct if execute() was a static method in AsyncTask, which it's not. In order to invoke the non-static execute() method, you first need a new instance of the DoAsynchTask class. Finally, the null, null, null parameter list is also not necessary, although I don't think it will cause the code to fail either.
Since your doInBackground() does not specify any parameters, you should call DoAsynchTask.execute() without parameters.
Why is your class abstract? Normally an AsyncTask should be an inner class of the activity starting it. So create your dialog in the activity, and execute the AsyncTask when clicking on OK button, like you do.
//final working copy -Thanks ALL
public void getWallpaper(final View v)
{
Vibrate(ClickVibrate);
final class SetWallPaperAsynchTask extends AsyncTask<Void,Void,Void>
{
#Override
protected Void doInBackground(Void... arg0)
{
Drawable drawable= getImage(imageSelect);
MakeWallPaper(drawable,1);
return null;
}
#Override
protected void onPostExecute(Void result)
{Toast.makeText(getBaseContext(), "Wallpaper Saved.", Toast.LENGTH_LONG).show();
AlertDialogProcessing=0;
}
}
if(AlertDialogProcessing==0)
{
ProgressDialog progress;
final String title="Set Image to Wallpaper";
final String message="Press OK to set as Wallpaper or CANCEL.";
final String ok="OK";
final String cancel="CANCEL";
final AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
alertbox.setCancelable(true);
alertbox.setIcon(android.R.drawable.ic_dialog_alert);
alertbox.setTitle(title);
alertbox.setMessage(message);
alertbox.setNegativeButton(cancel, null);
final AlertDialog dlg = alertbox.create();
alertbox.setPositiveButton(ok,new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface arg0, int arg1)
{
new SetWallPaperAsynchTask().execute();
dlg.dismiss();
Vibrate(ClickVibrate);
}
});
alertbox.setNegativeButton(cancel,new DialogInterface.OnClickListener(){ public void onClick(DialogInterface arg0, int arg1){AlertDialogProcessing=0; Vibrate(ClickVibrate); } });
alertbox.show();
}
}