PopUp dialog Android from background thread - java

I need a popup dialog to be shown when i get a message from different thread but the dialog should be not dependent on Activity i.e, it should display the dialog wherever the screen focus is.
Can it be done? Because the dialog is handled per Activity, I thought of using a service but again it would be one more thread added and I want to avoid that.
Any other options available?

If you're trying to ask how to show a dialog when your activity is not the focused activity on the user's phone then try using Notifications instead. Popping up a dialog over a different application interrupts the user when they may be doing something else. From the Android UI guidelines:
Use the notification system — don't
use dialog boxes in place of
notifications
If your background service needs to
notify a user, use the standard
notification system — don't use a
dialog or toast to notify them. A
dialog or toast would immediately take
focus and interrupt the user, taking
focus away from what they were doing:
the user could be in the middle of
typing text the moment the dialog
appears and could accidentally act on
the dialog. Users are used to dealing
with notifications and can pull down
the notification shade at their
convenience to respond to your
message.
A guide to create notifications is here: http://developer.android.com/guide/topics/ui/notifiers/notifications.html

Alternative solution :
AlertDialog dialog;
//add this to your code
dialog = builder.create();
Window window = dialog.getWindow();
WindowManager.LayoutParams lp = window.getAttributes();
lp.token = mInputView.getWindowToken();
lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
window.setAttributes(lp);
window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
//end addons
alert.show();

if I understand you correctly you could use a base class for all of your activities
public abstract class BaseActivity extends Activity{
protected static BaseActivity current_context = null;
#override
protected void onPause(){
current_context = null;
super.onPause();
}
#override
protected void onResume(){
current_context = this;
super.onResume();
}
public static void showDialog(/*your parameters*/){
//show nothing, if no activity has focus
if(current_context == null)return;
current_context.runOnUiThread(new Runnable() {
#override
public void run(){
AlertDialog.Builder builder =
new AlertDialog.Builder(current_context);
//your dialog initialization
builder.show();
}
});
}
}
in your thread show your dialog with BaseActivity.showDialog(..) But this approach doesn't work if you want to show your dialog on top of any activity of the target device.

Related

How do I make the AlertDialog box appear outside the app?

#Override
public void run() {
//Create thread that can alter the UI
AlarmPage.this.runOnUiThread(new Runnable() {
public void run() {
cal = Calendar.getInstance();
//See if current time matches set alarm time
if((cal.get(Calendar.HOUR_OF_DAY) == alarmTime.getCurrentHour())
&& (cal.get(Calendar.MINUTE) == alarmTime.getCurrentMinute())){
//If the sound is playing, stop it and rewind
if(sound.isPlaying()){
ShowDialog();
alarmTimer.cancel();
alarmTask.cancel();
alarmTask = new PlaySoundTask();
alarmTimer = new Timer();
alarmTimer.schedule(alarmTask, sound.getDuration(), sound.getDuration());
}
sound.start();
}
}
});
}
public void ShowDialog() {
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setTitle("REMINDER!");
alertDialog.setMessage("Turn off alarm by pressing off");
alertDialog.setNegativeButton("Off", new DialogInterface.OnClickListener(){
#Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getApplicationContext(), "OFF", Toast.LENGTH_SHORT);
}
});
alertDialog.show();
}
I am making a simple alarm clock app that notifies the user. I want to make a alert box that gives the user the option to turn off the alarm when it goes off. I was able to make the alert box, but it only appears in the app not outside of the app. I understand the app has to be in the background running. If I need to show more code or be more specific, just ask please.
Add a line as:
public void ShowDialog() {
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setTitle("REMINDER!");
alertDialog.setMessage("Turn off alarm by pressing off");
alertDialog.setNegativeButton("Off", new DialogInterface.OnClickListener(){
#Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getApplicationContext(), "OFF", Toast.LENGTH_SHORT).show();
}
});
alertDialog.show();
// line you have to add
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_TOAST);
}
check now.
Do not accept answers if they don't address your question, it is misleading.
The accepted answer is not correct, as it will never work outside your application.
Reason:
It requires an activity context not application context.
If you provide application context, your app will crash with IllegalArgumentException- you need to use Theme.AppCompat or their decendents...
If you need functionality as actually stated in the question you have to have a separate activity themed as a Dialog like here
or you can add a custom view to your window using window manager and making it system level alert like here.
Do this create an Activity without ContentView or a View associated with it and call your alertDialog method in your onCreate also remember to set the background of the Activity to Transparent using ColourDrawable
And that activity will look like a dialog or will suit your preference, you can also fall back to Themes so you can set an Activity as Dialog and treat it like Dialog also use DialogFragment

Android Math quiz (Thread manipulation)

