Python-Manifest文件注入和批量ADB安装应用
本文最后更新于 92 天前,其中的信息可能已经有所发展或是发生改变。

Manifest.xml文件注入修改

def injectManifest(dump: GameDump):
    # 解包后的 AndroidManifest.xml 路径
    manifest_path = dump.get_android_manifest_xml_path()
    ET.register_namespace('android', 'http://schemas.android.com/apk/res/android')
    # manifest_path = r'C:\Users\shubao67\Desktop\ybtjd\AndroidManifest.xml'

    print(manifest_path)

    # # 解析 XML 文件
    tree = ET.parse(manifest_path)
    root = tree.getroot()

    manifest = dump.get_manifest()
    print('injectManifest package_name:', manifest.get_package_name())

    # 定义要添加的 <provider> 元素,替换命名空间前缀 用于感知生命周期
    provider = ET.Element('provider')
    provider.set(f'android:name', 'com.ssy185.sdk.common.base.lifecycle.GmLifecycleInitializer')
    provider.set(f'android:authorities', f'{manifest.get_package_name()}.GmLifecycleInitializer')
    provider.set(f'android:exported', 'false')
    provider.set(f'android:multiprocess', 'true')

    service = ET.Element('service')
    service.set(f'android:name', 'com.ssy185.sdk.feature.record.ScreenRecordService')
    service.set(f'android:foregroundServiceType', 'mediaProjection')
    # service.set(f'tools:targetApi', 'q')

    # < uses - permission android: name = "android.permission.SYSTEM_ALERT_WINDOW" / >
    alert_window_permission = ET.Element('uses-permission')
    alert_window_permission.set(f'android:name', 'android.permission.SYSTEM_ALERT_WINDOW')

    record_audio_permission = ET.Element('uses-permission')
    record_audio_permission.set(f'android:name', 'android.permission.RECORD_AUDIO')

    foreground_service_permission = ET.Element('uses-permission')
    foreground_service_permission.set(f'android:name', 'android.permission.FOREGROUND_SERVICE')

    foreground_service_media_projection_permission = ET.Element('uses-permission')
    foreground_service_media_projection_permission.set(f'android:name', 'android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION')


    # 查找 <application> 标签并添加 <provider> 元素
    application = root.find('application')
    if application is not None:
        application.append(provider)
        application.append(service)
        request_legacy_external_storage = application.attrib.get("{http://schemas.android.com/apk/res/android}requestLegacyExternalStorage")
        if request_legacy_external_storage is None:
            # 如果没有该属性,添加并设置为 true
            application.set('android:requestLegacyExternalStorage', 'true')
            print("属性 'android:requestLegacyExternalStorage' 已添加并设置为 true")
        else:
            print("属性 'android:requestLegacyExternalStorage' 已存在")
    root.append(alert_window_permission)
    root.append(record_audio_permission)
    root.append(foreground_service_permission)
    root.append(foreground_service_media_projection_permission)

    activities = application.findall('activity')
    # 遍历所有Activity 小窗模式需要resizeableActivity 为 true
    for activity in activities:
        resizeable_activity_attr = '{http://schemas.android.com/apk/res/android}resizeableActivity'
        if resizeable_activity_attr in activity.attrib:
            print('injectManifest modify resizeableActivity to true is success!')
            activity.set(resizeable_activity_attr, 'true')

    # 将修改后的 XML 保存回文件
    tree.write(manifest_path, encoding='utf-8', xml_declaration=True)
    print(f"Provider added successfully to AndroidManifest.xml")
if __name__ == '__main__':
    injectManifest(None)

批量ADB安装应用

def process_file(file_path):
    """
    处理每个文件的函数,执行 inject_web.main 命令
    """
    command = ["adb", "install", file_path]
    print(f"正在处理: {file_path}")
    subprocess.run(command)


def foldInject(folder_paths, max_concurrent_tasks):
    """
    遍历多个文件夹路径,批量处理 APK 文件,限制每次最多并发执行 `max_concurrent_tasks` 个任务。
    """
    # 创建一个线程池,max_concurrent_tasks 确定每次最多并发的任务数
    with ThreadPoolExecutor(max_workers=max_concurrent_tasks) as executor:
        futures = []  # 用于存储所有任务的未来对象

        for folder_path in folder_paths:
            # 确保 folder_path 是一个有效路径
            folder_path = Path(folder_path)
            if not folder_path.is_dir():
                print(f"警告: 路径 {folder_path} 不是有效的目录。跳过...")
                continue

            # 遍历目录中的文件
            for root, dirs, files in os.walk(folder_path):
                for file in files:
                    # 这里可以根据需要筛选文件类型,例如只处理 .apk 文件
                    if file.endswith("_patched_signed.apk"):
                        file_path = os.path.join(root, file)
                        # 提交每个文件的处理任务到线程池
                        futures.append(executor.submit(process_file, file_path))

        # 使用 wait 来确保每批任务完成后再继续下一批
        while futures:
            # 等待最多 `max_concurrent_tasks` 个任务完成
            done, futures = wait(futures, return_when="FIRST_COMPLETED")
if __name__ == '__main__':
    # 文件夹路径数组
    folder_paths = [
        r"E:\game\webView2\test",
        # r"E:\game\webView3"
    ]
    # 设置每批最多并发执行 5 个任务
    foldInject(folder_paths, max_concurrent_tasks=5)
本文链接:https://iichen.cn/?p=819
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