Android5.0ステータスバーのドロップダウンを禁止
13181 ワード
本文は効果的で、疑問があれば、下に伝言してください.
ロックスクリーンのドロップダウンを禁止するのは、私のようにシステムのソースコードを変更できる場合と、上で開発したサードパーティのapp(システム権限がない場合)の2つです.2つの方法の処理は違います.具体的にどのように実現するかを探る前に、ソースコードを探してみましょう(興味がなければ直接スキップすることができます).
まず、comなどのステータスバーのドロップダウンを遮断する必要がある.android.phoneの緊急コール時(simカードロック)、この時ソースコード設計はステータスバーがドロップダウンできません.Androidには隠しサービスがたくさんあります.StatusBarManagerはContext.の1つです.JAvaでは、次のように表示されます.
StatusBarManagerでは、disable()メソッドのような有用なインタフェースが用意されています.システムレベルのアプリケーションでも、電話、スクリーンロックモジュールなどのStatusBarのドロップダウンを禁止するために呼び出されています.このメソッドを呼び出すには、次の権限が必要です.
1つ目は簡単ですが、システムを修正するだけで遠いですか?すべてのステータスバーがドロップダウンできません:(私がここで使っている5.1のソースコード)
アプリケーション実行中のドロップダウン不可(システムアプリケーション)
システムレベルのアプリケーション、つまり携帯電話メーカーがインプラントしたアプリケーションであれば、StatusBarManagerのdisable(int)を呼び出す方法でマスクできます.パラメータは以下の通りです.
ただし、アプリケーション・レイヤの場合、disableメソッドは権限の問題で使用できません(必ず使用する場合はシステム署名が必要です).このときcollapse()メソッドを使用することができ、現在の小米ロックスクリーンと360ロックスクリーンはこのメソッドを使用しています.
例1:会社は電話をかけてフロントで実行すると、ステータスバーがドロップダウンできないが、バックグラウンドで実行すると、ステータスバーがドロップダウンでき、phoneアプリケーションを修正する必要がある.電話の呼び出しプロセスでは、電話を呼び出すには最後にダイヤルキーを押す必要があります.ダイヤルキーを押すと、ダイヤル情報や他の情報が表示されます.このインタフェースがInCallScreenインタフェースです.もちろん、着信(2)のときは、ポップアップされたインタフェースは依然としてInCallScreenであり、私たちが電話(3)に接続した後に表示されるインタフェースは依然としてInCallScreenである.つまり、通話中、私たちがずっと見て操作していたインタフェースはInCallScreenクラスcomです.android.phone. InCallScreen.java
ロックスクリーンのドロップダウンを禁止するのは、私のようにシステムのソースコードを変更できる場合と、上で開発したサードパーティのapp(システム権限がない場合)の2つです.2つの方法の処理は違います.具体的にどのように実現するかを探る前に、ソースコードを探してみましょう(興味がなければ直接スキップすることができます).
まず、comなどのステータスバーのドロップダウンを遮断する必要がある.android.phoneの緊急コール時(simカードロック)、この時ソースコード設計はステータスバーがドロップダウンできません.Androidには隠しサービスがたくさんあります.StatusBarManagerはContext.の1つです.JAvaでは、次のように表示されます.
/**
* Use with {@link #getSystemService} to retrieve a {@link
* android.app.StatusBarManager} for interacting with the status bar.
*
* @see #getSystemService
* @see android.app.StatusBarManager
* @hide
*/
public static final String STATUS_BAR_SERVICE = "statusbar";
サービスが外部に提供されていないことを示し、@hideとマークされたインタフェースを呼び出すには、呼び出すにはソースコードでコンパイルする必要があります.ソースコードをコンパイルするclassesもできます.jarパッケージをプロジェクトに追加します.StatusBarManagerでは、disable()メソッドのような有用なインタフェースが用意されています.システムレベルのアプリケーションでも、電話、スクリーンロックモジュールなどのStatusBarのドロップダウンを禁止するために呼び出されています.このメソッドを呼び出すには、次の権限が必要です.
StatusBarManagerインスタンスの取得mStatusBarManager = (StatusBarManager) mContext.getSystemService(Context.STATUS_BAR_SERVICE);
ドロップダウン禁止と解除禁止mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND); //
mStatusBarManager.disable(StatusBarManager.DISABLE_NONE); //
システム全体をドロップダウンできません1つ目は簡単ですが、システムを修正するだけで遠いですか?すべてのステータスバーがドロップダウンできません:(私がここで使っている5.1のソースコード)
/**
* Disable some features in the status bar. Pass the bitwise-or of the DISABLE_* flags.
* To re-enable everything, pass {@link #DISABLE_NONE}.
*/
public void disable(int what) {
try {
final IStatusBarService svc = getService();
if (svc != null) {
//svc.disable(what, mToken, mContext.getPackageName());//--remove this
mService.disable(DISABLE_EXPAND, mToken, mContext.getPackageName()); //++added this
}
} catch (RemoteException ex) {
throw new RuntimeException(ex);
}
}
それからこの文章を参照して《frameworkを修正した後にシステムにブラシを入れます》をスタートさせて再起動して、一気に完成して、完成して、引き下がることができません.アプリケーション実行中のドロップダウン不可(システムアプリケーション)
システムレベルのアプリケーション、つまり携帯電話メーカーがインプラントしたアプリケーションであれば、StatusBarManagerのdisable(int)を呼び出す方法でマスクできます.パラメータは以下の通りです.
public static final int DISABLE_EXPAND = 0x00000001;
public static final int DISABLE_NOTIFICATION_ICONS = 0x00000002;
public static final int DISABLE_NOTIFICATION_ALERTS = 0x00000004;
public static final int DISABLE_NOTIFICATION_TICKER = 0x00000008;
public static final int DISABLE_NONE = 0x00000000;
具体的には、private StatusBarManager mStatusBarManager;
mStatusBarManager = (StatusBarManager)getSystemService(Context.STATUS_BAR_SERVICE);
@Override
protected void onResume() {
if (DBG) log("onResume()...");
super.onResume();
mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND);
...
}
アプリケーション実行中のドロップダウン不可(非システムアプリケーション)ただし、アプリケーション・レイヤの場合、disableメソッドは権限の問題で使用できません(必ず使用する場合はシステム署名が必要です).このときcollapse()メソッドを使用することができ、現在の小米ロックスクリーンと360ロックスクリーンはこのメソッドを使用しています.
public void onWindowFocusChanged(boolean hasFocus) {
disableStatusBar();
super.onWindowFocusChanged(hasFocus);
}
public void disableStatusBar(){
try {
Object service = getSystemService("statusbar");
Class> claz = Class.forName("android.app.StatusBarManager");
Method expand = claz.getMethod("disable");
expand.invoke(service);
} catch (Exception e) {
e.printStackTrace();
}
皆さんの理解を容易にするために、私はStatusBarManagerというクラスを貼りました:vim frameworks/base/core/java/android/app/statusBarManagement.java/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app;
import android.content.Context;
import android.os.Binder;
import android.os.RemoteException;
import android.os.IBinder;
import android.os.ServiceManager;
import android.util.Slog;
import android.view.View;
import com.android.internal.statusbar.IStatusBarService;
/**
* Allows an app to control the status bar.
*
* @hide
*/
public class StatusBarManager {
public static final int DISABLE_EXPAND = View.STATUS_BAR_DISABLE_EXPAND;
public static final int DISABLE_NOTIFICATION_ICONS = View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS;
public static final int DISABLE_NOTIFICATION_ALERTS
= View.STATUS_BAR_DISABLE_NOTIFICATION_ALERTS;
@Deprecated
public static final int DISABLE_NOTIFICATION_TICKER
= View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER;
public static final int DISABLE_SYSTEM_INFO = View.STATUS_BAR_DISABLE_SYSTEM_INFO;
public static final int DISABLE_HOME = View.STATUS_BAR_DISABLE_HOME;
public static final int DISABLE_RECENT = View.STATUS_BAR_DISABLE_RECENT;
public static final int DISABLE_BACK = View.STATUS_BAR_DISABLE_BACK;
public static final int DISABLE_CLOCK = View.STATUS_BAR_DISABLE_CLOCK;
public static final int DISABLE_SEARCH = View.STATUS_BAR_DISABLE_SEARCH;
@Deprecated
public static final int DISABLE_NAVIGATION =
View.STATUS_BAR_DISABLE_HOME | View.STATUS_BAR_DISABLE_RECENT;
public static final int DISABLE_NONE = 0x00000000;
public static final int DISABLE_MASK = DISABLE_EXPAND | DISABLE_NOTIFICATION_ICONS
| DISABLE_NOTIFICATION_ALERTS | DISABLE_NOTIFICATION_TICKER
| DISABLE_SYSTEM_INFO | DISABLE_RECENT | DISABLE_HOME | DISABLE_BACK | DISABLE_CLOCK
| DISABLE_SEARCH;
public static final int NAVIGATION_HINT_BACK_ALT = 1 << 0;
public static final int NAVIGATION_HINT_IME_SHOWN = 1 << 1;
public static final int WINDOW_STATUS_BAR = 1;
public static final int WINDOW_NAVIGATION_BAR = 2;
public static final int WINDOW_STATE_SHOWING = 0;
public static final int WINDOW_STATE_HIDING = 1;
public static final int WINDOW_STATE_HIDDEN = 2;
private Context mContext;
private IStatusBarService mService;
private IBinder mToken = new Binder();
StatusBarManager(Context context) {
mContext = context;
}
private synchronized IStatusBarService getService() {
if (mService == null) {
mService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
if (mService == null) {
Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE");
}
}
return mService;
}
/**
* :
* Disable some features in the status bar. Pass the bitwise-or of the DISABLE_* flags.
* To re-enable everything, pass {@link #DISABLE_NONE}.
*/
public void disable(int what) {
try {
final IStatusBarService svc = getService();
if (svc != null) {
//replace what to disable
svc.disable(what, mToken, mContext.getPackageName());
}
} catch (RemoteException ex) {
// system process is dead anyway.
throw new RuntimeException(ex);
}
}
/**
* Expand the notifications panel.
*/
public void expandNotificationsPanel() {
try {
final IStatusBarService svc = getService();
if (svc != null) {
svc.expandNotificationsPanel();
}
} catch (RemoteException ex) {
// system process is dead anyway.
throw new RuntimeException(ex);
}
}
/**
* Collapse the notifications and settings panels.
*/
public void collapsePanels() {
try {
final IStatusBarService svc = getService();
if (svc != null) {
svc.collapsePanels();
}
} catch (RemoteException ex) {
// system process is dead anyway.
throw new RuntimeException(ex);
}
}
/**
* Expand the settings panel.
*/
public void expandSettingsPanel() {
try {
final IStatusBarService svc = getService();
if (svc != null) {
svc.expandSettingsPanel();
}
} catch (RemoteException ex) {
// system process is dead anyway.
throw new RuntimeException(ex);
}
}
public void setIcon(String slot, int iconId, int iconLevel, String contentDescription) {
try {
final IStatusBarService svc = getService();
if (svc != null) {
svc.setIcon(slot, mContext.getPackageName(), iconId, iconLevel,
contentDescription);
}
} catch (RemoteException ex) {
// system process is dead anyway.
throw new RuntimeException(ex);
}
}
public void removeIcon(String slot) {
try {
final IStatusBarService svc = getService();
if (svc != null) {
svc.removeIcon(slot);
}
} catch (RemoteException ex) {
// system process is dead anyway.
throw new RuntimeException(ex);
}
}
public void setIconVisibility(String slot, boolean visible) {
try {
final IStatusBarService svc = getService();
if (svc != null) {
svc.setIconVisibility(slot, visible);
}
} catch (RemoteException ex) {
// system process is dead anyway.
throw new RuntimeException(ex);
}
}
/** @hide */
public static String windowStateToString(int state) {
if (state == WINDOW_STATE_HIDING) return "WINDOW_STATE_HIDING";
if (state == WINDOW_STATE_HIDDEN) return "WINDOW_STATE_HIDDEN";
if (state == WINDOW_STATE_SHOWING) return "WINDOW_STATE_SHOWING";
return "WINDOW_STATE_UNKNOWN";
}
}
模範事例例1:会社は電話をかけてフロントで実行すると、ステータスバーがドロップダウンできないが、バックグラウンドで実行すると、ステータスバーがドロップダウンでき、phoneアプリケーションを修正する必要がある.電話の呼び出しプロセスでは、電話を呼び出すには最後にダイヤルキーを押す必要があります.ダイヤルキーを押すと、ダイヤル情報や他の情報が表示されます.このインタフェースがInCallScreenインタフェースです.もちろん、着信(2)のときは、ポップアップされたインタフェースは依然としてInCallScreenであり、私たちが電話(3)に接続した後に表示されるインタフェースは依然としてInCallScreenである.つまり、通話中、私たちがずっと見て操作していたインタフェースはInCallScreenクラスcomです.android.phone. InCallScreen.java
private StatusBarManager mStatusBarManager;
mStatusBarManager = (StatusBarManager)getSystemService(Context.STATUS_BAR_SERVICE);
@Override
protected void onResume() {
if (DBG) log("onResume()...");
super.onResume();
mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND);
...
}
@Override
protected void onPause() {
if (DBG) log("onPause()...");
super.onPause();
mStatusBarManager.disable(StatusBarManager.DISABLE_NONE);
...
}
例2:会社にはセキュリティモードでステータスバーがドロップダウンできないという需要があります.androidモードではステータスバーがドロップダウンできます(2つのモードの切り替えブロードキャスト通知)、この需要は上記の方法を使用してもいいし、systemuiで直接修正してもいいです.この場合、2つ目の方法を使用します.status_bar.xml:ドロップダウンはこのViewにタッチするので、このビューでタッチイベントを表示できます.(ステータスバー部:フローティング通知、ヘッドホン、Bluetooth、バッテリ、信号、目覚まし時計などのアイコンを含む)packagecom.android.systemui.statusbar.phone;public classPhoneStatusBarView extends PanelBar {
@Override
public boolean panelsEnabled() { //
return ((mBar.mDisabled & StatusBarManager.DISABLE_EXPAND) == 0);
}
}
上記の方法では、以下のように変更できます.public boolean panelsEnabled() {
if( ){
return false;
}else{
return ((mBar.mDisabled &StatusBarManager.DISABLE_EXPAND) == 0);
}
}
package com.android.systemui.statusbar.phone;public classPanelBar extends FrameLayout {
@Override
publicboolean onTouchEvent(MotionEvent event) {
// Allow subclasses to implement enable/disable semantics
if (!panelsEnabled()) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Slog.v(TAG,String.format("onTouch: all panels disabled, ignoring touch at(%d,%d)",
(int)event.getX(), (int) event.getY()));
}
return false;
}
public booleanpanelsEnabled() {// PhoneStatusBarView
return true;
}
...
}