I need to make a math quiz. Here is workflow:
On button click(Start) i need to show a question e.g. 5+5, which stays on screen for 2 seconds after which a dialog i shown asking for result of previous operation. And i need to repeat that for e.g. 5 times. At the end I need to show to user number of correct answers.
I have Java experience but I'm new to Android. I have read various articles and examples regarding Android threading but haven't found solution to this workflow.
As far as I know I cannot block or pause main/UI thread, but the problem is that i should repeat questions for e.g. 5 times and after each one(after 2 sec.) I should pause activity to show Dialog and then go back to showing another question.
Thanks in advance!
EDIT:
Here is my code for now. The number is shown on screen and after 2 seconds alert dialog is shown asking to enter that number. But the problem is that the application doesn't wait for user input but continues to show new random number an opens new alert dialog every 2 seconds.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_questions);
tv = (TextView) findViewById(R.id.questionText);
handler = new Handler();
Runnable r = new Runnable() {
public void run() {
tv.setText(String.valueOf(rand.nextInt(50) + 1));
createDialog();
handler.postDelayed(this, 2000);
}
};
handler.postDelayed(r, 2000);
}
protected void createDialog() {
LayoutInflater li = LayoutInflater.from(context);
View promptsView = li.inflate(R.layout.activity_answer_dialog, null);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
// set prompts.xml to alertdialog builder
alertDialogBuilder.setView(promptsView);
final EditText userInput = (EditText) promptsView.findViewById(R.id.editTextDialogUserInput);
// set dialog message
alertDialogBuilder
.setCancelable(false)
.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
// get user input and set it to result
// edit text
result.setText(userInput.getText());
}
})
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
dialog.cancel();
}
});
// create alert dialog
AlertDialog alertDialog = alertDialogBuilder.create();
// show it
alertDialog.show();
}
PS. Also I tried to create separate Activity for dialog and added this line to Manifest:
android:theme="#android:style/Theme.Dialog"
but the same thing happens.
You use event driven programming and timers. To show the dialog after 2 seconds, the easiest way is to post a runnable to a handler using postDelayed, which will call your runnable in N milliseconds. Then display the dialog box.
You don't need to pause the activity to show the dialog box, just show it. Any code that you want to run after the dialog is finished with should be put in the handler for the dialog's ok button. In other words, your code is called in response to the event of a button being pressed.

How to use a button to show a custom dialog in android application?

I am following a youtube tutorial and I've got most of the works done, but I still got some problems.
I have my custom layout for my custom dialog, all I wanted to do is to set the custom dialog on a button. Once we click the button ,the dialog shows, that's it. I've already set the onclicklistener on the button, here's my code.
Credit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Dialog credit = new Dialog(Main.this);
credit.setContentView(R.layout.creditdialog);
credit.setTitle(" ");
credit.show();
}
});
I followed all of this on a tutorial, but I don't know that the "MAIN" is about, I got an error there. Please tell me what to do. Sorry for my poor English.
new Dialog(Main.this);
The above line creates a new dialog object and associates it with the context of your Activity. SO you have to pass the context of your activity in the paranthesis..
Eg:
If you are calling the dialog from Activity "ActivityMain".. then use:
new Dialog(ActivityMain.this);
try this
Credit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Dialog credit = new Dialog(getApplicationContext());
credit.setContentView(R.layout.creditdialog);
credit.setTitle(" ");
credit.show();
}
});
it is common question! but you can extend dialog box and can set custom layout for your dialog than on button click just call dialog like this:
new CustomDialog(activity).show();
also you can follow this tutorial on custom dialog to understand how to customise dialog and how to use it on button click.
http://www.shaikhhamadali.blogspot.com/2013/09/types-of-dialogbox-part-two-custom.html

Custom AlertDialog fails to initialize in onCreate()

