有时候我们使用某些功能时需要使用到shell命令来启动关闭服务,但是这样效率不高,每次都得自己手动在终端模拟器掉命令,确实麻烦。因此本文以代码实现一键点击发送shell命令来启动wifi调试模式。
先来看看布局把,以一个togglebutton和一个textview为主。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical" >
<ToggleButton
android:id="@+id/wifidebug"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOff="启动wifi调试"
android:textOn="关闭wifi调试" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/notice" />
</LinearLayout>
<LinearLayout
android:id="@+id/info"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:visibility="gone"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/info" />
<TextView
android:id="@+id/ip_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical" >
<TextView
android:id="@+id/wifi_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
那么就开始讲解代码了。首先我们根据需求还是得判断网络情况,通过ConnectivityManager的getNetworkInfo方法来取得wifi状态<pre name="code" class="java">ConnectivityManager conMan = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
State wifi = conMan.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
.getState();
if (wifi == State.CONNECTED || wifi == State.CONNECTING) {
wifidebug.setEnabled(true);
wifi_info.setText("");
} else {
wifidebug.setEnabled(false);
wifi_info.setText("wifi不可用");
}
对togglebutton设置点击事件,通过execShell方法来发送命令,这个方法是重点,待会也贴出来
wifidebug.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
// TODO Auto-generated method stub
if (arg1) {// true时
info.setVisibility(View.VISIBLE);
ip_info.setText("请在命令行输入 adb connect" + getLocalIpAddress()
+ ":5555");
execShell("setprop service.adb.tcp.port 5555");
execShell("stop adbd");
execShell("start adbd");
Toast.makeText(MainActivity.this, "wifi调试已经开启",
Toast.LENGTH_SHORT).show();
} else {// false时
execShell("setprop service.adb.tcp.port 5555");
execShell("stop adbd");
execShell("start adbd");
info.setVisibility(View.GONE);
Toast.makeText(MainActivity.this, "wifi调试已经关闭",
Toast.LENGTH_SHORT).show();
}
}
});
execShell方法
/**
* 发送shell命令
*
* @param str
*/
public void execShell(String str) {
try {
// 权限设置
Process p = Runtime.getRuntime().exec("su");
// 获取输出流
OutputStream outputStream = p.getOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(
outputStream);
// 将命令写入
dataOutputStream.writeBytes(str);
// 提交命令
dataOutputStream.flush();
// 关闭流操作
dataOutputStream.close();
outputStream.close();
} catch (Throwable t) {
t.printStackTrace();
}
}
另外我们在点击事件中还使用了getLocalIpAddress()方法来取得本机的ip
/**
* 检查网络及获得本机ip
*
* @return
*/
private String getLocalIpAddress() {
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
// 获取32位整型IP地址
int ipAddress = wifiInfo.getIpAddress();
// 返回整型地址转换成“*.*.*.*”地址
return String.format("%d.%d.%d.%d", (ipAddress & 0xff),
(ipAddress >> 8 & 0xff), (ipAddress >> 16 & 0xff),
(ipAddress >> 24 & 0xff));
}
/**
* 取得IP地址
* @return
*/
public static String getIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface
.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf
.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()
&& inetAddress instanceof Inet4Address) {
return inetAddress.getHostAddress().toString();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
大概这样就可以使用了,不过还不是很完善,例如我wifi下不同网段,没有判断。或者我启动wifi调试后我忽然没有网络了,也没有处理,所以会导致后面继续使用出问题。不过自己懒得改。