<?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>MacroDroid on 瞬息科技 blogs</title>
    <link>https://blog.ouob.net/tags/macrodroid/</link>
    <description>Recent content in MacroDroid on 瞬息科技 blogs</description>
    <generator>Hugo -- 0.152.2</generator>
    <language>zh-hant</language>
    <lastBuildDate>Thu, 27 Nov 2025 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://blog.ouob.net/tags/macrodroid/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>一鍵自動開關USB偵錯模式！</title>
      <link>https://blog.ouob.net/posts/auto-enable-or-disable-android-usb-debugging/</link>
      <pubDate>Thu, 27 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://blog.ouob.net/posts/auto-enable-or-disable-android-usb-debugging/</guid>
      <description>&lt;p&gt;現在 Android 的自由真的越收越緊&lt;/p&gt;
&lt;p&gt;很多 支付/銀行軟體 連 USB偵錯權限也要管&lt;/p&gt;
&lt;p&gt;都怪台灣詐騙罰太輕&amp;hellip;&lt;/p&gt;
&lt;p&gt;不給用就不用了啊，算了&lt;/p&gt;
&lt;p&gt;但有時還是需要那些討厭的軟體&lt;/p&gt;
&lt;p&gt;比如去全聯就需要全支付🤬&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>現在 Android 的自由真的越收越緊</p>
<p>很多 支付/銀行軟體 連 USB偵錯權限也要管</p>
<p>都怪台灣詐騙罰太輕&hellip;</p>
<p>不給用就不用了啊，算了</p>
<p>但有時還是需要那些討厭的軟體</p>
<p>比如去全聯就需要全支付🤬</p>
<p>導致我時常要關閉USB偵錯模式，回家再重新打開。</p>
<p>至於你說打開偵錯模式要幹嘛</p>
<p>當然是有些寶貝軟體要更高的權限</p>
<p>像是跳過開屏廣告、權限管理、自動化腳本&hellip;</p>
<p>也是多虧了 MacroDroid 這個簡單又強大的自動化程式，讓我很直觀的創建腳本。</p>
<p>反觀老牌的Tasker，你不看說明書根本不會用😂</p>
<p>總之，先來看看成效！</p>
<p>一鍵自動開關USB偵錯模式：</p>
<p><video width="400" controls style="max-width: 100%;"><source src="/videos/one_click_to_enable_usb_debugging.mp4"></video></p>
<h2 id="腳本截圖">腳本截圖</h2>
<p>小米用戶又可以來抄作業了🐶</p>
<p>開啟USB debugging：
<img src="/images/Screenshot_2025-11-24-00-00-48-225_com.arlosoft.macrodroid-edit.jpg" width="300px" /></p>
<p>開啟網路ADB：</p>
<p>這裡我是把網路偵錯開關直接放到下拉選單，這樣操作更快。
<img src="/images/Screenshot_2025-11-24-00-01-22-603_com.arlosoft.macrodroid.jpg" width="300px" /></p>
<p>關閉USB 偵錯：
<img src="/images/Screenshot_2025-11-24-00-00-06-980_com.arlosoft.macrodroid-edit.jpg" width="300px" /></p>
<p>這裡用到的大部分功能，在上篇 『自動解鎖Links to Windows』有詳細介紹，所以就不重複撰寫了～</p>
<p>MacroDroid 系列預計還會寫幾篇，有興趣的可以先追蹤。</p>
<p>那就這樣，下篇見～</p>
]]></content:encoded>
    </item>
    <item>
      <title>Seamless Link Android to Windows 自動解鎖手機並點擊確認連接</title>
      <link>https://blog.ouob.net/posts/seamless-link-android-to-windows/</link>
      <pubDate>Tue, 04 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://blog.ouob.net/posts/seamless-link-android-to-windows/</guid>
      <description>&lt;p&gt;用過iPhone mirroring的都知道，在Mac上控制iPhone不需要手動解鎖手機，整個連接的體驗可說是十分絲滑。（這就是封閉系統的好處嗎😆&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>用過iPhone mirroring的都知道，在Mac上控制iPhone不需要手動解鎖手機，整個連接的體驗可說是十分絲滑。（這就是封閉系統的好處嗎😆</p>
