<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Adb on Tarragon</title><link>https://tarrragon.github.io/blog/tags/adb/</link><description>Recent content in Adb on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Tue, 19 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/adb/index.xml" rel="self" type="application/rss+xml"/><item><title>flutter devices 卡住的訊號：device 數從 N 變 N-1 與 emulator 半活</title><link>https://tarrragon.github.io/blog/work-log/flutter-devices-%E5%8D%A1%E4%BD%8F%E7%9A%84%E8%A8%8A%E8%99%9Fdevice-%E6%95%B8%E5%BE%9E-n-%E8%AE%8A-n-1-%E8%88%87-emulator-%E5%8D%8A%E6%B4%BB/</link><pubDate>Tue, 19 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/work-log/flutter-devices-%E5%8D%A1%E4%BD%8F%E7%9A%84%E8%A8%8A%E8%99%9Fdevice-%E6%95%B8%E5%BE%9E-n-%E8%AE%8A-n-1-%E8%88%87-emulator-%E5%8D%8A%E6%B4%BB/</guid><description>&lt;p>&lt;code>flutter devices&lt;/code> 卡住時，最有用的訊號是「device 清單是否穩定」。這次的關鍵訊號是連續兩次掃描從 &lt;code>Found 4 connected devices&lt;/code> 變成 &lt;code>Found 3 connected devices&lt;/code>，再加上 &lt;code>Error -2 retrieving device properties for sdk gphone64 arm64&lt;/code>。這代表 ADB server 看得到某個 emulator entry，但對該 entry 的 property 查詢已經不穩定。&lt;/p>
&lt;p>這類狀態可以稱為 Android emulator 半活（zombie）：emulator host process 還在、ADB 清單仍殘留 device，但 emulator 內的 &lt;code>adbd&lt;/code> 或 Android system 已停止回應。Flutter 在掃描階段會對每個 Android device 查 properties，掃描到這個半活 device 就卡在 timeout。&lt;/p>
&lt;hr>
&lt;h2 id="事故場景">事故場景&lt;/h2>
&lt;p>事故場景的核心是「Flutter 指令看似卡住，其實卡在下游 device property 查詢」。連續跑 &lt;code>flutter devices&lt;/code> 時，輸出長這樣：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">$ flutter devices
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">Found 4 connected devices:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">Error -2 retrieving device properties for sdk gphone64 arm64:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">[卡住]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">$ flutter devices
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">Found 3 connected devices:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl">[繼續卡]&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>這段輸出有兩個值得注意的點：&lt;/p>
&lt;ol>
&lt;li>&lt;code>Error -2 retrieving device properties for sdk gphone64 arm64:&lt;/code> 訊息出現後仍繼續等待，代表 Flutter 沒有在第一個 device 失敗時 fail-fast&lt;/li>
&lt;li>第一次 &lt;code>Found 4&lt;/code>、第二次 &lt;code>Found 3&lt;/code>，代表 device 數在兩次掃描之間自己少了 1&lt;/li>
&lt;/ol>
&lt;p>&lt;code>sdk gphone64 arm64&lt;/code> 是 Android Studio AVD 預設模板（Google Phone 64-bit ARM）建出來的 emulator 顯示名稱、macOS 上跑 Android system image 都會看到這個。&lt;/p>
&lt;h3 id="為什麼計數變化是關鍵徵兆">為什麼計數變化是關鍵徵兆&lt;/h3>
&lt;p>device 數從 4 變 3，代表 ADB 對某個 emulator 的狀態判斷在兩次查詢之間變了。ADB server 內部追蹤每個 device 的狀態（&lt;code>device&lt;/code> / &lt;code>offline&lt;/code> / &lt;code>unauthorized&lt;/code> / &lt;code>no permissions&lt;/code>）；半活 emulator 在第一次掃描時仍被列在 &lt;code>Found 4&lt;/code>，第二次掃描時可能已被標成 offline 或從候選清單移除，所以掉到 &lt;code>Found 3&lt;/code>。&lt;/p>
&lt;p>判讀訊號是「同一條 list 指令連跑兩次，device 數或 device 狀態自己變」。正常穩定狀態下，清單應該保持一致；清單漂移代表 ADB server 對某個 entry 的看法不穩定，下一步要先找出那個 entry，再決定是否重啟 ADB 或 emulator。&lt;/p>
&lt;hr>
&lt;h2 id="為什麼-flutter-devices-會卡住">為什麼 flutter devices 會卡住&lt;/h2>
&lt;p>&lt;code>flutter devices&lt;/code> 的責任是把每個候選 device 補成 Flutter 可用的 target，而不只是印出 &lt;code>adb devices&lt;/code> 的結果。Flutter 對每個 ADB 看得到的 Android device 還要做幾件事：&lt;/p>
&lt;ol>
&lt;li>跑 &lt;code>adb shell getprop ro.product.cpu.abi&lt;/code> 拉 ABI&lt;/li>
&lt;li>跑 &lt;code>adb shell getprop ro.build.version.sdk&lt;/code> 拉 SDK level&lt;/li>
&lt;li>跑 &lt;code>adb shell getprop ro.product.model&lt;/code> 拉裝置型號&lt;/li>
&lt;li>視情況跑 &lt;code>adb shell&lt;/code> 其他指令確認 Flutter 支援度&lt;/li>
&lt;/ol>
&lt;p>這些是同步、序列化、有 timeout 的呼叫；timeout 通常設得相對寬鬆，讓慢一點的真機也能跑通。當其中一個 device 是 zombie 狀態：&lt;/p></description><content:encoded><![CDATA[<p><code>flutter devices</code> 卡住時，最有用的訊號是「device 清單是否穩定」。這次的關鍵訊號是連續兩次掃描從 <code>Found 4 connected devices</code> 變成 <code>Found 3 connected devices</code>，再加上 <code>Error -2 retrieving device properties for sdk gphone64 arm64</code>。這代表 ADB server 看得到某個 emulator entry，但對該 entry 的 property 查詢已經不穩定。</p>
<p>這類狀態可以稱為 Android emulator 半活（zombie）：emulator host process 還在、ADB 清單仍殘留 device，但 emulator 內的 <code>adbd</code> 或 Android system 已停止回應。Flutter 在掃描階段會對每個 Android device 查 properties，掃描到這個半活 device 就卡在 timeout。</p>
<hr>
<h2 id="事故場景">事故場景</h2>
<p>事故場景的核心是「Flutter 指令看似卡住，其實卡在下游 device property 查詢」。連續跑 <code>flutter devices</code> 時，輸出長這樣：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">$ flutter devices
</span></span><span class="line"><span class="ln">2</span><span class="cl">Found 4 connected devices:
</span></span><span class="line"><span class="ln">3</span><span class="cl">Error -2 retrieving device properties for sdk gphone64 arm64:
</span></span><span class="line"><span class="ln">4</span><span class="cl">[卡住]
</span></span><span class="line"><span class="ln">5</span><span class="cl">
</span></span><span class="line"><span class="ln">6</span><span class="cl">$ flutter devices
</span></span><span class="line"><span class="ln">7</span><span class="cl">Found 3 connected devices:
</span></span><span class="line"><span class="ln">8</span><span class="cl">[繼續卡]</span></span></code></pre></div><p>這段輸出有兩個值得注意的點：</p>
<ol>
<li><code>Error -2 retrieving device properties for sdk gphone64 arm64:</code> 訊息出現後仍繼續等待，代表 Flutter 沒有在第一個 device 失敗時 fail-fast</li>
<li>第一次 <code>Found 4</code>、第二次 <code>Found 3</code>，代表 device 數在兩次掃描之間自己少了 1</li>
</ol>
<p><code>sdk gphone64 arm64</code> 是 Android Studio AVD 預設模板（Google Phone 64-bit ARM）建出來的 emulator 顯示名稱、macOS 上跑 Android system image 都會看到這個。</p>
<h3 id="為什麼計數變化是關鍵徵兆">為什麼計數變化是關鍵徵兆</h3>
<p>device 數從 4 變 3，代表 ADB 對某個 emulator 的狀態判斷在兩次查詢之間變了。ADB server 內部追蹤每個 device 的狀態（<code>device</code> / <code>offline</code> / <code>unauthorized</code> / <code>no permissions</code>）；半活 emulator 在第一次掃描時仍被列在 <code>Found 4</code>，第二次掃描時可能已被標成 offline 或從候選清單移除，所以掉到 <code>Found 3</code>。</p>
<p>判讀訊號是「同一條 list 指令連跑兩次，device 數或 device 狀態自己變」。正常穩定狀態下，清單應該保持一致；清單漂移代表 ADB server 對某個 entry 的看法不穩定，下一步要先找出那個 entry，再決定是否重啟 ADB 或 emulator。</p>
<hr>
<h2 id="為什麼-flutter-devices-會卡住">為什麼 flutter devices 會卡住</h2>
<p><code>flutter devices</code> 的責任是把每個候選 device 補成 Flutter 可用的 target，而不只是印出 <code>adb devices</code> 的結果。Flutter 對每個 ADB 看得到的 Android device 還要做幾件事：</p>
<ol>
<li>跑 <code>adb shell getprop ro.product.cpu.abi</code> 拉 ABI</li>
<li>跑 <code>adb shell getprop ro.build.version.sdk</code> 拉 SDK level</li>
<li>跑 <code>adb shell getprop ro.product.model</code> 拉裝置型號</li>
<li>視情況跑 <code>adb shell</code> 其他指令確認 Flutter 支援度</li>
</ol>
<p>這些是同步、序列化、有 timeout 的呼叫；timeout 通常設得相對寬鬆，讓慢一點的真機也能跑通。當其中一個 device 是 zombie 狀態：</p>
<ul>
<li><code>adb shell getprop ...</code> 送出後，ADB 把指令轉發給 emulator 內的 <code>adbd</code></li>
<li><code>adbd</code> 收到了但 Android system 沒回應，或 emulator process 整個卡住沒在處理 ADB request</li>
<li>Flutter 端等 timeout、再 retry、再等更長 timeout，看起來就是「整個指令卡住」</li>
</ul>
<p><code>Error -2 retrieving device properties</code> 是其中一次嘗試 timeout 拿到的訊息（<code>-2</code> 是 Dart <code>ProcessException</code> 對應 <code>adb</code> exit code 的內部映射）。Flutter 仍會繼續掃描其他 device，所以使用者看到的是「印出錯誤訊息 + 繼續卡」。</p>
<hr>
<h2 id="為什麼是半活狀態">為什麼是半活狀態</h2>
<p>Android emulator 在 macOS 上的結構大致是：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">qemu-system-aarch64 (host process)
</span></span><span class="line"><span class="ln">2</span><span class="cl">  ├─ Android kernel
</span></span><span class="line"><span class="ln">3</span><span class="cl">  ├─ Android system services
</span></span><span class="line"><span class="ln">4</span><span class="cl">  └─ adbd (在 emulator 內部，跟 host ADB server 對接)</span></span></code></pre></div><p>半活狀態指的是「host process 還在，但 device 內部服務已無法完成 ADB request」。完全正常時 emulator 跑得動、ADB 也通；完全退出時 emulator process 已結束、ADB 清單看不到它。半活介於兩者之間：</p>
<ul>
<li>qemu host process 還在（活著）</li>
<li>emulator 內的某個環節卡住（Android system 沒在 schedule、或 adbd 卡在某個 mutex）</li>
<li>ADB server 還記得有這個 device，尚未穩定 evict</li>
<li>任何 <code>adb shell</code> 指令都打不通</li>
</ul>
<p>常見成因：</p>
<ul>
<li><strong>Quick Boot snapshot 還原失敗或部分還原</strong>——AVD 預設關機是 quick boot（存 snapshot），下次開機從 snapshot 還原；snapshot 跟當前 host kernel / hypervisor 狀態不相容時會半開機</li>
<li><strong>macOS 從 sleep 喚醒後 hypervisor framework 重置</strong>——emulator 是用 Hypervisor.framework，喚醒後虛擬 CPU 可能停在奇怪 state</li>
<li><strong>host 端記憶體壓力導致 emulator 被 swap 嚴重</strong>——表面看起來像卡，其實是在等 page fault</li>
</ul>
<p>這一層的操作目標是恢復工具鏈，而不是追到每個 emulator 內部 race condition。若症狀符合清單漂移與 property 查詢 timeout，先按恢復順序處理；只有反覆發生時，再追 AVD snapshot、system image 或 host 資源壓力。</p>
<hr>
<h2 id="恢復順序從輕到重">恢復順序（從輕到重）</h2>
<p>恢復順序的核心是先重置最小邊界，再逐層擴大。每一步都要重新跑一次 <code>flutter devices</code> 或 <code>adb devices</code>，確認是否已經恢復，避免直接砍掉 emulator 或清資料。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 1. 看 ADB 對每個 device 的狀態</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">adb devices
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1"># 看到 offline / no device / unauthorized 等異常狀態 → 先鎖定該 device</span></span></span></code></pre></div><p>如果有 device 顯示 <code>offline</code>，或正常列出但實際打不通，先重啟 ADB server：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 2. 重啟 ADB server（只重置 host 端 ADB session）</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">adb kill-server <span class="o">&amp;&amp;</span> adb start-server
</span></span><span class="line"><span class="ln">3</span><span class="cl">adb devices
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 多數狀況下，ADB 重啟後對該 device 的查詢會 fail-fast，flutter devices 會恢復</span></span></span></code></pre></div><p>如果 ADB 重啟後仍打不通該 emulator，再處理 emulator process：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 3. 對特定 emulator 發 emu kill（讓它優雅關閉）</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">adb -s emulator-5554 emu <span class="nb">kill</span>   <span class="c1"># 把 5554 換成實際 port</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 4. 還在的話，終止 qemu process</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">pkill -f qemu-system-aarch64</span></span></code></pre></div><p>長期修復路由是清掉不穩定的 snapshot。開 Android Studio → <strong>AVD Manager</strong> → 該 emulator 旁邊的小箭頭 → <strong>Cold Boot Now</strong>（避免 Quick Boot）。如果冷啟動後仍反覆壞，選 <strong>Wipe Data</strong> 把 snapshot 與 emulator 內資料整個清掉。</p>
<hr>
<h2 id="通用診斷思維">通用診斷思維</h2>
<p>工具鏈卡住的診斷核心是先區分「上游 CLI 壞掉」還是「下游 target 沒回應」。<code>flutter</code> / <code>adb</code> 指令卡住時，先用清單穩定性與 device 識別碼定位下游狀態，再決定重啟邊界。</p>
<ol>
<li><strong>觀察「同一指令連跑兩次結果是否一致」</strong>：不一致（device 數變、訊息變）等於某層狀態不穩定</li>
<li><strong>訊息裡有 device 識別碼就釘住它</strong>：<code>sdk gphone64 arm64</code>、<code>emulator-5554</code>、序號等都是 ADB 層的識別，可直接拿來 <code>adb -s &lt;id&gt; ...</code> 局部診斷</li>
<li><strong>從外往內排除</strong>：ADB server → 個別 device → emulator process → emulator 內 system，逐層重啟</li>
<li><strong>重啟邊界越大、副作用越大</strong>：<code>adb kill-server</code> 只影響 ADB session（其他 device 連線會斷一下），<code>pkill qemu</code> 直接砍 emulator，<code>Wipe Data</code> 連 emulator 內的資料都清。能用輕量手段解決就停在那層</li>
</ol>
<hr>
<h2 id="操作判準">操作判準</h2>
<ol>
<li><strong>「device 數兩次掃描之間自己變」是 zombie emulator 的關鍵徵兆</strong>：計數變化代表 ADB 內部狀態不穩定</li>
<li><strong><code>Error -2 retrieving device properties</code> 是 property 查詢失敗訊號</strong>：Flutter 仍可能繼續處理其他 device，結果是「印出錯誤訊息但繼續卡」</li>
<li><strong><code>adb kill-server &amp;&amp; adb start-server</code> 是輕量首選</strong>：它只重置 ADB session，不動 emulator 本身，多數狀況下可讓壞 device fail-fast</li>
<li><strong>半活狀態跟 application code 層級不同</strong>：先把工具鏈狀態釐清，再回到剛改的程式碼</li>
</ol>
<hr>
<h2 id="適用範圍">適用範圍</h2>
<p>這個診斷思維不限於 Android emulator：</p>
<ul>
<li>iOS Simulator 卡住時 <code>xcrun simctl list</code> 印不出來——同樣的「指令卡 + 訊息看似 fatal 但 process 仍存在」結構</li>
<li><code>flutter devices</code> 對任何 device（含 iOS、Web、desktop）的查詢都會走類似的「列出 → 逐個 query property」流程、任一層卡都會表現為類似症狀</li>
<li>廣義地說，任何「server 維護一份 client 清單 + 對每個 client 做同步呼叫」的架構（k8s <code>kubectl get pods</code> 對 zombie node、docker <code>docker ps</code> 對掛掉的 container runtime 等）都有同款 failure mode</li>
</ul>
<p>辨認規則一致：<strong>list 指令連跑兩次結果不一致 → 維護清單的 server 對某個 entry 的看法不穩定 → 找出那個 entry 局部處理</strong>。這條規則的邊界是：如果清單穩定但操作失敗，問題更可能在該 target 的權限、版本或 runtime 狀態，需要改走對應工具的細部診斷。</p>
]]></content:encoded></item><item><title>Android 無線調試連接指南</title><link>https://tarrragon.github.io/blog/other/android-%E7%84%A1%E7%B7%9A%E8%AA%BF%E8%A9%A6%E9%80%A3%E6%8E%A5%E6%8C%87%E5%8D%97/</link><pubDate>Sat, 01 Feb 2025 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/other/android-%E7%84%A1%E7%B7%9A%E8%AA%BF%E8%A9%A6%E9%80%A3%E6%8E%A5%E6%8C%87%E5%8D%97/</guid><description>&lt;h2 id="前置條件">前置條件&lt;/h2>
&lt;ul>
&lt;li>Android 裝置系統版本 &lt;strong>Android 11 以上&lt;/strong>&lt;/li>
&lt;li>電腦與 Android 裝置連接在&lt;strong>同一個區域網路&lt;/strong>&lt;/li>
&lt;li>已安裝 ADB 工具（通常隨 Android Studio 安裝）&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="步驟一啟用無線偵錯">步驟一：啟用無線偵錯&lt;/h2>
&lt;ol>
&lt;li>進入 Android 裝置的 &lt;strong>設定 → 開發人員選項&lt;/strong>&lt;/li>
&lt;li>開啟 &lt;strong>無線偵錯（Wireless debugging）&lt;/strong>&lt;/li>
&lt;li>在彈出的對話框中選擇「允許」&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="步驟二配對裝置首次連接需要">步驟二：配對裝置（首次連接需要）&lt;/h2>
&lt;h3 id="在-android-裝置上">在 Android 裝置上&lt;/h3>
&lt;ol>
&lt;li>點擊 &lt;strong>無線偵錯&lt;/strong> 進入詳細頁面&lt;/li>
&lt;li>點擊 &lt;strong>使用配對碼配對裝置&lt;/strong>&lt;/li>
&lt;li>記下畫面上顯示的：
&lt;ul>
&lt;li>&lt;strong>IP 位址與配對端口&lt;/strong>（例如：&lt;code>192.168.1.100:45213&lt;/code>）&lt;/li>
&lt;li>&lt;strong>配對碼&lt;/strong>（6 位數字）&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h3 id="在電腦終端機上">在電腦終端機上&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">adb pair &amp;lt;IP&amp;gt;:&amp;lt;配對端口&amp;gt;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>範例：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">adb pair 192.168.1.100:45213&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>輸入配對碼後，看到以下訊息表示配對成功：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">Successfully paired to 192.168.1.100:45213&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>&lt;strong>注意&lt;/strong>：配對碼有時效性，產生後請盡快輸入&lt;/p>&lt;/blockquote>
&lt;hr>
&lt;h2 id="步驟三連接裝置">步驟三：連接裝置&lt;/h2>
&lt;h3 id="在-android-裝置上-1">在 Android 裝置上&lt;/h3>
&lt;p>回到&lt;strong>無線偵錯主頁面&lt;/strong>，查看顯示的 &lt;strong>IP 位址與連接端口&lt;/strong>（與配對端口不同）&lt;/p>
&lt;p>例如：&lt;code>192.168.1.100:38745&lt;/code>&lt;/p>
&lt;h3 id="在電腦終端機上-1">在電腦終端機上&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">adb connect &amp;lt;IP&amp;gt;:&amp;lt;連接端口&amp;gt;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>範例：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">adb connect 192.168.1.100:38745&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>看到以下訊息表示連接成功：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">connected to 192.168.1.100:38745&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h2 id="步驟四驗證連接">步驟四：驗證連接&lt;/h2>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">adb devices&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>或使用 Flutter：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">flutter devices&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>應該能看到無線連接的裝置列表。&lt;/p>
&lt;hr>
&lt;h2 id="常用指令速查">常用指令速查&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>用途&lt;/th>
 &lt;th>指令&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>配對裝置&lt;/td>
 &lt;td>&lt;code>adb pair &amp;lt;IP&amp;gt;:&amp;lt;配對端口&amp;gt;&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>連接裝置&lt;/td>
 &lt;td>&lt;code>adb connect &amp;lt;IP&amp;gt;:&amp;lt;連接端口&amp;gt;&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>查看已連接裝置&lt;/td>
 &lt;td>&lt;code>adb devices&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>中斷連接&lt;/td>
 &lt;td>&lt;code>adb disconnect &amp;lt;IP&amp;gt;:&amp;lt;連接端口&amp;gt;&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>重啟 ADB 服務&lt;/td>
 &lt;td>&lt;code>adb kill-server &amp;amp;&amp;amp; adb start-server&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="疑難排解">疑難排解&lt;/h2>
