前往
大廳
主題

在Android 12中,收起通知中心的方法失效了

奇幻 | 2022-04-29 13:49:47 | 巴幣 0 | 人氣 375

今天發現我一直以來使用收起「Android 下拉式通知中心(status bar)」的方法,在Android 12中被屏蔽了,
try {
Object statusBarManager = getSystemService("statusbar");
Method collapse;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
collapse = statusBarManager.getClass().getMethod("collapse");
} else {
collapse = statusBarManager.getClass().getMethod("collapsePanels");
}
collapse.invoke(statusBarManager);
} catch (Exception localException) {
localException.printStackTrace();
}
上面的程式碼中,使用反射的方式呼叫StatusBarManager.collapsePanels()方法,collapsePanels方法雖然一直以來都不是公開的API,但是可以通過反射呼叫,而現在在Android 12中用反射的方法就會拋出錯誤java.lang.NoSuchMethodException: collapsePanels []。

在網路上有些文章中說也可以用
context.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));

目前我想到的解決辦法就是開啟一個Activity,因為當一個Activity被開啟時,通知中心就會自動縮回去,但是如果只是想讓使用者在按下通知裡的按鈕後在Service裡做點事的話,那麼突然跳出一個Activity又馬上被關閉感覺起來很影響使用體驗。

不過只要在AndroidManifest.xml中,在要開啟的Activity加入主題,例如
android:theme="@style/Theme.AppCompat.Transparent"
然後再加上
android:excludeFromRecents="true" (加上後,可以讓開啟這個Activity接著關閉後,就不會在系統的「應用程式總覽」畫面留下紀錄),
接著在styles.xml中,加上像是
<style name="Theme.AppCompat.Transparent" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
上面的xml中
  • 繼承了沒有Action Bar的主題NoActionBar
  • 將開啟的Activity的背景(windowBackground)設為透明
  • 因為Android開啟的Activity其實也是開啟一個window,因此將視窗設為透明(windowIsTranslucent設為真)
  • 將Activity設定成沒有標題(windowNoTitle設為真)
  • 讓開啟的Activity以懸浮的方式顯示,像是AlertDialog一樣(windowIsFloating設為真)
  • 不顯示app啟動畫面(windowContentOverlay設為null)
  • 因為將Activity以懸浮方式顯示,而只要以懸浮方式顯示的視窗,視窗以外的地方,預設都會覆蓋有黑色半透明的背景(像是AlertDialog),因此去除掉黑色半透明的背景(backgroundDimEnabled設為假)
然後在Activity的onCreate方法中,將setContentView去除,這樣子使用者就不會感覺到有Activity開啟了。

最後,在Activity的onCreate中,用context.startService回到Service後馬上將Activity給finish()就完成了。

創作回應

更多創作