androidのサービスからダイアログを表示する

androidのサービスからはダイアログを表示できない

ダイアログを生成する時に必要なContextはActivityでなければならないらしい。
サービスで下記のようにして自身のthisで生成したダイアログを表示しようとすると、例外が発生する。

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Test")
       .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
           public void onClick(DialogInterface dialog, int id) {
                dialog.cancel();
           }
        });
AlertDialog alert = builder.create();
alert.show();

例外メッセージ

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

一工夫

背景が透明なActivityを呼び出してそのActivityでダイアログを表示すれば、なんとかなりそう。ダイアログを閉じるときActivityも終了させないと操作が出来なくなるので注意が必要。

サービス側

Intent intent = new Intent(getApplicationContext(),TransparentActivity.class);
intent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
startActivity(intent);  

背景が透明なActivity

public class TransparentActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("Test")
           .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
              public void onClick(DialogInterface dialog, int id) {
                dialog.cancel();                
                TransparentActivity.this.finish();
              }
            });
    AlertDialog alert = builder.create();
    alert.show();
}

AndroidManifest.xml

<activity
  android:name="TransparentActivity"
  android:theme="@android:style/Theme.Translucent.NoTitleBar"
>
  <intent-filter>
      <action android:name="android.intent.action.MAIN" />
  </intent-filter>
</activity>