&lt;h3 id="配對失敗">配對失敗&lt;/h3>
&lt;ul>
&lt;li>確認電腦與裝置在同一區網&lt;/li>
&lt;li>檢查路由器是否開啟 AP 隔離功能&lt;/li>
&lt;li>暫時關閉電腦防火牆測試&lt;/li>
&lt;/ul>
&lt;h3 id="連接後無法使用">連接後無法使用&lt;/h3>
&lt;ul>
&lt;li>確認使用的是「連接端口」而非「配對端口」&lt;/li>
&lt;li>嘗試重啟 ADB 服務：&lt;code>adb kill-server &amp;amp;&amp;amp; adb start-server&lt;/code>&lt;/li>
&lt;/ul>
&lt;h3 id="裝置離線或消失">裝置離線或消失&lt;/h3>
&lt;ul>
&lt;li>無線偵錯可能因裝置休眠而中斷&lt;/li>
&lt;li>重新執行 &lt;code>adb connect&lt;/code> 即可恢復&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="流程圖">流程圖&lt;/h2>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">┌─────────────────┐
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">│ 啟用無線偵錯 │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">└────────┬────────┘
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> ▼
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">┌─────────────────┐
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">│ 取得配對資訊 │ ← 配對端口 + 配對碼
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">└────────┬────────┘
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> ▼
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">┌─────────────────┐
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">│ adb pair │ ← 首次連接需要
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">└────────┬────────┘
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl"> ▼
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">┌─────────────────┐
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl">│ 取得連接端口 │ ← 無線偵錯主頁面
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl">└────────┬────────┘
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">16&lt;/span>&lt;span class="cl"> ▼
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">17&lt;/span>&lt;span class="cl">┌─────────────────┐
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">18&lt;/span>&lt;span class="cl">│ adb connect │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">19&lt;/span>&lt;span class="cl">└────────┬────────┘
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">20&lt;/span>&lt;span class="cl"> ▼
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">21&lt;/span>&lt;span class="cl">┌─────────────────┐
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">22&lt;/span>&lt;span class="cl">│ 連接完成 │
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">23&lt;/span>&lt;span class="cl">└─────────────────┘&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr></description><content:encoded><![CDATA[<h2 id="前置條件">前置條件</h2>
<ul>
<li>Android 裝置系統版本 <strong>Android 11 以上</strong></li>
<li>電腦與 Android 裝置連接在<strong>同一個區域網路</strong></li>
<li>已安裝 ADB 工具（通常隨 Android Studio 安裝）</li>
</ul>
<hr>
<h2 id="步驟一啟用無線偵錯">步驟一：啟用無線偵錯</h2>
<ol>
<li>進入 Android 裝置的 <strong>設定 → 開發人員選項</strong></li>
<li>開啟 <strong>無線偵錯（Wireless debugging）</strong></li>
<li>在彈出的對話框中選擇「允許」</li>
</ol>
<hr>
<h2 id="步驟二配對裝置首次連接需要">步驟二：配對裝置（首次連接需要）</h2>
<h3 id="在-android-裝置上">在 Android 裝置上</h3>
<ol>
<li>點擊 <strong>無線偵錯</strong> 進入詳細頁面</li>
<li>點擊 <strong>使用配對碼配對裝置</strong></li>
<li>記下畫面上顯示的：
<ul>
<li><strong>IP 位址與配對端口</strong>（例如：<code>192.168.1.100:45213</code>）</li>
<li><strong>配對碼</strong>（6 位數字）</li>
</ul>
</li>
</ol>
<h3 id="在電腦終端機上">在電腦終端機上</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">adb pair &lt;IP&gt;:&lt;配對端口&gt;</span></span></code></pre></div><p>範例：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">adb pair 192.168.1.100:45213</span></span></code></pre></div><p>輸入配對碼後，看到以下訊息表示配對成功：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">Successfully paired to 192.168.1.100:45213</span></span></code></pre></div><blockquote>
<p><strong>注意</strong>：配對碼有時效性，產生後請盡快輸入</p></blockquote>
<hr>
<h2 id="步驟三連接裝置">步驟三：連接裝置</h2>
<h3 id="在-android-裝置上-1">在 Android 裝置上</h3>
<p>回到<strong>無線偵錯主頁面</strong>，查看顯示的 <strong>IP 位址與連接端口</strong>（與配對端口不同）</p>
<p>例如：<code>192.168.1.100:38745</code></p>
<h3 id="在電腦終端機上-1">在電腦終端機上</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">adb connect &lt;IP&gt;:&lt;連接端口&gt;</span></span></code></pre></div><p>範例：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">adb connect 192.168.1.100:38745</span></span></code></pre></div><p>看到以下訊息表示連接成功：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">connected to 192.168.1.100:38745</span></span></code></pre></div><hr>
<h2 id="步驟四驗證連接">步驟四：驗證連接</h2>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">adb devices</span></span></code></pre></div><p>或使用 Flutter：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">flutter devices</span></span></code></pre></div><p>應該能看到無線連接的裝置列表。</p>
<hr>
<h2 id="常用指令速查">常用指令速查</h2>
<table>
  <thead>
      <tr>
          <th>用途</th>
          <th>指令</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>配對裝置</td>
          <td><code>adb pair &lt;IP&gt;:&lt;配對端口&gt;</code></td>
      </tr>
      <tr>
          <td>連接裝置</td>
          <td><code>adb connect &lt;IP&gt;:&lt;連接端口&gt;</code></td>
      </tr>
      <tr>
          <td>查看已連接裝置</td>
          <td><code>adb devices</code></td>
      </tr>
      <tr>
          <td>中斷連接</td>
          <td><code>adb disconnect &lt;IP&gt;:&lt;連接端口&gt;</code></td>
      </tr>
      <tr>
          <td>重啟 ADB 服務</td>
          <td><code>adb kill-server &amp;&amp; adb start-server</code></td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="疑難排解">疑難排解</h2>