<p>然而，PC陣營就沒有這個待遇了。</p>
<p>因為Window和Android是不同廠商，彼此有安全性上的考量，所以可能永遠也不會有自動解鎖的功能。</p>
<p>但是！這兩個系統權限都足夠開放、自由，我們完全可以自己寫腳本，實現自動解鎖手機，媲美iPhone mirroring的絲滑體驗！😎</p>
<h2 id="前置要求">前置要求</h2>
<ul>
<li>電腦：Link to Windows 配對好手機</li>
<li>手機：Play Store 搜尋並安裝 MacroDroid</li>
</ul>
<h2 id="link-to-windows-遠控手機流程">Link to Windows 遠控手機流程</h2>

<div class="mermaid">flowchart LR
	A[電腦]
	B[手機]
	C[用戶點擊同意投影畫面]
	D{手機為鎖定狀態？}
	E[用戶解鎖手機]
	Z[成功投影畫面]
	
	A--發送控制請求-->B --> C --> D
	D --是--> E --> Z
	D --否--> Z</div>
 
<p>需要自動化的部分：</p>
<ul>
<li>點擊同意投影畫面</li>
<li>解鎖手機</li>
</ul>
<h2 id="設定流程">設定流程</h2>
<p>以下流程基於小米手機，其他品牌要自己微調腳本。</p>
<p>米粉可以直接抄作業了😇
<div class="embedded-file" style="border: 1px solid var(--border); border-radius: 8px; padding: 20px; margin: 20px 0; background-color: var(--code-bg);">
    <div style="display: flex; align-items: center; margin-bottom: 15px;"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#28a745" stroke-width="2" style="margin-right: 10px;">
                <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon>
            </svg>
        <div>
            <h4 style="margin: 0; color: var(--primary);">Auto_confirm_Link_to_windows MacroDroid 腳本</h4><p style="margin: 5px 0 0 0; color: var(--secondary); font-size: 14px;">MacroDroid 自動化腳本檔案</p>
        </div>
    </div>
    
    <div style="display: flex; gap: 10px;">
        <a href="/files/Auto_confirm_Link_to_windows.macro" download style="display: inline-flex; align-items: center; background-color: #007acc; color: white; padding: 8px 16px; text-decoration: none; border-radius: 5px; font-size: 14px; transition: opacity 0.2s;">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 6px;">
                <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
                <polyline points="7,10 12,15 17,10"></polyline>
                <line x1="12" y1="15" x2="12" y2="3"></line>
            </svg>
            下載檔案
        </a>
        <button onclick="previewFile('\/files\/Auto_confirm_Link_to_windows.macro', 'Auto_confirm_Link_to_windows.macro')" style="display: inline-flex; align-items: center; background-color: transparent; color: var(--primary); padding: 8px 16px; text-decoration: none; border-radius: 5px; font-size: 14px; border: 1px solid var(--border); transition: background-color 0.2s; cursor: pointer;">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 6px;">
                <path d="M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6"></path>
                <path d="M15 3h6v6"></path>
                <path d="M10 14L21 3"></path>
            </svg>
            預覽
        </button>
    </div>

    <script>
    function previewFile(fileUrl, filename) {
        fetch(fileUrl)
            .then(response => response.text())
            .then(content => {
                const html = `<!DOCTYPE html>
<html lang="zh-TW">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>${filename}</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        html, body {
            width: 100%;
            height: 100%;
            overflow: auto;
        }
        body {
            font-family: 'Monaco', 'Courier New', monospace;
            font-size: 14px;
            line-height: 1.5;
            padding: 20px;
            background-color: #f5f5f5;
            color: #333;
        }
        pre {
            background-color: white;
            padding: 20px;
            border-radius: 4px;
            border: 1px solid #ddd;
            white-space: pre-wrap;
            word-wrap: break-word;
            overflow-x: auto;
        }
        @media (prefers-color-scheme: dark) {
            body {
                background-color: #1e1e1e;
                color: #e0e0e0;
            }
            pre {
                background-color: #2d2d2d;
                border-color: #444;
                color: #e0e0e0;
            }
        }
    </style>
</head>
<body>
    <pre>${escapeHtml(content)}</pre>
</body>
</html>`;
                const blob = new Blob([html], { type: 'text/html; charset=utf-8' });
                const url = URL.createObjectURL(blob);
                window.open(url, '_blank');
            })
            .catch(err => {
                console.error('Preview failed:', err);
                alert('無法預覽檔案');
            });
    }

    function escapeHtml(text) {
        const map = {
            '&': '&amp;',
            '<': '&lt;',
            '>': '&gt;',
            '"': '&quot;',
            "'": '&#039;'
        };
        return text.replace(/[&<>"']/g, m => map[m]);
    }
    </script>
</div>
<div class="embedded-file" style="border: 1px solid var(--border); border-radius: 8px; padding: 20px; margin: 20px 0; background-color: var(--code-bg);">
    <div style="display: flex; align-items: center; margin-bottom: 15px;"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="var(--secondary)" stroke-width="2" style="margin-right: 10px;">
                <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
                <polyline points="14,2 14,8 20,8"></polyline>
            </svg>
        <div>
            <h4 style="margin: 0; color: var(--primary);">Unlock_phone.ablock</h4><p style="margin: 5px 0 0 0; color: var(--secondary); font-size: 14px;">檔案下載</p>
        </div>
    </div>
    
    <div style="display: flex; gap: 10px;">
        <a href="/files/Unlock_phone.ablock" download style="display: inline-flex; align-items: center; background-color: #007acc; color: white; padding: 8px 16px; text-decoration: none; border-radius: 5px; font-size: 14px; transition: opacity 0.2s;">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 6px;">
                <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
                <polyline points="7,10 12,15 17,10"></polyline>
                <line x1="12" y1="15" x2="12" y2="3"></line>
            </svg>
            下載檔案
        </a>
        <button onclick="previewFile('\/files\/Unlock_phone.ablock', 'Unlock_phone.ablock')" style="display: inline-flex; align-items: center; background-color: transparent; color: var(--primary); padding: 8px 16px; text-decoration: none; border-radius: 5px; font-size: 14px; border: 1px solid var(--border); transition: background-color 0.2s; cursor: pointer;">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 6px;">
                <path d="M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6"></path>
                <path d="M15 3h6v6"></path>
                <path d="M10 14L21 3"></path>
            </svg>
            預覽
        </button>
    </div>

    <script>
    function previewFile(fileUrl, filename) {
        fetch(fileUrl)
            .then(response => response.text())
            .then(content => {
                const html = `<!DOCTYPE html>
<html lang="zh-TW">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>${filename}</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        html, body {
            width: 100%;
            height: 100%;
            overflow: auto;
        }
        body {
            font-family: 'Monaco', 'Courier New', monospace;
            font-size: 14px;
            line-height: 1.5;
            padding: 20px;
            background-color: #f5f5f5;
            color: #333;
        }
        pre {
            background-color: white;
            padding: 20px;
            border-radius: 4px;
            border: 1px solid #ddd;
            white-space: pre-wrap;
            word-wrap: break-word;
            overflow-x: auto;
        }
        @media (prefers-color-scheme: dark) {
            body {
                background-color: #1e1e1e;
                color: #e0e0e0;
            }
            pre {
                background-color: #2d2d2d;
                border-color: #444;
                color: #e0e0e0;
            }
        }
    </style>
</head>
<body>
    <pre>${escapeHtml(content)}</pre>
</body>
</html>`;
                const blob = new Blob([html], { type: 'text/html; charset=utf-8' });
                const url = URL.createObjectURL(blob);
                window.open(url, '_blank');
            })
            .catch(err => {
                console.error('Preview failed:', err);
                alert('無法預覽檔案');
            });
    }

    function escapeHtml(text) {
        const map = {
            '&': '&amp;',
            '<': '&lt;',
            '>': '&gt;',
            '"': '&quot;',
            "'": '&#039;'
        };
        return text.replace(/[&<>"']/g, m => map[m]);
    }
    </script>
</div>
腳本截圖：
<img src="/images/Screenshot_2025-07-13-00-18-28-770_com.arlosoft.macrodroid.jpg" width="400px" />
<img src="/images/Screenshot_2025-07-13-00-17-28-157_com.arlosoft.macrodroid-edit%201.jpg" width="400px" /></p>
<h3 id="設置macrodroid">設置MacroDroid</h3>
<ol>
<li>
<p>自動同意投影畫面</p>
<p>我首先給予這兩個系統應用 project_media 權限：</p>
<ul>
<li>連接至Windows</li>
<li>Device Integration Service（負責用戶確認介面）</li>
</ul>
<p>測試後還是會顯示要求權限的介面，因此可以得知這個介面是他們魔改過的，不是直接調用系統權限的介面。</p>
<p>所以，改用無障礙權限直接點擊。</p>
<p>在macrodroid中創建腳本並新增trigger，檢測螢幕內容，檢測範圍只選擇Device Integration Service 這個系統應用，沒限制的話會一直檢測螢幕內容很耗電哦
<img src="/images/Screenshot_2025-07-12-23-48-04-541_com.arlosoft.macrodroid.jpg" width="400px" /></p>
<pre tabindex="0"><code>要透過連結至 Windows 開始進行錄製或投放內容嗎
</code></pre><p>Include overlays 要打勾 ✅</p>
<p>這樣檢測到該文本後就可以自動執行點擊Action了</p>
</li>
<li>
<p>自動解除鎖定畫面</p>
<p>當手機處於鎖定狀態，Link to Windows連接時會自動轉跳至輸入密碼頁面</p>
<p>所以，加入一個wait until trigger 檢測鎖定畫面的文字，小米手機是：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">請用數字密碼或指紋解鎖
</span></span></code></pre></div><p>並設定cancel after timeout，因為沒有檢測到文字，就表示手機處於解鎖狀態，不需要持續檢測。</p>
 <img src="/images/Screenshot_2025-07-13-00-18-24-337_com.arlosoft.macrodroid.jpg" width="400px" />
<p>剩下的解鎖action我放到action block裡面，也方便其他腳本調用。</p>
<pre tabindex="0"><code>📚 action block的概念就類似程式中的函數
</code></pre><pre tabindex="0"><code>💡 如果你只有一個腳本要用話，就直接把輸入密碼的action放到同個腳本就好。
</code></pre> <img src="/images/Screenshot_2025-07-13-00-17-28-157_com.arlosoft.macrodroid-edit%201.jpg" width="400px" />
<p>在這個action block 定義兩個輸入變量，
是否亮屏和切換至輸入密碼介面，用於執行特定操作。
不過在我們這個場景中都用不到，所以忽略即可。</p>
<p>後面的action group 就是放輸入密碼的action。</p>
<pre tabindex="0"><code>📚 action group 的用途就是把很多action放到一個群組裡面，方便移動位置。
</code></pre><pre tabindex="0"><code>💡 如果你用的不是數字密碼，就用UI Interaction 裡面的paste 把你的密碼輸入進去就好。
或者直接用作者的pin unlock的action，但輸入密碼中間的間隔會比較久，因該有兼容性考量，我就沒有使用。
</code></pre></li>
<li>
<p>腳本設置完成！</p>
<p>可以來測試效果了，沒意外的話，你應該可以做到像我影片中所展示的效果。</p>
</li>
</ol>
<p><video width="400" controls style="max-width: 100%;"><source src="/videos/auto_link2windows_mute_.mp4"></video></p>
]]></content:encoded>
    </item>
  </channel>
</rss>
