Android禁止ステータスバードロップダウン4.4

19875 ワード

概要
プロジェクト需要APP全画面の場合、ステータスバーのドロップダウンを禁止するのは一般的な需要でしょうが、androidシステムは普通のAPPに直接呼び出すインタフェースを直接提供していません.では、私たちは自分でインタフェースを増やしてこの機能を実現するしかありません.
具体的な実装方法
1.システムUIの変更
パス:===/frameworks/base/packages/systemUI//src/com/android/systemui/statusbar/phone/iPhone StatusBar.JAva==PhoneStatusBarでJAvaクラスにブロードキャストを登録してステータスバーの無効化と解除を実現し、その核心的な方法はdisable()メソッドを呼び出すことである.disable()はSystemUIカスタマイズの方法であり,興味のある学生はその具体的な実装を見ることができる.
次に、SystemUIの実装コードについて説明します.
@@ -494,6 +494,31 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
                                                                                                                        }

+       //add steven zhang by 20160701
+       private BroadcastReceiver mStatusShowHide = new BroadcastReceiver() {
+
+               @Override
+               public void onReceive(final Context context, Intent intent) {
+                       // TODO Auto-generated method stub
+                       String action = intent.getAction();
+                       
+                       if ("com.aura.statusbar.SHOW_OR_HIDE".equals(action)) {
+                               //  StatusBarManager.DISABLE_NONE
+                               //  StatusBarManager.DISABLE_EXPAND
+                               final int mode = intent.getIntExtra("mode", StatusBarManager.DISABLE_NONE);
+                               if (mNavigationBarView != null) {
+                                       mHandler.post(new Runnable() {
+                                               
+                                               @Override
+                                               public void run() {
+                                                       
+                                                       disable(mode);
+                                               }
+                                       });
+                               }
+                       } 
+               }
+       };
         //micheal add the Broadcast interface for  Control the wifi sleep mode change begin 20150514
         private BroadcastReceiver wifiSleepModeChangeReceiver = new BroadcastReceiver(){
             @Override
@@ -519,6 +544,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
     // ================================================================================
     protected PhoneStatusBarView makeStatusBarView() {
         final Context context = mContext;
+               // add steven zhang by 20160701
+               IntentFilter statusFilter = new IntentFilter();
+               statusFilter.addAction("com.aura.statusbar.SHOW_OR_HIDE");
+               context.registerReceiver(mStatusShowHide, statusFilter);

隠し放送を表示して登録した以上、アプリでの具体的な呼び出しを見てみましょう.
    @Override
    protected void onResume() {
        super.onResume();
        Intent i = new Intent("com.aura.statusbar.SHOW_OR_HIDE");
        i.putExtra("mode", StatusBarManager.DISABLE_EXPAND);
        sendBroadcast(i);
    }

    @Override
    protected void onPause() {
        super.onPause();
        Intent i = new Intent("com.aura.statusbar.SHOW_OR_HIDE");
        i.putExtra("mode", StatusBarManager.DISABLE_NONE);
        sendBroadcast(i);
    }

ActivityでonResumeメソッドとonPauseメソッドを書き換えてステータスバーの無効化と無効化を解除します.また、StatusBarManagerは非表示クラスなので、呼び出すときにパッケージをインポートできないとエラーが発生する可能性があります.最も簡単な方法は、間を数値で置き換えることです.以下に対応関係を示します.
public static final int DISABLE_EXPAND              = 0x00010000;
public static final int DISABLE_NOTIFICATION_ICONS  = 0x00020000;
public static final int DISABLE_NOTIFICATION_ALERTS = 0x00040000;
public static final int DISABLE_NOTIFICATION_TICKER = 0x00080000;
public static final int DISABLE_SYSTEM_INFO         = 0x00100000;
public static final int DISABLE_HOME                = 0x00200000;
public static final int DISABLE_RECENT              = 0x01000000;
public static final int DISABLE_BACK                = 0x00400000;
public static final int DISABLE_CLOCK               = 0x00800000;
public static final int DISABLE_SEARCH              = 0x02000000;
public static final int DISABLE_NONE                = 0x00000000;


public static final int DISABLE_NAVIGATION = 
        View.STATUS_BAR_DISABLE_HOME | View.STATUS_BAR_DISABLE_RECENT;

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;

したがって、StatusBarManagerを参照できない学生間では、その値は同じです.ソースコードを持っている方は、システムコンパイル後のframework jarパッケージをアプリのlibとして使用すれば、StatusBarManagerメソッドを直接使用できます.その経路は/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar.classes.JArをframeworkに変更します.jar導入工事でOKです.
上記の手順で最も重要なのはPhoneStatusBarのdisable()メソッドを呼び出すことであることを知っています.ここではブロードキャストで実現しています.新しいメソッドのある学生は、disable()に呼び出すことができればステータスバーを無効にすることができます.
2.PhoneWindowManagerの変更
パス:==/frameworks/base/policy/src/com/android/internal/policy/impl/iPhone WindowManager.java==
// monitor for system gestures
mSystemGestures = new SystemGesturesPointerEventListener(context,
new SystemGesturesPointerEventListener.Callbacks() {
    @Override
    public void onSwipeFromTop() {
        if (isGestureIsolated()) 
            return;

        if (mStatusBar != null) {
            requestTransientBars(mStatusBar);
        }
    }
    @Override
    public void onSwipeFromBottom() {
        if (isGestureIsolated()) 
            return;

        if (mNavigationBar != null && mNavigationBarOnBottom) {
            requestTransientBars(mNavigationBar);
        }
    }
    @Override
    public void onSwipeFromRight() {
        if (isGestureIsolated()) 
            return;

        if (mNavigationBar != null && !mNavigationBarOnBottom) {
            requestTransientBars(mNavigationBar);
        }
    }
    @Override
    public void onDebug() {
        // no-op
    }

    private boolean isGestureIsolated() {
        boolean ret = false;

        ret = Settings.System.getInt(mContext.getContentResolver(),"status_bar_disabled", 0) == 1;

        return ret;
    }
});

S y m e G e s t uresPointerEventListener.Callbacksの方法には、対応するジェスチャー動作がサポートされているか否かを判断する判断関数isGestureIsolated()が追加される.ここで特に説明しますが、ネットで見つけた方法は
    private boolean isGestureIsolated() {
        boolean ret = false;
        WindowState win = mFocusedWindow != null ? mFocusedWindow:mTopFullscreenOpaqueWindowState;  
        if (win != null && (win.getSystemUiVisibility() & View.SYSTEM_UI_FLAG_IMMERSIVE_GESTURE_ISOLATED) != 0)
            ret = true;  
        else  
            ret = false;  

        return ret;
    }

getSystemUiVisibility()というように判断すると、取得したwinは必ずしも現在のactivityではなく、statusbarの場合もあるので、このような効果はあまりよくなく、常にステータスバーを引き出しているので、
Settings.System.getInt(mContext.getContentResolver(),”status_bar_disabled”, 0) == 1;
判断の仕方として、この方法では非常に直接的で、ドロップダウンを禁止する必要があるときに呼び出すメリットがあります.
Settings.System.putInt(getContentResolver(), “status_bar_disabled”, 1);
OKです、禁止解除の時に呼び出します
Settings.System.putInt(getContentResolver(), “status_bar_disabled”, 0);
Activityの呼び出しを見て
@Override
    protected void onResume() {
        super.onResume();
        //    
        Settings.System.putInt(getContentResolver(), "status_bar_disabled", 1);
    }

    @Override
    protected void onPause() {
        super.onPause();
        //    
        Settings.System.putInt(getContentResolver(), "status_bar_disabled", 0);
    }

AndroidManifestでxmlで適切な権限を宣言
<uses-permission android:name="android.permission.WRITE_SETTINGS" />

インターネット上では、PhoneWindowManagerのadjustSystemUiVisibilityLwメソッドを変更する方法もあります.
@Override
    public int adjustSystemUiVisibilityLw(int visibility){
        if (Settings.System.getInt(mContext.getContentResolver(),"status_bar_disabled", 0) == 0) {
            mStatusBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility);
        }   
        mNavigationBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility);
        // Reset any bits in mForceClearingStatusBarVisibility that
        // are now clear.
        mResettingSystemUiFlags &= visibility;
        // Clear any bits in the new visibility that are currently being
        // force cleared, before reporting it.  
        return visibility & ~mResettingSystemUiFlags
                & ~mForceClearedSystemUiFlags;
    }

