如何在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