如何在Android 4.0 ICS中禁用StatusBar | SystemBar | 狀態欄 【完美版】


這個世界上總是有很多牛人,我們不得不對此表示無限欽佩。

 

在我上次博文發出后,我始終對此耿耿於懷,因為之前提供的解決禁用Statusbar問題在ICS中依然存在問題,即不能自動隱現,需要重啟。因此在搜索幾個月之后發現,依然難有進展。 

就在前幾天,我發現在Acer A510 這個平板上之前的方法已經完全行不通,於是重新搜索整個互聯網。茫茫大海,虧我之前做的功課甚多,在Hide Bar (http://ppareit.github.com/HideBar/ 
)這個小工具上得到啟發,很巧妙的解決了這個問題。

 

這個Hide Bar也是一國外小團隊做的禁用statusbar工具,六月份之前,仍然沒有給出適用ICS版本的更新。於是在這次重新搜索中,我欣然發現它偷偷支持了,等不及下載,看源碼,一會功夫我就將這些代碼摳到項目中。

 

說說原理吧,原理很簡單,我之前也知道過一部分,他是將com.android.systemui名稱的進程殺掉,不過這個殺不同,它是每隔一秒殺一回。之前我也試過kill這個進程,但因為每次kill后隔幾秒就會重啟,可能因為內核保護吧,當時就沒再繼續。而Hide Bar跑了個循環,隔一秒殺一下,這下內核想保護也沒用了。

 

當然我手上平板眾多,也發現一些小問題,比如一秒有點長,有的板子在這一秒間隔重啟了com.android.systemui進程,界面顯示出加載的畫面,但是不一會又被殺了,界面抖了一下又沒了那個進程,因為這樣顯得有點不穩定,我減小了kill的間隔;還有就是因為調用殺進程的命令是killall,在有的板子上卻不支持這個命令,於是我又將其他板子上/system/xbin/下的killall和usleep拿了過來,增加了這個代碼的適用性。

 

