|
9 | 9 | import tempfile |
10 | 10 | import threading |
11 | 11 | import time |
| 12 | +import zipfile |
12 | 13 | from collections.abc import Callable |
13 | 14 | from enum import Enum |
14 | 15 | from functools import partial, wraps |
@@ -1673,13 +1674,33 @@ def backup_func() -> None: |
1673 | 1674 |
|
1674 | 1675 |
|
1675 | 1676 | def perform_install(file_path: str) -> None: |
| 1677 | + if not Path(file_path).exists(): |
| 1678 | + print_error_and_exit(f"File {file_path} does not exist") |
| 1679 | + |
| 1680 | + if file_path.endswith(".xapk"): |
| 1681 | + _perform_xapk_install(file_path) |
| 1682 | + return |
| 1683 | + |
1676 | 1684 | print_verbose(f"Installing {file_path}") |
1677 | 1685 | # -r: replace existing application |
1678 | 1686 | result = execute_adb_command2(f"install -r {file_path}") |
1679 | 1687 | if result.return_code != 0: |
1680 | 1688 | print_error(f"Failed to install {file_path}, stderr: {result.stderr}") |
1681 | 1689 |
|
1682 | 1690 |
|
| 1691 | +# Note this does not handle the obb files, which are deprecated |
| 1692 | +# https://android-developers.googleblog.com/2020/11/new-android-app-bundle-and-target-api.html |
| 1693 | +def _perform_xapk_install(file_path: str) -> None: |
| 1694 | + # Unzip the xapk file |
| 1695 | + with tempfile.TemporaryDirectory() as temp_dir: |
| 1696 | + print_verbose(f"Unzipping {file_path} to {temp_dir}") |
| 1697 | + with zipfile.ZipFile(file_path, 'r') as zip_ref: |
| 1698 | + zip_ref.extractall(temp_dir) |
| 1699 | + |
| 1700 | + result = execute_adb_command2(f"install-multiple -r {temp_dir}/*.apk") |
| 1701 | + if result.return_code != 0: |
| 1702 | + print_error_and_exit(f"Failed to install xapk {file_path}, stderr: {result.stderr}") |
| 1703 | + |
1683 | 1704 | @ensure_package_exists |
1684 | 1705 | def perform_uninstall(app_name: str, first_user: bool) -> None: |
1685 | 1706 | print_verbose(f"Uninstalling {app_name}") |
|
0 commit comments