1

這是一個非常古老的問題,但經過這麼多的努力,我仍然無法弄清楚一個可能的解決方案。Android 5.0,防止狀態欄擴展

目的

其實很簡單。我想開發一些全屏應用程序(例如遊戲),其中狀態欄不展開,但用戶觸摸屏幕。

該應用應該能夠在Android 5.0,sdk 21(Lollipop)上工作。

我做了什麼至今

我發現this post,其中介紹瞭如何蓋上CustomView吸收觸摸事件的狀態欄,但它不爲我工作...

我甚至改變了CustomView的大小,使它覆蓋整個屏幕,但它仍然無法工作,它甚至不能覆蓋我的按鈕。

我使用的代碼附在下面。在設備上運行時,按鈕和狀態欄都可以正常工作 - 沒有任何內容被阻止。

我錯過了什麼嗎?

代碼

在AndroidManifest.xml:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> 

<application 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:supportsRtl="true" 
    android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen"> 
    <activity android:name=".MainActivity"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
</application> 

activity_main.xml中:

<TextView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Hello World!" 
    android:id="@+id/text_show" /> 

<Button 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Click" 
    android:id="@+id/button_click" 
    android:onClick="changeText" 
    android:layout_centerVertical="true" 
    android:layout_centerHorizontal="true" /> 

在MainActivity.java:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    WindowManager manager = ((WindowManager) getApplicationContext() 
      .getSystemService(Context.WINDOW_SERVICE)); 
    WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams(); 
    localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR; 
    localLayoutParams.gravity = Gravity.TOP; 
    localLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| 
      // this is to enable the notification to recieve touch events 
      WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | 
      // Draws over status bar 
      WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; 
    localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT; 
    localLayoutParams.height = (int) (50 * getResources() 
      .getDisplayMetrics().scaledDensity); 
    localLayoutParams.format = PixelFormat.TRANSPARENT; 
    CustomViewGroup view = new CustomViewGroup(this); 
    manager.addView(view, localLayoutParams); 
    setContentView(R.layout.activity_main); 
} 
boolean key = false; 
public void changeText(View view) { 
    TextView tv = (TextView) findViewById(R.id.text_show); 
    if (key) { 
     tv.setText("hahaha"); 
    } else { 
     tv.setText("eroero"); 
    } 
    key = ! key; 
} 

在CustomViewGroup(從上面的鏈接複製):

public class CustomViewGroup extends ViewGroup { 
    public CustomViewGroup(Context context) { 
     super(context); 
    } 
    @Override 
    protected void onLayout(boolean changed, int l, int t, int r, int b) { 
    } 
    @Override 
    public boolean onInterceptTouchEvent(MotionEvent ev) { 
     Log.v("CustomViewGroup", "**********Intercepted"); 
     return true; 
    } 
} 
+0

我想你需要從'onInterceptTouchEvent'方法返回** false **。 –

+0

@SweetWisherツ從這裏:https://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent(android.view.MotionEvent)它說:「返回真正的從孩子偷動作事件,並讓他們通過onTouchEvent()分派給這個ViewGroup,當前目標會收到一個ACTION_CANCEL事件,這裏不會傳遞進一步的消息。「 – WhatsUp

+0

你試過了嗎? –

回答

1

最後,我可以做的最好的是使用的是Android 5.0引入了任務鎖定功能。

參考:startLockTask

這種方法的問題:

  1. 除非你已經是授予鎖定任務的權限,以您的全屏幕應用程序一個助手應用程序,用戶將被如果他(她)允許鎖問道。
  2. 一旦被鎖定,用戶仍然可以使用物理按鈕(家庭,後面,體積等)。

因爲我的目的不是有kiosk模式,我真的不關心點2

1點也可以接受,但有點討厭,因爲它會(也應該)被要求每次調用onResume

這可以通過將服務應用程序設置爲設備所有者來解決,該服務應用程序向需要該應用程序的應用程序授予權限。但用戶必須自己做(他)自己(c.f. this answer),這是合理的,否則應用程序將能夠完全綁定您的設備。