diff --git a/core/apk_manager.py b/core/apk_manager.py index 6dafdaf..42bfc93 100644 --- a/core/apk_manager.py +++ b/core/apk_manager.py @@ -274,27 +274,36 @@ class ApkManager: def _install_one(self, serial, apk_path, package_name=""): """直连设备安装 APK。 - serial 即设备的 adb 网络地址(IP:5555),直接 adb connect 即可。 + serial 为 adb 网络地址(IP:5555)时直接 adb connect; + 本机 USB 有线设备(serial 无冒号,如 ZY322XXXX)已在 adb 中,无需 connect。 不经过 STF occupy/release,安装完断开连接,app 永久保留。 """ from .adb_helper import _adb self._set_item(serial, "installing", f"正在连接 {serial}...") try: - # adb connect(带重试,设备网络可能需要几次握手) - connected = False - last_out = "" - for attempt in range(1, 4): # 最多 3 次 - out = _adb("connect", serial) - last_out = out - if "connected" in out.lower() and "failed" not in out.lower(): - connected = True - break - _log.info(f"[{serial}] adb connect 第{attempt}次: {out}") - time.sleep(1 + attempt) - if not connected: - _log.warning(f"[{serial}] adb connect 失败: 输出={last_out}") - self._set_item(serial, "failed", f"adb connect 失败: {last_out[:150]}") - return + if ":" in serial: + # 网络设备:adb connect(带重试,设备网络可能需要几次握手) + connected = False + last_out = "" + for attempt in range(1, 4): # 最多 3 次 + out = _adb("connect", serial) + last_out = out + if "connected" in out.lower() and "failed" not in out.lower(): + connected = True + break + _log.info(f"[{serial}] adb connect 第{attempt}次: {out}") + time.sleep(1 + attempt) + if not connected: + _log.warning(f"[{serial}] adb connect 失败: 输出={last_out}") + self._set_item(serial, "failed", f"adb connect 失败: {last_out[:150]}") + return + else: + # 本机 USB 设备:确认已在 adb devices 列表中 + dev_out = _adb("devices") + if serial not in (dev_out or ""): + self._set_item(serial, "failed", + "设备未在本地 adb 列表中,请检查 USB 连接/驱动") + return # 安装 self._set_item(serial, "installing", "正在安装...") diff --git a/core/task_manager.py b/core/task_manager.py index f801231..894cd39 100644 --- a/core/task_manager.py +++ b/core/task_manager.py @@ -458,6 +458,12 @@ class TaskManager: if name in self.groups: del self.groups[name] self._save_groups() + # 同上:显式删数据库行,避免删除的分组重启后复活 + with self._db(): + row = GroupRow.query.filter_by(name=name).first() + if row: + db.session.delete(row) + db.session.commit() return True return False @@ -492,6 +498,13 @@ class TaskManager: if job_id in self.jobs: del self.jobs[job_id] self._save_jobs() + # _save_jobs 只做 upsert 不会删行:必须显式删数据库行, + # 否则删除的任务重启后会从数据库重新加载回来 + with self._db(): + row = JobRow.query.get(job_id) + if row: + db.session.delete(row) + db.session.commit() return True return False diff --git a/static/admin/monitor.js b/static/admin/monitor.js index 9a7570c..b85a8c4 100644 --- a/static/admin/monitor.js +++ b/static/admin/monitor.js @@ -2365,11 +2365,10 @@ async function deleteApk(id){ async function openInstallModal(apkId){ const apk=_apksCache.find(a=>a.id===apkId); const apkName=apk?(apk.display_name||'APK'):'APK'; - const sr=await apiGet('/api/status');if(!sr||!sr.ok)return; - const devices=sr.devices||[]; - const online=devices.filter(d=>d.present); + const r=await apiGet('/api/apks/install/devices'); + const online=(r&&r.ok)?(r.devices||[]):[]; if(!online.length){ - showToast('没有在线设备','error');return; + showToast('没有可用设备(STF 池或本机 adb 均无)','error');return; } const body= '