Get an exception when displaying a notification dialog box from a service. Unable to add a null window token not for the application.

Get an exception when displaying a notification dialog box from a service.

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

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

I am also attaching a snapshot of my journal 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

+6
source share
5 answers

I have this problem, but now it is solved , if you really want to run alertDialog from the service, you should set the dialog as System Alert and do not forget to add permission to your AndroidManifest.xml:

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

/ Here is a 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(); 
+21
source

You have to keep some things in your mind when creating your gui:

  • All time-consuming work without gui should be done in the background (using asyncTask, services, threads, etc.).

  • GUIs (such as views and other graphical objects) should always be created and updated from UIthreads.

Thus, the create and display dialog is the work of the user interface, so it should be in the user interface thread. You can use various methods to run any code in the user interface thread, for example:

  • You can use runOnUiThread to run a piece of code in a user interface thread.
  • You can use messageHandler.
  • You can use the broadcast sender and receiver.

I think runOnUiThread is best used for your case

 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 a broadcast, you can use:

Step 1. Create a broadcast receiver in your activity from the place where you start 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. Transfer the broadcast from the service to display a dialog box.

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

Hope this helps you.

+4
source

Instead of creating a new transparent activity, use the SYSTEM_ALERT_WINDOW permission for 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(); } 
+2
source

Try it.

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

Change

Sorry, no comments. Put the context that started your service as an instance in the service and used it.

 class SomeService { private final Context myContext; public WebService(Context myContext) { this.myContext= myContext; } public void showDialog() { AlertDialog d = new AlertDialog.Builder(myContext); } } 
+1
source

You can make UI elements, for example, show AlertDialog only in the user interface thread. And since your service does not work in the user interface thread, you get this exception.

Try using runOnUiThread to display a warning: -

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

Source: https://habr.com/ru/post/957013/


All Articles