4

I am trying to launch checkbox dialog from Service by the use of AlertDialog.Builder but I am getting the following error:

This error when I launch the dialog without builder.getWindow().setType():

05-28 10:48:42.816: E/AndroidRuntime(18510): FATAL EXCEPTION: main
05-28 10:48:42.816: E/AndroidRuntime(18510): Process: com.bustracker, PID: 18510
05-28 10:48:42.816: E/AndroidRuntime(18510): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
05-28 10:48:42.816: E/AndroidRuntime(18510):    at android.view.ViewRootImpl.setView(ViewRootImpl.java:691)
05-28 10:48:42.816: E/AndroidRuntime(18510):    at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:288)
05-28 10:48:42.816: E/AndroidRuntime(18510):    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
05-28 10:48:42.816: E/AndroidRuntime(18510):    at android.app.Dialog.show(Dialog.java:312)
05-28 10:48:42.816: E/AndroidRuntime(18510):    at android.app.AlertDialog$Builder.show(AlertDialog.java:991)
05-28 10:48:42.816: E/AndroidRuntime(18510):    at com.bustracker.TrackingService.stop_popup(TrackingService.java:370)
05-28 10:48:42.816: E/AndroidRuntime(18510):    at com.bustracker.TrackingService.onAsyncTaskFinished(TrackingService.java:305)

I tried to luanch it with builder.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

but I got this error:

The method getWindow() is undefined for the type

private void stop_popup(final ArrayList<Integer> routeList) {


    int routeListSize = routeList.size();

    if (routeListSize > 0) {

        String[] charSequence = new String[routeList.size()];
        for (int i = 0; i < routeList.size(); i++) {
            charSequence[i] = String.valueOf(routeList.get(i));
        }
        AlertDialog.Builder builder = new AlertDialog.Builder(this);

        builder.setTitle("Has this route arrived the stop? ");

        builder.setMultiChoiceItems(charSequence, null,
                new DialogInterface.OnMultiChoiceClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which,
                            boolean isChecked) {

                        if (isChecked) {

                            route_number = routeList.get(which);

                        }  
                    }
                });

        builder.setPositiveButton(android.R.string.ok,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {

                    }
                });
        builder.setNegativeButton(android.R.string.cancel,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {

                    }
                });

        builder.create();
        builder.show();
    }
}
Mr Asker
  • 2,300
  • 11
  • 31
  • 56

5 Answers5

16

If you want to popup a dialog in Android Service, you have two ways:

  1. Use an Activity as Dialog

  2. Use AlertDialog.Builder, but you'll need to config dialog as System Alert by using dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

Here is the sample code:

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Test dialog"));
builder.setIcon(R.drawable.icon);
builder.setMessage("Content");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int whichButton) {
        //Do something
        dialog.dismiss();
});
builder.setNegativeButton("Close", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int whichButton) {
        dialog.dismiss();
    }
});
AlertDialog alert = builder.create();
alert.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alert.show();

Also, remember to add permission in your AndroidManifest.xml

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
Tim
  • 10,459
  • 4
  • 36
  • 47
Kartheek
  • 7,104
  • 3
  • 30
  • 44
  • It works thanks but do you know why the dialog window color is so dark gray and not as ordinary light gray ? – Mr Asker May 28 '15 at 09:36
  • 1
    You can set the theme for the alert dialog AlertDialog.Builder builder = new AlertDialog.Builder(this,AlertDialog.THEME_HOLO_LIGHT); – Kartheek May 28 '15 at 09:42
1

Try this.

Create Activity as Dialog Theme and start that Activity from Service.

Just need to register you Activity in manifest.xml like as below

android:theme="@android:style/Theme.Dialog"

or

android:theme="@android:style/Theme.Translucent.NoTitleBar"

MyDialog.java

public class MyDialog extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        final AlertDialog alertDialog = new AlertDialog.Builder(this).create();
        alertDialog.setTitle("your title");
        alertDialog.setMessage("your message");
        alertDialog.setIcon(R.drawable.icon);

        alertDialog.show();
    }
}
Sohail
  • 303
  • 1
  • 10
0

Add the below code to the stop_popup() method

AlertDialog alertDialog = builder.create();
        alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
        alertDialog.show();

And add the permission in the manifest file

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
Chandrakanth
  • 3,711
  • 2
  • 18
  • 31
0

manifest

<service android:name=".HelloService" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

service class: HelloService.class

public class HelloService extends Service
{

@Override
public IBinder onBind(Intent arg0) {
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // Let it continue running until it is stopped.
    Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
    return START_STICKY;
}
@Override
public void onDestroy() {
    super.onDestroy();
    Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("Test dialog");
    builder.setMessage("Content");
    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            //Do something
            dialog.dismiss();
        }
    });
    builder.setNegativeButton("Close", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            dialog.dismiss();
        }
    });
    AlertDialog alert = builder.create();
    alert.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
    alert.show();
}
}

call from activity on destroy

public class MainActivity extends ActionBarActivity
{

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    startService(new Intent(getBaseContext(), HelloService.class));
}

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings)
    {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

@Override
protected void onDestroy()
{
    // TODO Auto-generated method stub
    super.onDestroy();
    stopService(new Intent(getBaseContext(), HelloService.class));
}
}
krunal shah
  • 364
  • 2
  • 14
0
val builder = AlertDialog.Builder(this)
builder.setTitle("")
builder.setMessage("")
builder.setPositiveButton("") { dialogInterface, i ->
}
builder.setNegativeButton("1 Year") { dialogInterface, i ->
}
val alert = builder.create()
alert.show()

Best!

Source

Braian Coronel
  • 22,105
  • 4
  • 57
  • 62