I've got a class inside my MainActivity class from which I'm trying to display an AlertDialog. The Dialog isn't showing and there are no errors. The code for the dialog is:
AlertDialog.builder builder = new AlertDialog.builder(MainActivity.this);
builder.setMessage("Unkown Game Code. please try again.").setTitle("Game Code Error").setNeutralButton("Okay", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
}
builder.create().show();
As the code is triggered when you receive a message via WebSocket, it might probably be async.
Try and run your code in your Activitys main Thread:
YourActivity.this.runOnUiThread(new Runnable() {
public void run() {
//Your Code
}
});
Related
I am trying to include an AlertDialog builder within a method that prompts for a pin code and when the positive button is pressed, checks it against a database value and returns a true or false value to the method caller.
For example: Adding/editing/deleting a user task requires a pin code. I don't want to generate a different AlertDialog for all three (and more) of these actions. I want to wrap the following code within a TaskService class that I can call from any activity, and react based on the result from within that activity.
So TaskService.java would have:
public boolean isCorrectPin(View v){
AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
final EditText editText = new EditText(context);
builder.setView(editText);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (editText.getText().toString()) == getPinCode(){
//return true
}
}
});
builder.show();
}
and OpenTaskAdapter.java would have:
public void onBindViewHolder(ViewHolder holder, int position){
holder.btnMarkAsComplete.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
if (service.isCorrectPin(v) {
//complete task
}
}
});
holder.btnDelete.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
if (service.isCorrectPin(v) {
//delete task
}
}
});
It's important to note that these two button listeners could be in totally different activities.
You can create your own method to generate dialog with listener:
public void isCorrectPin(Context context, String title, String message, String btnPositive, final DialogSingleButtonListener dialogSingleButtonListener) {
final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
dialogBuilder.setTitle(title);
dialogBuilder.setMessage(message);
dialogBuilder.setPositiveButton(btnPositive, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (editText.getText().toString() == getPinCode()){
dialogSingleButtonListener.onButtonClicked(dialog);
}
}
});
AlertDialog dialog = dialogBuilder.create();
dialog.show();
}
And the listener class:
public interface DialogSingleButtonListener {
public abstract void onButtonClicked(DialogInterface dialog);
}
And use it like:
service.isCorrectPin(context, title, message, btnPositive
new DialogSingleButtonListener() {
#Override
public void onButtonClicked(DialogInterface dialog) {
//code here is only called if they entered a correct pin.
}
}
);
A dialog can't "return" a value in the way that it looks like you're expecting. A dialog can make changes to some other object, but you can't have a bit of code block on it and wait for the user to finish interacting with it.
Instead, you'll need to set up listeners for when the prompt dialog is dismissed or buttons or clicked, or whatever other event signals that you have what you need from it. Those listeners can then read the data gathered and set by the dialog.
this is how i'm doing :
public Boolean showAlert(String message)
{
action = false;
AlertDialog.Builder alertDialog = new AlertDialog.Builder(HAActivity.this);
// Setting Dialog Title
alertDialog.setTitle(getString(R.string.app_name));
// Setting Dialog Message
alertDialog.setMessage(message);
// Setting Icon to Dialog
// Setting Positive "Yes" Button
alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
// Write your code here to invoke YES event
action = true;
}
});
// Setting Negative "NO" Button
alertDialog.setNegativeButton("Cancle", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Write your code here to invoke NO event
action = false;
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
return action;
}
and calling function like this :
//activity in which you create function
if (Activity.showAlert("Do you really want to delete ??"))
{
//delete it anyway.
}
I knew this question has been asked but I couldn't solve it. I want to show simple AlertDialog on Android's Service. I can show it nicely on MainActivity but I had a problem on Service , Here is my code:
CustomMainActivity.java:
public void popupDialogMain()
{
final Context context = getApplicationContext();
Handler h1 = new Handler(context.getMainLooper());
h1.post(new Runnable() {
#Override
public void run() {
if (mBXmpp)
mBXmppService.popupDialogMain2();
}
});
}
XmppService.java:
public static void popupDialogMain2()
{
AlertDialog.Builder builder = new AlertDialog.Builder(CustomMainActivity.this)
.setMessage("Look at this dialog!")
.setCancelable(true)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//do things
}
});
AlertDialog alert = builder.create();
builder.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alert.show();
}
I get an error on this line:
AlertDialog.Builder builder = new AlertDialog.Builder(CustomMainActivity.this)
Android Manifest:
I added this permission:
android.permission.SYSTEM_ALERT_WINDOW
And I get this error:
not an enclosing class: CustomMainActivity
Any suggestion to solve it?
You cannot access a this from a static method.
When I create AlertDialog in backgroud background thread AsyncTask, I get error. if I create AlertDialog outside of AsyncTask its working great. How I can fix that?
final ProgressDialog mDialog = new ProgressDialog(PageAndExercise.this);
mDialog.setMessage(getString(R.string.loading));
mDialog.setCancelable(false);
mDialog.show();
alertDialog2 = new AlertDialog.Builder(this);
AsyncTask.execute(new Runnable() {
#Override
public void run() {
mDialog.dismiss();
alertDialog2.setTitle(getString(R.string.tnxupload));
// Setting Dialog Message
alertDialog2.setMessage(getString(R.string.tnxupload2));
alertDialog2
.setCancelable(false)
.setPositiveButton("", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
})
.setNegativeButton(getString(R.string.tnxupload3), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// if this button is clicked, just close
// the dialog box and do nothing
dialog.cancel();
}
});
AlertDialog alertDialog = alertDialog2.create();
// show it
alertDialog2.show();
}
});
The error:
28928-31794/com.example.exampleE/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #5
Process: com.example.example, PID: 28928
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
You should look more into what AsyncTask does and why.
It is a convenience class to allow work to be done in the background. The doInBackground method allows long-running work to not block the UI thread.
However, if you want to display or perform tasks on the UI thread, you need to make sure those happen on the UI thread. For example, your line:
mDialog.dismiss();
should execute in onPreExecute because it impacts the UI. Likewise:
alertDialog2.show()
is trying to change the UI. This should be run in onPostExecute.
Fundamentally, though, building an AlertDialog is not a long running task at all. None of that needs to be in AsyncTask unless you have intentions to expand what happens prior to displaying the next dialog.
See this post here: http://blog.nikitaog.me/2014/10/11/android-looper-handler-handlerthread-i/
You can't interact with UI non from main-Thread.
The short solution here is:
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
// Call UI related methods.
}
});
I guess AsyncTask implement to your code is something like this:
final ProgressDialog mDialog = new ProgressDialog(this);
mDialog.setMessage("loading");
mDialog.setCancelable(false);
mDialog.show();
final AlertDialog.Builder alertDialog2 = new AlertDialog.Builder(this);
new AsyncTask<Void, Void, Void>() {
#Override
protected void onPreExecute() {
super.onPreExecute();
mDialog.dismiss();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
AlertDialog alertDialog = alertDialog2.create();
alertDialog2.setTitle("tnxupload");
alertDialog2.setMessage("tnxupload");
alertDialog2.setCancelable(false).setPositiveButton("", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
}).setNegativeButton("tnxupload3", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// if this button is clicked, just close
// the dialog box and do nothing
dialog.cancel();
}
});
alertDialog2.show();
}
#Override
protected Void doInBackground(Void... params) {
return null;
}
}.execute();
I've got a really strange problem where on some KitKat devices, my simple yes/no AlertDialog will appear behind the current fragment and not in the foreground. The reason I say the dialog appears behind the current fragment is because the dialog appears in the foreground only after I rotate the device. The app has a MainActivity that switches between different fragments that take up most of the screen.
MainActivity.java
#Override
public void onBackPressed() {
Builder builder = new AlertDialog.Builder(this);
builder.setMessage(getString(R.string.exit_confirm_summary))
.setTitle(getString(R.string.exit_confirm_title))
.setCancelable(true)
.setPositiveButton(getString(R.string.ok),
new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//...
}
})
.setNegativeButton(getString(R.string.cancel),
new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//...
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
After doing some research I found that it is best to use DialogFragment when using Fragments in your app, so I changed my code to this:
MainActivity.java
#Override
public void onBackPressed() {
AlertDialogFragment adf = new AlertDialogFragment();
adf.setRetainInstance(true);
adf.show(getFragmentManager(), "dialog");
}
AlertDialogFragment.java
public class AlertDialogFragment extends DialogFragment {
public AlertDialogFragment() {}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setCancelable(false)
.setTitle("Alert DialogFragment")
.setMessage("AlertDialogFragment Test")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// ...
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// ...
}
}).create();
}
}
However, the effect is still the same. The dialog should appear when I press the back button, but is only visible after I press the back button and then rotate the device. It also becomes visible after I go home and come back into the app. I've noticed it only happens on a few devices but I'd like to get rid of this problem for good.
Note: this behavior happens for all dialogs in the app, not just this one.
Anyone have any ideas what is going on?
To insert input values into mysql database I write insert() method
after insert method inserted data successfully I want to show Dialog popup with message "Success"
but I'm unable to execute the dialog.show() code :(
may be because of I pass MainActivity.this
Code in MainActivity
public class MainActivity extends Activity {
//call insert method to insert data into mysql
new Thread(new Runnable() {
public void run() {
insert(name.getText().toString());
}
}).start();
}
public void insert(final String name){
//insert logic code
//returns true if success
if(true)
{
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(MainActivity.this);
alertDialogBuilder.setMessage("Record submited successfully!");
alertDialogBuilder.setTitle("Success!");
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setNeutralButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton){
dialog.cancel();
}
})
.show();
}
}//END class MainActivity
here is my problem :(
Call show() on the main application thread, such as from onPostExecute() of an AsyncTask.