经过两个月的探索和不懈研究,在市面上未有任何解决方案的情况下,由于一次巧合,我有幸实现了它。谢天谢地。
网上确有实现该功能的一些方案,但是因为都是基于Android 2.x 和 3.x,4.x还没有解决办法,因此前两个月的过程中我有了个不完善的实现方案。可以实现启用和禁用状态栏,但是每次切换需要重启系统。原理是将/system/app/SystemUI.apk文件移动到其他目录,系统会立即停止SystemUI进程,这样状态栏就会被禁用;如果要还原,再将该文件移动到原目录,重启系统即可。
不过今天我偶然发现可以不用再次重启,将SystemUI.apk文件移回原目录后,通过intent启用组件"com.android.systemui", "com.android.systemui.SystemUIService"即可主动启用systemui进程,如此可以实现不重启控制状态栏显示。废话不多说,直接上代码。
SystemBarManagerActivity.java
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.InputStreamReader;
import java.io.PrintStream;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ToggleButton;
public class SystemBarManagerActivity extends Activity {
File systemUIapkFile = new File("/system/app/SystemUI.apk");
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final ToggleButton systemBarToggleButton = (ToggleButton) findViewById(R.id.systemBarToggleButton);
systemBarToggleButton.setChecked(systemUIapkFile.exists());
systemBarToggleButton.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
systemBarToggleButton.setChecked(isChecked);
switchSystemUI();
if (isChecked) {
Intent intent = new Intent();
intent.setComponent(new ComponentName(
"com.android.systemui",
"com.android.systemui.SystemUIService"));
startService(intent);
}
}
});
}
private void switchSystemUI() {
try {
Process p;
p = Runtime.getRuntime().exec("su");
// Attempt to write a file to a root-only
DataOutputStream os = new DataOutputStream(p.getOutputStream());
os.writeBytes("mount -o remount,rw /dev/block/stl6 /system\n");
if (systemUIapkFile.exists()) {
os.writeBytes("mv /system/app/SystemUI.apk /system/SystemUI.apk\n");
}else {
os.writeBytes("mv /system/SystemUI.apk /system/app/SystemUI.apk\n");
}
os.writeBytes("mount -o remount,ro /dev/block/stl6 /system\n");
// Close the terminal
os.writeBytes("exit\n");
os.flush();
p.waitFor();
} catch (Exception e) {
ShowErrorGlobal(e);
}
}
protected void ShowErrorGlobal(Exception e) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream stream = new PrintStream(baos);
e.printStackTrace(stream);
stream.flush();
new AlertDialog.Builder(this)
.setIconAttribute(android.R.attr.alertDialogIcon)
.setTitle("Epic fail")
.setMessage("Error: " + new String(baos.toByteArray())).show();
}
}
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.InputStreamReader;
import java.io.PrintStream;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ToggleButton;
public class SystemBarManagerActivity extends Activity {
File systemUIapkFile = new File("/system/app/SystemUI.apk");
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final ToggleButton systemBarToggleButton = (ToggleButton) findViewById(R.id.systemBarToggleButton);
systemBarToggleButton.setChecked(systemUIapkFile.exists());
systemBarToggleButton.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
systemBarToggleButton.setChecked(isChecked);
switchSystemUI();
if (isChecked) {
Intent intent = new Intent();
intent.setComponent(new ComponentName(
"com.android.systemui",
"com.android.systemui.SystemUIService"));
startService(intent);
}
}
});
}
private void switchSystemUI() {
try {
Process p;
p = Runtime.getRuntime().exec("su");
// Attempt to write a file to a root-only
DataOutputStream os = new DataOutputStream(p.getOutputStream());
os.writeBytes("mount -o remount,rw /dev/block/stl6 /system\n");
if (systemUIapkFile.exists()) {
os.writeBytes("mv /system/app/SystemUI.apk /system/SystemUI.apk\n");
}else {
os.writeBytes("mv /system/SystemUI.apk /system/app/SystemUI.apk\n");
}
os.writeBytes("mount -o remount,ro /dev/block/stl6 /system\n");
// Close the terminal
os.writeBytes("exit\n");
os.flush();
p.waitFor();
} catch (Exception e) {
ShowErrorGlobal(e);
}
}
protected void ShowErrorGlobal(Exception e) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream stream = new PrintStream(baos);
e.printStackTrace(stream);
stream.flush();
new AlertDialog.Builder(this)
.setIconAttribute(android.R.attr.alertDialogIcon)
.setTitle("Epic fail")
.setMessage("Error: " + new String(baos.toByteArray())).show();
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ToggleButton
android:text="System Tray"
android:id="@+id/systemBarToggleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn="Hide System Tray"
android:textOff="Show System Tray"
android:layout_gravity="center_horizontal"
/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ToggleButton
android:text="System Tray"
android:id="@+id/systemBarToggleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn="Hide System Tray"
android:textOff="Show System Tray"
android:layout_gravity="center_horizontal"
/>
</LinearLayout>