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

冷暖自知 提交于 2019-12-17 16:47:07

问题


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();
            }


回答1:


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();



回答2:


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.




回答3:


Instead of creating a new transparent activity, Use the SYSTEM_ALERT_WINDOW permission to do this

public void onReceive(Context ctx, Intent intent) {
    LayoutInflater inflater = (LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View popup = inflater.inflate(R.layout.mypopup, null, false);
    CustomDialog dialog = new CustomDialog(ctx, popup );

    dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

    dialog.getWindow().getAttributes().windowAnimations = R.style.PauseDialogAnimation;
    dialog.show();
}



回答4:


Try this.

AlertDialog.Builder alertDialog  = new AlertDialog.Builder(myContext);

Edit.

Sorry about no comment. Put Context which started your service like a instance in service and use it.

class SomeService 
{   
     private final Context myContext;
     public WebService(Context myContext) 
     {

        this.myContext= myContext;
     }

   public void showDialog()
   {
        AlertDialog d = new AlertDialog.Builder(myContext);
   }
}



回答5:


You can do UI stuff like showing an AlertDialog only in the UI thread. And since your service is not running on the UI thread you are getting this exception.

Try using runOnUiThread to show the Alert:-

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

            runOnUiThread(new Runnable(){

            public void run(){
                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();
            }

            });
}


来源:https://stackoverflow.com/questions/19677670/get-exception-when-showing-alert-dialog-from-service-unable-to-add-window-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!