Android手機插上usb能充電但不能識別的一種解決方法
裝置要求
已root的Android手機。
背景
這個方法是意外發現的,最初同事有一臺測試機插上usb能充電但不能識別,他讓我幫他看看怎麼回事,於是我就按照常規套路,開發者模式、usb除錯、MTP什麼的一通操作,插上電腦一看,還是沒有反應,於是只有尷尬的給他說,估計是usb介面壞了,
本來以為這就完事了,事實證明,出來混都是要還的,過了幾天,是因為膝上型電腦的usb介面不夠用,想通過無線網路連線手機進行除錯,於是百度一下,找了篇教程【使用WIFI連線ADB、再也不用USB啦~~~~】就開始操作,成功連線,想著從此擺脫介面限制,心裡美滋滋,然後因為當時測試一個東西需要好幾臺手機,在附近搜刮了一波,沒想到那個破手機又到我手上來了
操作過程
先來一個正常的手機
電腦和手機在同一個區域網:
直接adb連線,會被拒絕
開啟終端模擬器進入shell,設定埠
adb通過ip連線手機,檢視裝置,可以看到已經連線上了
再看一個坑爹手機
首先,還是電腦和手機在同一區域網
同樣,直接adb連線,會被拒絕
進入終端模擬器設定埠,也沒有什麼異常
接下來,adb通過ip連線手機,杯具了,還是連線不上
開始還以為是我那裡弄錯了,又重複弄了幾遍,還是不行,開始懷疑人生了,
然後我就懷疑是adbd有問題,於是用ps檢視程序,發現根本沒有adbd的程序,
於是手動啟動adbd的程序試下
再次用adb通過ip連線手機,已經能連線上了
意外收穫
adb連線上後突然想到,因為adbd程序沒有啟動導致通過WiFi連線不上,那麼usb連線不上是不是也是這個原因呢,於是馬上插上資料線驗證一下,發現已經能連線到該裝置了
由此想到,手機啟動的時候,由於某些原因,adbd啟動失敗,導致usb連線不上手機,
解決方法
既然知道了連線不上手機是adbd沒有啟動導致的,那麼每次手機重啟動後手動把adbd啟動即可,
但是想著在手機上去輸命令列有點麻煩,於是動手寫了個app,每次啟動後點一下這個app就好了
,
程式碼如下,一條命令搞定,
package com.example.startadbd; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ShellUtils.execCommand("/sbin/adbd &",true); } }
其中用到的執行shell命令的工具類ShellUtils是以前在網上找的,具體網址忘了收藏了,程式碼直接貼下面吧,
public class ShellUtils { public static final String COMMAND_SU = "su"; public static final String COMMAND_SH = "sh"; public static final String COMMAND_EXIT = "exit\n"; public static final String COMMAND_LINE_END = "\n"; private ShellUtils() { throw new AssertionError(); } /** * 檢視是否有了root許可權 * * @return */ public static boolean checkRootPermission() { return execCommand("echo root", true, false).result == 0; } /** * 執行shell命令,預設返回結果 * * @param command command * @param isRoot 執行是否需要root許可權 * @return * @see ShellUtils#execCommand(String[], boolean, boolean) */ public static CommandResult execCommand(String command, boolean isRoot) { return execCommand(new String[]{command}, isRoot, true); } /** * 執行shell命令,預設返回結果 * * @param commands command list * @param isRoot 執行是否需要root許可權 * @return * @see ShellUtils#execCommand(String[], boolean, boolean) */ public static CommandResult execCommand(List<String> commands, boolean isRoot) { return execCommand( commands == null ? null : commands.toArray(new String[]{}), isRoot, true); } /** * 執行shell命令,預設返回結果 * * @param commands command array * @param isRoot 執行是否需要root許可權 * @return * @see ShellUtils#execCommand(String[], boolean, boolean) */ public static CommandResult execCommand(String[] commands, boolean isRoot) { return execCommand(commands, isRoot, true); } /** * execute shell command * * @param command command * @param isRoot 執行是否需要root許可權 * @param isNeedResultMsg whether need result msg * @return * @see ShellUtils#execCommand(String[], boolean, boolean) */ public static CommandResult execCommand(String command, boolean isRoot, boolean isNeedResultMsg) { return execCommand(new String[]{command}, isRoot, isNeedResultMsg); } /** * execute shell commands * * @param commands command list * @param isRoot 執行是否需要root許可權 * @param isNeedResultMsg 是否需要返回執行結果 * @return * @see ShellUtils#execCommand(String[], boolean, boolean) */ public static CommandResult execCommand(List<String> commands, boolean isRoot, boolean isNeedResultMsg) { return execCommand( commands == null ? null : commands.toArray(new String[]{}), isRoot, isNeedResultMsg); } /** * execute shell commands * * @param commands command array * @param isRoot 執行是否需要root許可權 * @param isNeedResultMsg 是否需要返回執行結果 * @return <ul> * <li>if isNeedResultMsg is false, {@link CommandResult#successMsg} * is null and {@link CommandResult#errorMsg} is null.</li> * <li>if {@link CommandResult#result} is -1, there maybe some * excepiton.</li> * </ul> */ public static CommandResult execCommand(String[] commands, boolean isRoot, boolean isNeedResultMsg) { int result = -1; if (commands == null || commands.length == 0) { return new CommandResult(result, null, null); } Process process = null; BufferedReader successResult = null; BufferedReader errorResult = null; StringBuilder successMsg = null; StringBuilder errorMsg = null; DataOutputStream os = null; try { process = Runtime.getRuntime().exec( isRoot ? COMMAND_SU : COMMAND_SH); os = new DataOutputStream(process.getOutputStream()); for (String command : commands) { if (command == null) { continue; } // donnot use os.writeBytes(commmand), avoid chinese charset // error os.write(command.getBytes()); os.writeBytes(COMMAND_LINE_END); os.flush(); } os.writeBytes(COMMAND_EXIT); os.flush(); result = process.waitFor(); // get command result if (isNeedResultMsg) { successMsg = new StringBuilder(); errorMsg = new StringBuilder(); successResult = new BufferedReader(new InputStreamReader( process.getInputStream())); errorResult = new BufferedReader(new InputStreamReader( process.getErrorStream())); String s; while ((s = successResult.readLine()) != null) { successMsg.append(s); } while ((s = errorResult.readLine()) != null) { errorMsg.append(s); } } } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (os != null) { os.close(); } if (successResult != null) { successResult.close(); } if (errorResult != null) { errorResult.close(); } } catch (IOException e) { e.printStackTrace(); } if (process != null) { process.destroy(); } } return new CommandResult(result, successMsg == null ? null : successMsg.toString(), errorMsg == null ? null : errorMsg.toString()); } /** * 執行結果 * <ul> * <li>{@link CommandResult#result} means result of command, 0 means normal, * else means error, same to excute in linux shell</li> * <li>{@link CommandResult#successMsg} means success message of command * result</li> * <li>{@link CommandResult#errorMsg} means error message of command result</li> * </ul> * * @author <a href="http://www.trinea.cn" target="_blank">Trinea</a> * 2013-5-16 */ public static class CommandResult { /** * 執行結果 **/ public int result; /** * 執行成功結果 **/ public String successMsg; /** * 執行失敗結果 **/ public String errorMsg; public CommandResult(int result) { this.result = result; } public CommandResult(int result, String successMsg, String errorMsg) { this.result = result; this.successMsg = successMsg; this.errorMsg = errorMsg; } } }
再附一個編譯好的安裝包,不想自己編譯的可以直接【下載】安裝,