I'm trying to build a custom AlertDialog by extending the AlertDialog class.
As usual, I'm setting up the dialog inside its onCreate() method. Or, I'm trying to do so:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setTitle("Some title");
this.setButton(BUTTON_POSITIVE, "Click me", (DialogInterface.OnClickListener)null);
final FrameLayout custom = (FrameLayout) this
.findViewById(android.R.id.custom);
custom.addView(this.getLayoutInflater().inflate(R.layout.mydlg, null),
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
}
Now, when it comes to displaying an instance of this dialog, nothing is shown. The current Activity fades out and loses focus but not a single pixel of my dialog is displayed. Pressing Back brings the Activity back to the foreground, indicating to me that a dialog actually is shown, but just a completely empty one.
However, when I create an AlertDialog and use, for instance, dlg.setButton(BUTTON_POSITIVE, "Click me", (DialogInterface.OnClickListener)null);
the dialog is shown with the respective button.
Even when I set up my custom dialog in its constructor using the very same code as above everything seems to work ok.
Now, how can this be? Why can't I seem to initialize my dialog in its onCreate() method? Isn't this the way you're supposed to initialize any GUI element? What am I missing?
EDIT
Please note, that something is 'shown', fading out the Activity and taking focus from it. It's just that it seems to be completely empty/invisible.
Here another attempt:
this.setTitle("Some title");
this.setButton(BUTTON_POSITIVE, "Click me", (DialogInterface.OnClickListener)null);
final View v = this.getLayoutInflater().inflate(R.layout.mydlg, null);
this.setView(v);
These exact lines do work when put into my dialog's constructor.
These exact lines do not work when put into my dialog's onCreate().
What is going on here?!
Generally, am I not supposed to do it in onCreate()? - Am I facing trouble if I resort to doing the above initialization in the constructor instead? (This does not seem too clean to me, anyway.)
You need to call the show() method in order to see something.
You should consider using AlertDialog.Builder instead of subclassing AlertDialog itself. It allows you to do all the things you need in your example (in order: setTitle(),setPositiveButton() and setView() ). Don't forget to call create() at the end to actually get your dialog.
Also, check if your onCreateDialog() and onPrepareDialog() activity methods are implemented correctly. If you don't have them implemented at all (an unmanaged dialog), consider doing that anyway, especially if your app allows for orientation changes. You probably know about this, but here is a tutorial:
http://developer.android.com/guide/topics/ui/dialogs.html
also, DialogFragments are a bit easier way to implement this, but you need a newer API version or the Compatibility package:
http://developer.android.com/reference/android/app/DialogFragment.
One final issue - where are you calling show() in your activity? onResume() should be OK, onCreate() not as much.
Sorry I'm late to the party :)
You have to thing differently for the alert dialog.
The way I did it is to customize the view before creating the alert dialog:
// This is the activity that is the background of the AlertDialog
public class Main extends Activity {
public static final int DIALOG_CONFIG = 1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.emptybackground);
}
#Override
protected void onStart() {
super.onStart();
// Open the alert dialog on openning the Activity
showDialog(Main.DIALOG_CONFIG );
}
protected Dialog onCreateDialog(int id) {
LayoutInflater factory = LayoutInflater.from(this);
switch (id) {
case DIALOG_CONFIG:
// Here, we load the existing view R.layout.config
configView = factory.inflate(R.layout.config, null);
configDialog = new AlertDialog.Builder(this)
.setTitle("Configuration")
.setView(configView)
.create();
// Using configView, you can do whatever you want with the view. Here, we add value to a spinner.
Spinner spinner = (Spinner)configView.findViewById(R.id.config_select_conn);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
adapter.add("TCP");
adapter.add("Bluetooth");
spinner.setAdapter(adapter);
return configPrinter;
}
return null;
}
}
you should call custom_alertDialog.create(); before custom_alertDialog.show();

showDialog() is accessing old View => Error: Activity has leaked window [...]

I am writing the app and I have the following scenario:
First i show an Acitivty and I show a ProgressDialog while loading data from a Server. I do the loading task in a Thread because I found this to be a solution so that the Dialog is shown correctly
showDialog(DIALOG_LOAD);
loadListThread = new Thread(new Runnable(){
#Override
public void run(){
service.execRequest();
loadingFinishedHandler.sendEmptyMessage(0);
MyActivity.this.dismissDialog(MyActivity.DIALOG_LOAD);
}
});
loadListThread.start();
After the Thread is finished I notify a Handler. Again this is a solution I found for the problem to access Views in the activity without being in the Thread anymore
loadingFinishedHandler = new Handler(){
#Override
public void handleMessage(Message msg){
showList();
}
};
After loading is finished, I check whether I received data correctly. If not, i want to show an error dialog:
showDialog(DIALOG_ERROR);
I call the dialogs with the onCreateDialog method
public Dialog onCreateDialog(int dialogId){
switch(dialogId){
case DIALOG_LOAD:
String message = getString(R.string.load);
ProgressDialog loadDialog = new ProgressDialog(this);
loadDialog.setMessage(message);
loadDialog.setCancelable(false);
return loadDialog;
case DIALOG_ERROR:
String message = getString(R.string.error);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(errorMessage);
builder.setNeutralButton(getString(R.string.ok), null);
return builder.create();
}
return null;
}
And here is the problem: If I change the Orientation of my phone while data is loading and an error dialog shall be created afterwards, I get this message
Activity [...] has leaked window [...] that was originally added here
I understand why this is happening. The View has been re-created, when i rotated my phone and showDialog() is obviously trying to access the old one. But I do not know how to fix it.
Does anyone has an idea?
Edit: solved it :-)
I found out that I can prevent my Activity from restarting on orientation change. I read about it in this article
Handling Runtime Changes
I declared in the AndroidManifest by adding
android:configChanges="orientation"
that i handle orientation changes by myself. These changes can now be handled with this method
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
}
But for my case it was not necessary to add any code!
public Dialog onCreateDialog(int dialogId){
if(isFinishing()){
return null;)}...

Categories