2010-09-28 29 views
14

我有問題顯示AlertDialog從服務。我可以使用Toast或使用WindowManager(TYPE_SYSTEM_ALERT或TYPE_SYSTEM_OVERLAY)顯示自定義佈局窗口。但是,我不想使用自定義佈局,我更願意直接使用漂亮的AlertDialog GUI。顯示AlertDialog作爲系統覆蓋窗口從服務

場景:

  • 正在運行的服務。目前沒有活動的活動。
  • 在某些外部事件,服務發送通知
  • 當用戶按壓的通知,服務經由的PendingIntent和AlertDialog通知應當被顯示(用AlertDialog.Builder(this)創建)

錯誤:

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

搜索對於這個答案,我感到我正在嘗試一些目前不可能的事情(Android 2.2)。或者,也許是。

+0

[從Android的服務警報對話框(可能的重複http://stackoverflow.com/questions/3599563/alert-dialog-from-android-service) – araks 2015-11-06 17:36:26

回答

25

已找到符合上述場景的解決方案。

  • 新活動已創建並從服務啓動。但是,這是帶有半透明背景的活動。此類活動在onCreate()中沒有行super.setContentView()。更重要的是,確保透明度

    @android:風格/ Theme.Translucent

下的主題標籤進入了在AndroidManifest.xml GUI這一活動。所以,新的行添加到清單XML是

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

  • onCreate()實際AlertDialog的顯示發生

  • 按AlertDialog按鈕使對話框和活動關閉和意圖的發送(或使用其他方式)將結果交付給服務。

  • 確保您爲對話框定義了setOnDismissListener()(實現應調用finish()on activity)。如果你不這樣做,請按Back鍵取消對話框,但將你留在當前活動中,這是透明的,看起來像用戶真的是錯的。

+0

Zelimir,非常感謝。我有同樣的問題,我正在尋找這個。 – Amitku 2011-04-27 06:40:18

+0

我很高興它有幫助。最好的祝福。 – Zelimir 2011-04-27 12:12:32

+0

如果我錯了,請糾正我。是不是半透明的問題是它只是背後的一面鏡子?例如如果它在來電屏幕上。你不能真的接電話嗎?因爲你的活動阻止了它(雖然半透明?) – Guy 2012-01-02 08:11:26

6

謝謝您的解決方案。 我面臨同樣的問題,並在您的幫助下解決問題。

我把這個答案只是爲了分享我的方式將結果傳遞迴服務。

我沒有創建任何額外的自定義意圖類,只用Intent.putExtra()方法和一些技巧解決了結果傳遞問題。

在該服務中,使用此代碼啓動DialogActivity,其中顯示onCreate()中的警報對話框。

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

而在DialogActivity,完成它是這樣的:

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.startService(tgtIntent); 
    this.finish(); 
} 

最後,在服務,覆蓋onStartCommand()方法,並從意圖的結果。

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    int ret = super.onStartCommand(intent, flags, startId); 
    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 start logic here... 
     } 
    } 
    return ret; 
} 

我不知道這種方式是否是一個很好的解決方案,至少它爲我工作。希望這會對像我這樣的其他人有所幫助。

的完整源可以在這裏找到:

+2

使用startService()返回結果比使用廣播更好。我經常使用這種方法。 – Zelimir 2012-11-11 15:04:24

+0

嗨 CAn你要告訴我什麼是CLASS_KEY常量在這裏 – ekjyot 2013-01-14 04:34:41

+0

CLASS_KEY只是一個字符串,作爲您輸入意圖的值的名稱。 – Programus 2013-01-15 05:40:31