私はロック画面アプリに取り組んでおり、画面の上部にある通知/ステータス バーをプルダウンする機能を無効にする必要があります。Holo Locker というアプリがあり、このアプリが行うことは、ユーザーが画面の上部から引き下げると、バーが画面の上部に戻り、引き出しを引き下げることができなくなります。
どこから始めればよいかわかりません。どんな助けでも素晴らしいでしょう!ありがとう!
私はロック画面アプリに取り組んでおり、画面の上部にある通知/ステータス バーをプルダウンする機能を無効にする必要があります。Holo Locker というアプリがあり、このアプリが行うことは、ユーザーが画面の上部から引き下げると、バーが画面の上部に戻り、引き出しを引き下げることができなくなります。
どこから始めればよいかわかりません。どんな助けでも素晴らしいでしょう!ありがとう!
これはリフレクションを使用して可能です。問題は山ほどあるけど。
通知パネルが開いているか、開いているかを確認する方法はありません。したがって、に依存する必要がありますActivity#onWindowFocusChanged(boolean)
。そして、ここから問題が始まります。
メソッドの機能:
public void onWindowFocusChanged (boolean hasFocus)
アクティビティの現在の Window がフォーカスを取得または失ったときに呼び出されます。これは、このアクティビティがユーザーに表示されるかどうかを示す最良の指標です。
そのため、通知パネルの表示によるフォーカスの喪失と、他のイベントによるフォーカスの喪失を区別する方法を考え出す必要があります。
トリガーされるいくつかのイベントonWindowFocusChanged(boolean)
:
アクティビティがバックグラウンドに送信されると、ウィンドウのフォーカスが失われます (ユーザーがアプリを切り替えるか、home
ボタンを押す) 。
Dialogs と PopupWindows はそれぞれ別のウィンドウで開くため、これらが表示されると、アクティビティのウィンドウ フォーカスは失われます。
アクティビティのウィンドウがフォーカスを失うもう 1 つの例は、スピナーがクリックされて PopupWindow が表示されたときです。
あなたの活動は、これらすべての問題に対処する必要はないかもしれません。次の例は、それらのサブセットを処理します。
まず、EXPAND_STATUS_BAR
許可が必要です。
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
次に、これらのクラス スコープ変数をアクティビティで宣言します。
// To keep track of activity's window focus
boolean currentFocus;
// To keep track of activity's foreground/background status
boolean isPaused;
Handler collapseNotificationHandler;
オーバーライドonWindowFocusChanged(boolean)
:
@Override
public void onWindowFocusChanged(boolean hasFocus) {
currentFocus = hasFocus;
if (!hasFocus) {
// Method that handles loss of window focus
collapseNow();
}
}
定義collapseNow()
:
public void collapseNow() {
// Initialize 'collapseNotificationHandler'
if (collapseNotificationHandler == null) {
collapseNotificationHandler = new Handler();
}
// If window focus has been lost && activity is not in a paused state
// Its a valid check because showing of notification panel
// steals the focus from current activity's window, but does not
// 'pause' the activity
if (!currentFocus && !isPaused) {
// Post a Runnable with some delay - currently set to 300 ms
collapseNotificationHandler.postDelayed(new Runnable() {
@Override
public void run() {
// Use reflection to trigger a method from 'StatusBarManager'
Object statusBarService = getSystemService("statusbar");
Class<?> statusBarManager = null;
try {
statusBarManager = Class.forName("android.app.StatusBarManager");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Method collapseStatusBar = null;
try {
// Prior to API 17, the method to call is 'collapse()'
// API 17 onwards, the method to call is `collapsePanels()`
if (Build.VERSION.SDK_INT > 16) {
collapseStatusBar = statusBarManager .getMethod("collapsePanels");
} else {
collapseStatusBar = statusBarManager .getMethod("collapse");
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
collapseStatusBar.setAccessible(true);
try {
collapseStatusBar.invoke(statusBarService);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
// Check if the window focus has been returned
// If it hasn't been returned, post this Runnable again
// Currently, the delay is 100 ms. You can change this
// value to suit your needs.
if (!currentFocus && !isPaused) {
collapseNotificationHandler.postDelayed(this, 100L);
}
}
}, 300L);
}
}
アクティビティonPause()
と を処理しonResume()
ます。
@Override
protected void onPause() {
super.onPause();
// Activity's been paused
isPaused = true;
}
@Override
protected void onResume() {
super.onResume();
// Activity's been resumed
isPaused = false;
}
これがあなたが探しているものに近いことを願っています。
注: 通知バーをスライドして保持したときに発生するちらつきは、残念ながら避けられません。ただし、ハンドラー遅延の「より良い」値を使用して、その外観を制御/改善できます。これは Holo Locker アプリにも存在する問題です。
ユーザーがステータスを開けないようにしたいだけの場合は、これを試してください:
getWindow().addFlags(WindowManager.LayoutParams.[TYPE_SYSTEM_OVERLAY][1]);
使用法 :
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY);
setContentView(R.layout.your_layout);
前に追加 特定のニーズに基づいて、適切なWindowManager.LayoutParamsを選択できます。
お役に立てれば。
private void disablePullNotificationTouch() {
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) (25 * getResources()
.getDisplayMetrics().scaledDensity);
localLayoutParams.format = PixelFormat.RGBX_8888;
customViewGroup view = new customViewGroup(this);
manager.addView(view, localLayoutParams);
}
//Add this class in your project
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;
}