Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Exception when showing Alert Dialog from Service - Unable to add window -- token null is not for an application

Get Exception when showing Alert Dialog from Service.

Following is the code in my Service class: I am trying to show an AlertDialog.

But I get the error: Unable to add window -- token null is not for an application

I am also attaching snapshot of my Log to this Question.

 if(!mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)&& !mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){

                Log.d("TrackingService","H: Exception after this");

                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setMessage("Your GPS seems to be disabled, do you want to enable it?")
                .setCancelable(false)
                .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                    public void onClick(final DialogInterface dialog, final int id) {
                        startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
                    }
                })
                .setNegativeButton("No", new DialogInterface.OnClickListener() {
                    public void onClick(final DialogInterface dialog,  final int id) {
                        dialog.cancel();
                    }
                });
                AlertDialog alert = builder.create();
                alert.show();
            }

enter image description here

like image 228
Dawood Awan Avatar asked Oct 30 '13 08:10

Dawood Awan


2 Answers

I have this problem but now is solved , if you want really run an alertDialog from a service , you should config dialog as System Alert and remember to add permission in your AndroidManifest.xml:

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

/Here is the sample code:

AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
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();
like image 147
Zied R. Avatar answered Sep 26 '22 00:09

Zied R.


You should keep some of the things in your mind while creating your gui:

  1. All time consuming non gui work should be done in background (using asyncTask, Services, Threads etc).

  2. GUI(like views and other graphical objects) should always be created and updated from UIthreads.

So create and displaying dialog is a UI work so it should be in UI thread. To run any code in UI thread you can use different methods like:

  1. You can use runOnUiThread to run a piece of code in UI thread.
  2. You can use messageHandler.
  3. You can use Broadcast sender and receiver.

I think for your case runOnUiThread is best So use

runOnUiThread (new Runnable() {
                public void run ()
                {
                    // WRITE YOUR PIECE OF CODE HERE TO UPDATE OR CREATE GUI.
                }
            });

To understand the concept this can help you:

http://developer.android.com/guide/components/processes-and-threads.html

To create broadcast you can use:

Step 1: Create a broadcast receiver in your activity from where you are starting your service.

   BroadcastReceiver receiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals("create_dialog")) {
                // create your dialog here.
            }
        }
    };

Step 2: Register your receiver after creating your broadcast receiver.

IntentFilter filter = new IntentFilter("create_dialog");
registerReceiver(receiver, filter);

Step 3: Send broadcast from your service to display dialog.

Intent intent = new Intent("create_dialog");
intent.putExtra("dialog_data", data_object to display in dialog);
SendBroadcast(intent);

I hope this can help you.

like image 29
Bharat Sharma Avatar answered Sep 23 '22 00:09

Bharat Sharma