iT邦幫忙

2025 iThome 鐵人賽

DAY 15
0

萬一刪錯怎麼辦

工具做到現在功能都滿完整了,但一直有個擔心:萬一使用者不小心刪錯重要的 APP 怎麼辦?

雖然有做安全檢查和確認對話框,但人總是會手滑。如果能在刪除前先備份 APK,刪錯了還能救回來。

提取 APK 檔案

ADB 可以把手機裡的 APP 提取出來:

# 先找到 APK 路徑
adb shell pm path com.example.app

# 然後下載 APK
adb pull /data/app/com.example.app-xxx/base.apk

包裝成函數:

async extractAPK(deviceId, packageName) {
  // 取得 APK 路徑
  const pathCmd = `"${this.adbPath}" -s ${deviceId} shell pm path ${packageName}`;
  const pathResult = await this.executeCommand(pathCmd);
  const apkPath = pathResult.replace('package:', '').trim();
  
  // 下載 APK
  const savePath = path.join(this.backupDir, `${packageName}.apk`);
  const pullCmd = `"${this.adbPath}" -s ${deviceId} pull ${apkPath} "${savePath}"`;
  
  await this.executeCommand(pullCmd);
  return savePath;
}

建立備份資料夾

需要一個地方存放備份的 APK:

getBackupDir() {
  const userDataPath = app.getPath('userData');
  const backupPath = path.join(userDataPath, 'backups');
  
  if (!fs.existsSync(backupPath)) {
    fs.mkdirSync(backupPath, { recursive: true });
  }
  
  return backupPath;
}

刪除前自動備份

修改刪除流程,加入自動備份:

async deleteWithBackup(deviceId, packageName) {
  try {
    // 先備份
    mdui.snackbar({ message: '正在備份 APK...' });
    await this.extractAPK(deviceId, packageName);
    
    // 再刪除
    await this.uninstallApp(deviceId, packageName);
    
    mdui.snackbar({ message: '刪除成功,APK 已備份' });
  } catch (error) {
    console.error('操作失敗:', error);
  }
}

還原功能

提取出來的 APK 可以重新安裝:

async restoreAPK(deviceId, apkPath) {
  const cmd = `"${this.adbPath}" -s ${deviceId} install "${apkPath}"`;
  
  await this.executeCommand(cmd);
  mdui.snackbar({ message: 'APP 已還原' });
}

備份管理介面

加個頁面讓使用者管理備份:

<div class="backup-list">
  <mdui-list>
    <mdui-list-item>
      <div slot="headline">Chrome 瀏覽器</div>
      <div slot="supporting-text">備份時間: 2024-01-15</div>
      <mdui-button-group slot="end">
        <mdui-button onclick="restoreBackup()">還原</mdui-button>
        <mdui-button onclick="deleteBackup()">刪除</mdui-button>
      </mdui-button-group>
    </mdui-list-item>
  </mdui-list>
</div>

測試備份還原

實際測試流程:

  1. 選擇一個測試 APP
  2. 點擊刪除,自動備份 APK
  3. APP 從手機上消失
  4. 到備份管理找到該 APP
  5. 點擊還原,重新安裝

成功了!刪掉的 APP 又回來了。

遇到的問題

APK 檔案很大

有些遊戲 APP 的 APK 可能有好幾 GB,下載很慢。

Split APK 問題

現在很多 APP 用 Split APK,要下載多個檔案才能還原。

async extractSplitAPK(deviceId, packageName) {
  const pathResult = await this.executeCommand(`adb shell pm path ${packageName}`);
  const apkPaths = pathResult.split('\n')
    .filter(line => line.startsWith('package:'))
    .map(line => line.replace('package:', '').trim());
  
  // 下載所有 split APK
  for (const apkPath of apkPaths) {
    // ...
  }
}

使用者資料不會備份

APK 只是程式本體,使用者資料(如遊戲進度)不會一起備份。


上一篇
[Day 13] 無線連接:擺脫 USB 線的束縛
下一篇
[Day 15] Bug 修復:讓工具更穩定
系列文
試著開發一些有用的工具程式16
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言