話不多說了,上代碼。

  1  package transight.tablet.android.util;
  2 
  3  import java.io.BufferedInputStream;
  4  import java.io.BufferedReader;
  5  import java.io.DataOutputStream;
  6  import java.io.File;
  7  import java.io.FileNotFoundException;
  8  import java.io.FileOutputStream;
  9  import java.io.IOException;
 10  import java.io.InputStream;
 11  import java.io.InputStreamReader;
 12  import java.util.ArrayList;
 13  import java.util.Map;
 14 
 15  import android.content.Context;
 16  import android.content.res.AssetManager;
 17  import android.util.Log;
 18 
 19  /**
 20   * Class with global information about the specific device.
 21    */
 22  public  enum Device {
 23 
 24     INSTANCE;
 25 
 26      private  static String TAG = Device. class.getSimpleName();
 27 
 28      private  boolean mHasRootBeenChecked =  false;
 29      private  boolean mIsDeviceRooted =  false;
 30 
 31      private  boolean mHasBeenInitialized =  false;
 32      private Context mAppContext =  null;
 33 
 34      //  flag if the systembar is currently visible, assume at start this is true
 35       private  boolean mSystembarVisible =  true;
 36 
 37      static  public  void initialize(Context appContext) {
 38          if (INSTANCE.mHasBeenInitialized ==  true) {
 39             Log.e(TAG, "Initializing already initialized class " + TAG);
 40              //  throw new IllegalStateException(
 41               //  "Trying to initialize already initialized class " + TAG);
 42          }
 43         INSTANCE.mHasBeenInitialized =  true;
 44         INSTANCE.mAppContext = appContext;
 45         AddKillAll(appContext, "killall");
 46         AddKillAll(appContext, "usleep");
 47     }
 48 
 49      private  static  void AddKillAll(Context appContext, String commandFileName) {
 50         File killAllFile =  new File("/system/xbin/"+commandFileName);
 51          if (!killAllFile.exists()) {
 52             AssetManager assetManager = appContext.getAssets();
 53             InputStream inputStream =  null;
 54             String commandFilePath =  null;
 55              try {
 56                 inputStream = assetManager.open(commandFileName);
 57                 commandFilePath = appContext.getApplicationContext().getFilesDir()
 58                         .getAbsolutePath() + File.separator + commandFileName;
 59                 saveToFile(commandFilePath, inputStream);
 60             }  catch (IOException e) {
 61                 Log.e("tag", e.toString());
 62             }
 63              try {
 64                 Process p;
 65                 p = Runtime.getRuntime().exec("su");
 66 
 67                  //  Attempt to write a file to a root-only
 68                  DataOutputStream os =  new DataOutputStream(p.getOutputStream());
 69                 os.writeBytes("cd system/xbin\n");
 70                 os.writeBytes("cat " + commandFilePath + " > " + commandFileName + "\n");
 71                 os.writeBytes("chmod 755 " + commandFileName + "\n");
 72 
 73                  //  Close the terminal
 74                  os.writeBytes("exit\n");
 75                 os.flush();
 76                 p.waitFor();
 77             }  catch (Exception e) {
 78                 Log.e(TAG, e.toString());
 79             }
 80         }
 81     }
 82 
 83      static  public Device getInstance() {
 84         INSTANCE.checkInitialized();
 85          return INSTANCE;
 86     }
 87 
 88      private  void checkInitialized() {
 89          if (mHasBeenInitialized ==  false)
 90              throw  new IllegalStateException("Singleton class " + TAG
 91                     + " is not yet initialized");
 92     }
 93 
 94      public  boolean isRooted() {
 95 
 96         checkInitialized();
 97 
 98         Log.v(TAG, "isRooted called");
 99 
100          if (mHasRootBeenChecked) {
101             Log.v(TAG, "Result for isRooted is cached: " + mIsDeviceRooted);
102              return mIsDeviceRooted;
103         }
104 
105          //  first try
106          Log.v(TAG, "Checking if device is rooted by checking if Superuser is available");
107          try {
108             File file =  new File("/system/app/Superuser.apk");
109              if (file.exists()) {
110                 Log.v(TAG, "Device seems rooted");
111                 mHasRootBeenChecked =  true;
112                 mIsDeviceRooted =  true;
113                  return  true;
114             }
115         }  catch (Exception e) {
116             e.printStackTrace();
117         }
118 
119          //  second try
120          Log.v(TAG, "Checking if device is rooted by checking if su is available");
121          try {
122              //  get the existing environment
123              ArrayList<String> envlist =  new ArrayList<String>();
124             Map<String, String> env = System.getenv();
125              for (String envName : env.keySet()) {
126                 envlist.add(envName + "=" + env.get(envName));
127             }
128             String[] envp = (String[]) envlist.toArray( new String[0]);
129              //  execute which su
130              Process proc = Runtime.getRuntime()
131                     .exec( new String[] { "which", "su" }, envp);
132             BufferedReader in =  new BufferedReader( new InputStreamReader(
133                     proc.getInputStream()));
134              //  if we receive location, we are on a rooted device
135               //  TODO: can break if the executable is on the device, but non working
136               if (in.readLine() !=  null) {
137                 Log.v(TAG, "Device seems rooted");
138                 mHasRootBeenChecked =  true;
139                 mIsDeviceRooted =  true;
140                  return  true;
141             }
142         }  catch (Exception e) {
143             e.printStackTrace();
144         }
145 
146         mHasRootBeenChecked =  true;
147         mIsDeviceRooted =  false;
148          return  false;
149 
150     }
151 
152      public  enum AndroidVersion {
153         HC, ICS, JB, UNKNOWN
154     };
155 
156      public AndroidVersion getAndroidVersion() {
157         checkInitialized();
158         Log.v(TAG, "getAndroidVersion called");
159          int sdk = android.os.Build.VERSION.SDK_INT;
160          if (11 <= sdk && sdk <= 13) {
161             Log.v(TAG, "We are running on HoneyComb");
162              return AndroidVersion.HC;
163         }  else  if (14 <= sdk && sdk <= 15) {
164             Log.v(TAG, "We are running on IceCreamSandwich");
165              return AndroidVersion.ICS;
166         }  else  if (16 == sdk) {
167             Log.v(TAG, "We are running on JellyBean");
168              return AndroidVersion.JB;
169         }  else {
170             Log.v(TAG, "We don't know what we are running on");
171              return AndroidVersion.UNKNOWN;
172         }
173     }
174 
175      public  void showSystembar( boolean makeVisible) {
176         checkInitialized();
177          try {
178              //  get the existing environment
179              ArrayList<String> envlist =  new ArrayList<String>();
180             Map<String, String> env = System.getenv();
181              for (String envName : env.keySet()) {
182                 envlist.add(envName + "=" + env.get(envName));
183             }
184             String[] envp = (String[]) envlist.toArray( new String[0]);
185              //  depending on makeVisible, show or hide the bar
186               if (makeVisible) {
187                 Log.v(TAG, "showBar will show systembar");
188                  //  execute in correct environment
189                  String command;
190                 Device dev = Device.getInstance();
191                  if (dev.getAndroidVersion() == AndroidVersion.HC) {
192                     command = "LD_LIBRARY_PATH=/vendor/lib:/system/lib am startservice -n com.android.systemui/.SystemUIService";
193                 }  else {
194                     command = "rm /sdcard/hidebar-lock\n"
195                             + "sleep 5\n"
196                             + "LD_LIBRARY_PATH=/vendor/lib:/system/lib am startservice -n com.android.systemui/.SystemUIService";
197                 }
198                 Runtime.getRuntime().exec( new String[] { "su", "-c", command }, envp);
199                  //  no proc.waitFor();
200                   //  we just shown the bar, set flag to visible
201                  mSystembarVisible =  true;
202             }  else {
203                 Log.v(TAG, "showBar will hide the systembar");
204                  //  execute in correct environment
205                  String command;
206                 Device dev = Device.getInstance();
207                  if (dev.getAndroidVersion() == AndroidVersion.HC) {
208                     command = "LD_LIBRARY_PATH=/vendor/lib:/system/lib service call activity 79 s16 com.android.systemui";
209                 }  else {
210                     command = "touch /sdcard/hidebar-lock\n"
211                             + "while [ -f /sdcard/hidebar-lock ]\n"
212                             + "do\n"
213                             + "killall com.android.systemui\n"
214  //                             + "sleep 1\n"
215                              + "usleep 600000\n"
216                             + "done\n"
217                             + "LD_LIBRARY_PATH=/vendor/lib:/system/lib am startservice -n com.android.systemui/.SystemUIService";
218                 }
219                 Runtime.getRuntime().exec( new String[] { "su", "-c", command }, envp);
220                  //  no proc.waitFor();
221                   //  we just hide the bar, set flag to not visible
222                  mSystembarVisible =  false;
223             }
224         }  catch (Exception e) {
225             e.printStackTrace();
226         }
227     }
228 
229      /**
230       *  @return  true is the systembar is visible or false when it is not visible
231        */
232      public  boolean isSystembarVisible() {
233         checkInitialized();
234          //  TODO: this might be improved by using 'ps ...' to see if the systemui process
235           //  is running and by checking the /sdcard/hidebar-lock file
236           return mSystembarVisible;
237     }
238 
239      public  void sendBackEvent() {
240         Log.v(TAG, "sendBackEvent");
241          try {
242              //  get the existing environment
243              ArrayList<String> envlist =  new ArrayList<String>();
244             Map<String, String> env = System.getenv();
245              for (String envName : env.keySet()) {
246                 envlist.add(envName + "=" + env.get(envName));
247             }
248             String[] envp = (String[]) envlist.toArray( new String[0]);
249             Runtime.getRuntime().exec(
250                      new String[] { "su", "-c",
251                             "LD_LIBRARY_PATH=/vendor/lib:/system/lib input keyevent 4" },
252                     envp);
253         }  catch (Exception e) {
254             e.printStackTrace();
255         }
256     }
257     
258      public  static  void saveToFile(String filePath, InputStream in){
259         FileOutputStream fos =  null;
260         BufferedInputStream bis =  null;
261          int BUFFER_SIZE = 1024;
262          byte[] buf =  new  byte[BUFFER_SIZE];
263          int size = 0;
264         bis =  new BufferedInputStream(in);
265          try {
266             fos =  new FileOutputStream(filePath);
267              while ((size = bis.read(buf)) != -1)
268                 fos.write(buf, 0, size);
269         }  catch (FileNotFoundException e) {
270             e.printStackTrace();
271         }  catch (IOException e) {
272             e.printStackTrace();
273         }  finally {
274              try {
275                  if (fos !=  null) {
276                     fos.close();
277                 }
278                  if (bis !=  null) {
279                     bis.close();
280                 }
281             }  catch (IOException e) {
282                 e.printStackTrace();
283             }
284         }
285     }
286 

287 } 

 

將killall和usleep放到assets文件夾下,執行以下代碼即可。

1 Device.initialize(getApplicationContext());
2 Device device = Device.getInstance();
3 device.showSystembar( false);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM