2017-05-05 65 views
11

如何檢查是否有任何系統dialog(如下面的那個或USSD)在Android中顯示?如何確定是否顯示任何系統對話框?

airplane mode switching dialog

編程方式或CMD根呢? 任何變體。

+2

「系統對話框」只是一個活動,就像任何其他活動一樣。沒有任何魔法使一個活動成爲「系統對話框」,另一個不是「系統對話框」。所以,你首先需要爲自己決定「系統對話」和其他一些以對話爲主題的活動之間的區別特徵。 – CommonsWare

+0

我的意思是類似於關於「飛機模式開啓或關閉」或ussd消息或類似東西的消息... – Andreyua

回答

2

系統對話框是一個活動。您可以使用ActivityManager通過頂級活動類名稱來檢測它。

final ActivityManager manager = (ActivityManager) context 
    .getSystemService(Activity.ACTIVITY_SERVICE); 

與API級別小於23(M)設備:

final List<ActivityManager.RunningTaskInfo> runningTasks = manager.getRunningTasks(1); 
final ComponentName componentName = runningTasks.get(0).topActivity; 
final String className = componentName.getClassName(); 

if (className.equals("YOUR_EXPECTED_ACTIVITY_CLASS_NAME")) { 
    // do something 
} 

在較新的設備:

final List<ActivityManager.AppTask> appTasks = manager.getAppTasks(); 
final ComponentName componentName = appTasks.get(0).getTaskInfo().topActivity; 
final String className = componentName.getClassName(); 

if (className.equals("YOUR_EXPECTED_ACTIVITY_CLASS_NAME")) { 
    // do something 
} 

或在這種情況下,您可以檢查設備是否在在開始活動之前的飛行模式:

private boolean isAirplaneModeOn(final Context context) { 
    final int airplaneMode = Settings.System.getInt(
     context.getContentResolver(), 
     Settings.System.AIRPLANE_MODE_ON, 
     0 
    ); 

    return airplaneMode != 0; 
} 

... 

if (!isAirplaneModeOn(this)) { 
    // do something 
} 
+0

謝謝你的努力。但不幸的是,你的選擇不適合我。在我的情況下,className總是等於我的主要活動類名稱。我之前檢查過你的方法,他們甚至都沒有爲我工作。這就是我問這個問題的原因。 另外,您的isAirplaneModeOn方法不是我所需要的。我只需要跟蹤AirplaneMode對話框的外觀。 我會投你的答案,但我不能接受它。抱歉。 – Andreyua

+0

我的測試代碼: https://gist.github.com/goodandrewsoft/b961c2b6cfc6666bcbbb2a617f6f8d9e – Andreyua

+0

對不起,我誤解了。 –

3

理論上你可以使用AccessibilityService來做到這一點,但它很複雜,可能會或可能不會在不同的設備上工作。用戶需要爲應用程序手動啓用輔助功能。您可以在任何窗口打開時從Android獲取回調,然後可以詢問窗口以確定它是否包含特定文本或屬於特定包等。這是一種「暴力」方法,但它可能很有用在某些情況下。

+0

類似的東西http://stackoverflow.com/a/32251469/3478155? – Andreyua

2

您的問題讓我想到了Android 6+中的權限管理所使用的解決方案。嘗試設置權限時,如果Toast或系統警報對話框打開,您是否曾見過錯誤消息? Android "Screen Overlay Detected" message if user is trying to grant a permission when a notification is showing

他們這樣做的方式是通過覆蓋Activity中的dispatchTouchEvent方法。這可以檢查是否有任何東西在攔截觸摸事件。您可以將您的特殊活動作爲您應用中任何想要檢測任何疊加層的活動的基類。

@Override 
    public boolean dispatchTouchEvent(MotionEvent event) { 
     mObscured = (event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0; 
    return super.dispatchTouchEvent(event); 
} 

添加一個公共的方法來檢查,在任何給定的時間,如果你的活動被遮擋

public boolean isObscured() { 
    return mObscured; 
} 

你應該要小心 - 因爲它不是從問題明確 -​​ 如果從系統的第二活動或特權應用程序位於堆棧的前端,那麼您自己的活動將不再接收觸摸事件。這是爲了捕獲可能共享視圖層次的碎片,吐司,浮動小部件和其他項目。

+0

不幸的是,不要在kitkat上工作 – Andreyua