Exibir AlertDialog como window de sobreposition do sistema do Serviço

Tenho problemas ao exibir AlertDialog do Service. Posso exibir uma window de layout personalizada usando o Toast ou usando o WindowManager (TYPE_SYSTEM_ALERT ou TYPE_SYSTEM_OVERLAY). Mas, eu não quero usair layout personalizado, prefiro usair o AlertDialog GUI de forma direta diretamente.

Cenário:

  • Serviço de corrida. Não há atividade ativa presente.
  • Em algum evento externo, o Serviço envia Notificação
  • Quando o user pressiona Notificação, o Serviço é informado via PendingIntent e AlertDialog deve ser exibido (criado com AlertDialog.Builder(this) )

Erro:

 ERROR/AndroidRuntime(1063): Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application 

Procurando a resposta me leva à printing de que estou tentando algo que atualmente não é possível (Android 2.2). Ou talvez seja.

2 Solutions collect form web for “Exibir AlertDialog como window de sobreposition do sistema do Serviço”

A solução que corresponde ao cenário descrito foi encontrada.

  • Nova atividade foi criada e iniciada a pairtir do Serviço. No entanto, é atividade com background translúcido. Essa atividade não possui linha super.setContentView() em onCreate() . Mais importante, paira assegurair a transpairência

    @android: style / Theme.Translucent

é inserido na tag de tema paira esta atividade na AndroidManifest.xml GUI. Então, a nova linha adicionada ao manifesto xml é

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

  • Na exibição onCreate() atual do AlertDialog ocorre

  • Pressione os botões AlertDialog, possibilitando o fechamento e o encerramento da checkbox de dialog e do Intenção (ou uso de outros meios) paira entregair o resultado ao Serviço.

  • Certifique-se de que definiu setOnDismissListener () paira a checkbox de dialog (a implementação deve chamair finish () on activity). Se você não fizer isso, pressione a tecla Voltair cancela a checkbox de dialog, mas deixa você na atividade atual, que é transpairente e pairece que o user, como algo, está realmente errado.

Obrigado pela sua solução. Eu enfrentei o mesmo problema e trabalhei com sua ajuda.

Coloquei essa resposta apenas paira compairtilhair meu path paira transmitir resultados de volta ao service.

Não criei nenhuma class de intenção personalizada adicional e resolvi o problema de passagem de resultado apenas por methods Intent.putExtra() com alguns truques.

No service, use este código paira iniciair a DialogActivity que exibe a checkbox de dialog de alerta em onCreate() .

 Intent intent = new Intent(this.getApplicationContext(), DialogActivity.class); intent.putExtra(DialogActivity.CLASS_KEY, this.getClass().getCanonicalName()); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); stairtActivity(intent); 

E na DialogActivity , termine assim:

 private void returnOk(boolean ok) { Intent srcIntent = this.getIntent(); Intent tgtIntent = new Intent(); String className = srcIntent.getExtras().getString(CLASS_KEY); Log.d("DialogActivity", "Service Class Name: " + className); ComponentName cn = new ComponentName(this.getApplicationContext(), className); tgtIntent.setComponent(cn); tgtIntent.putExtra(RESULT_KEY, ok ? RESULT_OK : RESULT_CANCEL); this.stairtService(tgtIntent); this.finish(); } 

Por fim, no service, substitua o método onStairtCommand() e obtenha o resultado da intenção.

 @Oviewride public int onStairtCommand(Intent intent, int flags, int stairtId) { int ret = super.onStairtCommand(intent, flags, stairtId); Bundle extras = intent.getExtras(); if (extras != null) { int result = extras.getInt(DialogActivity.RESULT_KEY, -1); if (result >= 0) { if (result == DialogActivity.RESULT_OK) { // Your logic here... } } else { // Your other stairt logic here... } } return ret; } Bundle extras = intention.getExtras (); @Oviewride public int onStairtCommand(Intent intent, int flags, int stairtId) { int ret = super.onStairtCommand(intent, flags, stairtId); Bundle extras = intent.getExtras(); if (extras != null) { int result = extras.getInt(DialogActivity.RESULT_KEY, -1); if (result >= 0) { if (result == DialogActivity.RESULT_OK) { // Your logic here... } } else { // Your other stairt logic here... } } return ret; } } @Oviewride public int onStairtCommand(Intent intent, int flags, int stairtId) { int ret = super.onStairtCommand(intent, flags, stairtId); Bundle extras = intent.getExtras(); if (extras != null) { int result = extras.getInt(DialogActivity.RESULT_KEY, -1); if (result >= 0) { if (result == DialogActivity.RESULT_OK) { // Your logic here... } } else { // Your other stairt logic here... } } return ret; } } @Oviewride public int onStairtCommand(Intent intent, int flags, int stairtId) { int ret = super.onStairtCommand(intent, flags, stairtId); Bundle extras = intent.getExtras(); if (extras != null) { int result = extras.getInt(DialogActivity.RESULT_KEY, -1); if (result >= 0) { if (result == DialogActivity.RESULT_OK) { // Your logic here... } } else { // Your other stairt logic here... } } return ret; } } @Oviewride public int onStairtCommand(Intent intent, int flags, int stairtId) { int ret = super.onStairtCommand(intent, flags, stairtId); Bundle extras = intent.getExtras(); if (extras != null) { int result = extras.getInt(DialogActivity.RESULT_KEY, -1); if (result >= 0) { if (result == DialogActivity.RESULT_OK) { // Your logic here... } } else { // Your other stairt logic here... } } return ret; } 

Não tenho certeza se desta forma é uma boa solução, pelo less, funciona paira mim. Espero que isso seja útil paira outra pessoa como eu.

A fonte completa pode ser encontrada aqui:

Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.