I'm working on an Android project. I need to use Android 1.6 or above.
My project was working, but now it is showing me some warnings about Dialogs like
"The method dismissDialog(int) from the type Activity is deprecated"
"The method showDialog(int) from the type Activity is deprecated", etc.
So I want to "update" my project to solve these warnings.
I have read and made some test projects to learn about Fragments and DialogFragment.
I have created my own ProgressDialog and I want to use it on my real project, but I have some problems.
public class MyProgressDialog extends DialogFragment {
public MyProgressDialog(){
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Context context = getActivity();
ProgressDialog dialog = new ProgressDialog(context);
Resources resources = context.getResources();
String message = resources.getText(R.string.wait).toString();
dialog.setMessage(message);
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
return dialog;
}
}
Earlier in my project, I created the ProgressDialog and then, in onPrepareDialog() method, I called an AsyncTask to connect the server, downloaded the data, etc. Then in onPostExecute of the AsyncTask, I dismissed the ProgressDialog and started the new Activity. But now I can't do that because onPrepareDialog is deprecated.
Calling ActionAsyncTask on onPrepareDialog of Activy
#Override
protected void onPrepareDialog(int id, Dialog dialog) {
switch(id){
case Constants.PROGRESS_DIALOG:
new ActionAsyncTask().execute();
break;
}
}
onPostExecute of ActionAsyncTask
#Override
protected void onPostExecute(Integer result) {
dismissDialog(Constants.PROGRESS_DIALOG);
}
How can solve this? What is the right way to do this? I want to write the best code for this, the most efficient code.
Thanks.
Related
This has been driving me nuts and I cannot find an answer anywhere. A very simple spinner dialog, but the setMessage is not working, it's blank!
public class MainActivity extends FragmentActivity {
ProgressDialog loadingProgress;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loadingProgress = new ProgressDialog(this);
loadingProgress.setIndeterminate(true);
loadingProgress.setMessage("Loading");
loadingProgress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
}
In AsyncTask I just show the ProgressDialog:
protected void onPreExecute() {
super.onPreExecute();
loadingProgress.show();
}
The result is this:
Blank, nothing... Doesn't matter if it's simulator or device... Any ideas why? Your help is appreciated.
I've tested your code and saw the "Loading" string is displayed very well.
Seeing that your screenshot has the space of textview, i think it will be the problem of text color or theme.
If setMessage works, you can detect in "Dump View Hierarchy for UI Automator" tool of device tab in Eclipse like following screenshot.
Here is the code I am using in my app. It works well -- a spinner with a message. The main differences between what you show and this are: 1) I'm using a DialogFragment; 2) I don't call setProgressStyle. Not sure which (if either) of these matter, but this code definitely is working for me.
public void showProgressDialog(int stringResId, boolean isCancelable) {
Bundle arguments = new Bundle();
arguments.putString(EXTRA_MESSAGE, getString(stringResId));
arguments.putBoolean(EXTRA_CANCELABLE, isCancelable);
DialogFragment fragment = new ProgressDialogFragment();
fragment.setArguments(arguments);
showDialog(fragment);
}
public static class ProgressDialogFragment extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Bundle arguments = getArguments();
String message = arguments.getString(EXTRA_MESSAGE, null);
boolean isCancelable = arguments.getBoolean(EXTRA_CANCELABLE, true);
ProgressDialog dialog = new ProgressDialog(getActivity());
dialog.setIndeterminate(true);
if (message != null) {
dialog.setMessage(message);
}
dialog.setCancelable(isCancelable);
dialog.setCanceledOnTouchOutside(isCancelable);
return dialog;
}
}
I am starting the asynctask inside a SherlockListFragment which was created inside a SherlockFragmentActivity as a tab.
I pass the asynctask constructor my activity context and initialize the asynctask like this inside onCreate():
AsyncTask<String, Integer, String[]> asynctask = new DownloadFilesTask(getSherlockActivity()).execute(url);
The constructor inside the AsyncTask class DownloadFilesTask looks like this:
private ProgressDialog dialog;
private SherlockFragmentActivity activity;
public DownloadFilesTask(SherlockFragmentActivity activity) {
this.activity = activity;
this.dialog = new ProgressDialog(activity);
}
Pre-execute and post execute look like this:
protected void onPreExecute(){
Log.d("AsyncTask!", "Showing dialog now!"); //shown in logcat
dialog.setMessage("Retrieving all currently airing anime. Please wait.");
dialog.setCancelable(false);
dialog.show();
}
.
protected void onPostExecute(String[] result) {
Log.d("AsyncTask!", "Dismissing dialog now!"); //shown in logcat
dialog.dismiss();
}
But the progress dialog doesn't show up while all the background work is being done!
What am I doing wrong here? I think it might be a context problem.
Part of the problem was fixed thanks to the comment from Mike Repass about passing a plain old context.
As for the dialog not showing up...I was just being stupid because I called a .get() after the execute OUTSIDE the AsyncTask which blocks the UI thread. Obviously the dialog is not going to show up that way.
In Java "If your method overrides one of its superclass's methods, you can invoke the overridden method through the use of the keyword super." Therefore change your onPreExecute() method when you start progress dialog to:
#Override
protected void onPreExecute(){
super.onPreExecute();
dialog = new ProgressDialog(activity);
Log.d("AsyncTask!", "Showing dialog now!"); //shown in logcat
dialog.setMessage("Retreiving all currently airing anime. Please wait.");
dialog.setCancelable(false);
dialog.show();
}
I want to show a ProgressDialog in AsyncTask.
This run fantastic. But if i call mLoginPD.dissmiss() in onPostExecute() do not run.
The ProgressDialog is always on the screen.
Here is my code:
SherlockActivity mActivity;
ProgressDialog mLoginPD;
public Task_Login(String name, String pass, SherlockActivity activity) {
this.passwort = pass;
this.benutzername = name;
this.mActivity = activity;
}
protected void onPreExecute() {
super.onPreExecute();
mLoginPD = new ProgressDialog(mActivity);
mLoginPD.show(mActivity, "Login", "Logge Spieler ein...");
}
protected void onPostExecute(Void result) {
Log.e("hello", "hello");
mLoginPD.dismiss();
mLoginPD.cancel();
if(mLoginPD.isShowing()) {
mLoginPD.dismiss();
}
}
onPostExecute() calls. I can see "hello" in LogCat.
(I have doInBackground() but i is irrelevant)
The problem is that you're creating two ProgressDialog objects.
This line:
mLoginPD = new ProgressDialog(mActivity);
creates a dialog and assigns it to mLoginPD, but does not show it.
This line:
mLoginPD.show(mActivity, "Login", "Logge Spieler ein...");
creates another dialog and shows that one. The problem is that show() is a static method that creates and shows a dialog all in one. So it's creating a second one separate from mLoginPD which is shown. mLoginPD is never shown, so calling dismiss() or cancel() doesn't do anything.
What you need to do is this:
mLoginPD = ProgressDialog.show(mActivity, "Login", "Logge Spieler ein...");
in place of both those lines. This uses show() to create and show the dialog and assign it to mLoginPD so you can dismiss it later.
If you're overriding onPreExecute, i dont think you're supposed to call super.onPreExecute()?
The answer from Geobits istn running too. Always show a NullPointerException.
Here is the code to solve my problem:
mLoginPD = new ProgressDialog(mActivity);
mLoginPD.setTitle("Login");
mLoginPD.setMessage("Logge Spieler ein...");
mLoginPD.show();
than i can call mLoginDP.dismiss() or cancel() in onPostExecute()
In my activity I need a ProgressDialog with a horizontal progress bar to visualise the progress of a background task. To make the activity care for the dialog e.g. in case of screen rotation, I would like to use a managed dialog created in onCreateDialog. The problem is that I need to update the progress bar of the dialog after it has been created and therefor I need a reference to the managed progress dialog: Does anyone know how to retrieve a reference to a dialog created by onCreateDialog?
At the moment I am storing a reference to the dialog created in onCreateDialog, but that my fail with a InvalidArgumentException in the onFinished() method after the screen has been rotated (and the activity has been recreated):
public final class MyActivity extends Activity {
private static final int DIALOG_PROGRESS = 0;
private ProgressDialog progressDialog = null;
// [...]
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_PROGRESS:
progressDialog = createProgressDialog();
return progressDialog;
default:
return super.onCreateDialog(id);
}
}
// [...]
public void updateProgress(int progress) {
progressDialog.setProgress(0);
}
public void onFinished() {
progressDialog.dismiss();
}
// [...]
}
I would have expected something like a getDialog(int) method in the Activity class to get a reference to a managed dialog, but this doesn't seem to exist. Any ideas?
I answer myself:
There really is no getDialog(int) method available in the Activity class.
Storing the reference like shown above works correctly -- the bug was something else...
The problem was, that the parallel thread, that called the onFinished() method called this method on the already destroyed activity, thus the accessed ProgressDialog instance is still existing but no longer a valid dialog. Instead another activity with another ProgressDialog has already been created by Android.
So all I needed to do was to make the background thread call the onFinished() method of the new activity and everything works fine. To switch the reference I override the onRetainNonConfigurationInstance() and getLastNonConfigurationInstance() methods of the Activity class.
The good thing of the shown example: Android really cares about recreating the new dialog after the screen orientation changed. So constructing the ProgressDialog that way is definitely easier than using ProgressDialog.show() where I would need to handle the dialog recreation on my own (the two methods described above would be a good place to do this.
I want to create a dialog with a string that I build at runtime. It looks like API level 8 allows you to call showDialog with a bundle, but I have to write an app that will run on the older OSs.
How do I create a dialog with something like a simple error string and make sure it doesn't die when I rotate the screen.
I realize if I override onCreateDialog, it will do it for me. The problem is, this just takes the int constant. I need to pass a string to it so it knows what to put in the dialog.
If I build my dialog myself and then call .show() on it, it won't live through a screen orientation change.
If you're targeting API Level <8, then it's sort of a pain.
Set the string message to a property on your Activity
Use onSaveInstanceState(Bundle) and onRestoreInstanceState(Bundle) to manage your property through configuration changes (such as re-orientation)
In onPrepareDialog(int, Dialog), set the message of the dialog to this property. If you don't set this in onPrepareDialog, it'll re-display the previous dialog (in case your message needs to change between dialogs.)
Code:
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Save dialog message
if(dialogMessage != null) {
outState.putString(STATE_KEY_DIALOG_MESSAGE, dialogMessage);
}
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Load dialog message
if(savedInstanceState.containsKey(STATE_KEY_DIALOG_MESSAGE)) {
dialogMessage = savedInstanceState.getString(STATE_KEY_DIALOG_MESSAGE);
}
}
/** onCreateDialog as normal **/
#Override
protected void onPrepareDialog(int id, Dialog dialog) {
super.onPrepareDialog(id, dialog);
switch(id) {
case DIALOG_MESSAGE:
// Decorate dialog appropriately
AlertDialog messageDialog = (AlertDialog) dialog;
messageDialog.setMessage(dialogMessage);
}
}
You could just pass the string in the constructor.
public class MyDialog extends Dialog {
public MyDialog(Context context, String msg) {
super(context);
TextView textView = new TextView(context);
textView.setText(msg);
setContentView(textView);
}
}