Service内でDialogを利用しようとしても、show()を呼んだ段階で例外が発生してしまいます.
ここではその回避方法について紹介します.
発生する例外
1 2 3 4 5 6 |
<span class="pln">android</span><span class="pun">.</span><span class="pln">view</span><span class="pun">.</span><span class="typ">WindowManager$BadTokenException</span><span class="pun">:</span> <span class="typ">Unable</span><span class="pln"> to add window </span><span class="pun">--</span><span class="pln"> token </span><span class="kwd">null</span> <span class="kwd">is</span> <span class="kwd">not</span> <span class="kwd">for</span><span class="pln"> an application at android</span><span class="pun">.</span><span class="pln">view</span><span class="pun">.</span><span class="typ">ViewRoot</span><span class="pun">.</span><span class="pln">setView</span><span class="pun">(</span><span class="typ">ViewRoot</span><span class="pun">.</span><span class="pln">java</span><span class="pun">:</span><span class="lit">509</span><span class="pun">)</span><span class="pln"> at android</span><span class="pun">.</span><span class="pln">view</span><span class="pun">.</span><span class="typ">WindowManagerImpl</span><span class="pun">.</span><span class="pln">addView</span><span class="pun">(</span><span class="typ">WindowManagerImpl</span><span class="pun">.</span><span class="pln">java</span><span class="pun">:</span><span class="lit">177</span><span class="pun">)</span><span class="pln"> at android</span><span class="pun">.</span><span class="pln">view</span><span class="pun">.</span><span class="typ">WindowManagerImpl</span><span class="pun">.</span><span class="pln">addView</span><span class="pun">(</span><span class="typ">WindowManagerImpl</span><span class="pun">.</span><span class="pln">java</span><span class="pun">:</span><span class="lit">91</span><span class="pun">)</span><span class="pln"> at android</span><span class="pun">.</span><span class="pln">app</span><span class="pun">.</span><span class="typ">Dialog</span><span class="pun">.</span><span class="pln">show</span><span class="pun">(</span><span class="typ">Dialog</span><span class="pun">.</span><span class="pln">java</span><span class="pun">:</span><span class="lit">241</span><span class="pun">)</span> |
回避方法
Dialog#showを呼ぶまえに、システムレベルのアラートだと設定する.
1 2 3 4 5 6 |
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);// AppicationContextを渡す(Serviceのインスタンス) Dialog alertDialog = alertBuilder.setCancelable(false) .setMessage(R.string.confirm_close) .create(); alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);//ここがポイント alertDialog.show(); |
システムレベルのアラートをあげるためには、Permissionの設定が必要.
1 |
<span class="tag"><uses-permission</span> <span class="atn">android:name</span><span class="pun">=</span><span class="atv">"android.permission.SYSTEM_ALERT_WINDOW"</span><span class="tag">/></span> |
注意点
Serviceは画面を持たない、裏で動く処理です.
そこからダイアログという画面を起動するのはあまりいいデザインではありません.
この議論についてはリンク先を参照ください.
かわりにNotificationが利用できないか検討してください.
1 2 3 4 5 6 |
<span class="typ">NotificationManager</span><span class="pln"> notificationManager </span><span class="pun">=</span> <span class="pun">(</span><span class="typ">NotificationManager</span><span class="pun">)</span><span class="pln"> getSystemService</span><span class="pun">(</span><span class="pln">NOTIFICATION_SERVICE</span><span class="pun">);</span> <span class="typ">Notification</span><span class="pln"> notification </span><span class="pun">=</span> <span class="kwd">new</span> <span class="typ">Notification</span><span class="pun">(</span><span class="com">/* your notification */</span><span class="pun">);</span> <span class="typ">PendingIntent</span><span class="pln"> pendingIntent </span><span class="pun">=</span> <span class="com">/* your intent */</span><span class="pun">;</span><span class="pln"> notification</span><span class="pun">.</span><span class="pln">setLatestEventInfo</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">,</span> <span class="com">/* your content */</span><span class="pun">,</span><span class="pln"> pendingIntent</span><span class="pun">);</span><span class="pln"> notificationManager</span><span class="pun">.</span><span class="pln">notify</span><span class="pun">(</span><span class="com">/* id */</span><span class="pun">,</span><span class="pln"> notification</span><span class="pun">);</span> |