<h3 id="配對失敗">配對失敗</h3>
<ul>
<li>確認電腦與裝置在同一區網</li>
<li>檢查路由器是否開啟 AP 隔離功能</li>
<li>暫時關閉電腦防火牆測試</li>
</ul>
<h3 id="連接後無法使用">連接後無法使用</h3>
<ul>
<li>確認使用的是「連接端口」而非「配對端口」</li>
<li>嘗試重啟 ADB 服務：<code>adb kill-server &amp;&amp; adb start-server</code></li>
</ul>
<h3 id="裝置離線或消失">裝置離線或消失</h3>
<ul>
<li>無線偵錯可能因裝置休眠而中斷</li>
<li>重新執行 <code>adb connect</code> 即可恢復</li>
</ul>
<hr>
<h2 id="流程圖">流程圖</h2>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">┌─────────────────┐
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">│  啟用無線偵錯   │
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">└────────┬────────┘
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">         ▼
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">┌─────────────────┐
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">│  取得配對資訊   │ ← 配對端口 + 配對碼
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">└────────┬────────┘
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">         ▼
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">┌─────────────────┐
</span></span><span class="line"><span class="ln">10</span><span class="cl">│   adb pair      │ ← 首次連接需要
</span></span><span class="line"><span class="ln">11</span><span class="cl">└────────┬────────┘
</span></span><span class="line"><span class="ln">12</span><span class="cl">         ▼
</span></span><span class="line"><span class="ln">13</span><span class="cl">┌─────────────────┐
</span></span><span class="line"><span class="ln">14</span><span class="cl">│  取得連接端口   │ ← 無線偵錯主頁面
</span></span><span class="line"><span class="ln">15</span><span class="cl">└────────┬────────┘
</span></span><span class="line"><span class="ln">16</span><span class="cl">         ▼
</span></span><span class="line"><span class="ln">17</span><span class="cl">┌─────────────────┐
</span></span><span class="line"><span class="ln">18</span><span class="cl">│  adb connect    │
</span></span><span class="line"><span class="ln">19</span><span class="cl">└────────┬────────┘
</span></span><span class="line"><span class="ln">20</span><span class="cl">         ▼
</span></span><span class="line"><span class="ln">21</span><span class="cl">┌─────────────────┐
</span></span><span class="line"><span class="ln">22</span><span class="cl">│    連接完成     │
</span></span><span class="line"><span class="ln">23</span><span class="cl">└─────────────────┘</span></span></code></pre></div><hr>
]]></content:encoded></item></channel></rss>