adjustSystemUiVisibilityLwではフラグの判断を1つ追加しますが、この実現の効果もあまりよくなく、ドロップダウンが取れる場合があります.
以上より、PhoneWindowManagerのドロップダウン禁止を実現する方法を変更するのは、S y stemGesturesPointerEventListenerである.Callbacksでは、ステータスバードロップダウンがサポートされているかどうかを判断するためにフラグビットの形式を使用する内部メソッドを追加します.
3.StatusBarManagerでのメソッドの使用
StatusBarManagerは非表示の方法なので、IDEで直接使用するにはframework jarパッケージをインポートするには、framework jarが1.SystemUIを修正したという話がありますが、ここでは繰り返しません.直接コード:
  • はAndroidManifestにあります.xmlで対応する権限を宣言する
  • <uses-permission android:name="android.permission.STATUS_BAR"/>
    <uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/>

    ネット上で声明する文章があります
    android : sharedUserId=”android.uid.system”
    この行のコードを付けずに自分でテストしても使えます.2.Activityでの参照
    @Override
        protected void onResume() {
            super.onResume();
            StatusBarManager statusBarManager = (StatusBarManager) getSystemService(Context.STATUS_BAR_SERVICE);
            statusBarManager.disable(StatusBarManager.DISABLE_EXPAND);
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            StatusBarManager statusBarManager = (StatusBarManager) getSystemService(Context.STATUS_BAR_SERVICE);
            statusBarManager.disable(StatusBarManager.DISABLE_NONE);
        }
  • は、システム署名を使用して、システムapp
  • にコンパイルされる.
    java -jar signapk.jar platform.x509.pem platform.pk8 TestDemo.apk TestDemoNew.apk TestDemoNew.apkはシステム署名後のapkで、pushは/system/app/ディレクトリの下でokになります.署名に関する知識はあまり言わないが、自分で関連資料を見つけることができる.
    次に、原生システムにおける電話処理禁止ドロップダウンのやり方を見てみましょう.コードは以下の通りです.
    パス:==/packages/apps/iPhone/src/com/android/phone/NotificationMgr.java==
    /**
     * Updates the status bar to reflect the current desired state.
     */
    private void updateStatusBar() {
        int state = StatusBarManager.DISABLE_NONE;
    
        if (!mIsExpandedViewEnabled) {
            state |= StatusBarManager.DISABLE_EXPAND;
        }
        if (!mIsNotificationEnabled) {
            state |= StatusBarManager.DISABLE_NOTIFICATION_ALERTS;
        }
        if (!mIsSystemBarNavigationEnabled) {
            // Disable *all* possible navigation via the system bar.
            state |= StatusBarManager.DISABLE_HOME;
            state |= StatusBarManager.DISABLE_RECENT;
            state |= StatusBarManager.DISABLE_BACK;
        }
    
        if (DBG) log("updateStatusBar: state = 0x" + Integer.toHexString(state));
        mStatusBarManager.disable(state);
    }

    この方法から,システムがステータスバーを無効にする方法がStatusBarManagerを呼び出して実現されることが分かった.
    参考記事
    Android応用レベルシールドステータスバー方法まとめ
    Android禁止のStatusBarドロップダウン