├── app ├── .gitignore ├── src │ ├── full │ │ ├── assets │ │ │ └── APKEditor.pk8 │ │ ├── res │ │ │ ├── values-zh-rCN │ │ │ │ └── strings.xml │ │ │ └── values │ │ │ │ └── strings.xml │ │ └── AndroidManifest.xml │ ├── main │ │ ├── ic_launcher-playstore.png │ │ ├── res │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_round.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_round.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_round.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_round.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_round.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ ├── values │ │ │ │ ├── ic_launcher_background.xml │ │ │ │ ├── colors.xml │ │ │ │ └── styles.xml │ │ │ ├── xml │ │ │ │ └── provider_paths.xml │ │ │ ├── layout │ │ │ │ ├── layout_recyclerview.xml │ │ │ │ ├── recycle_view_xmleditor.xml │ │ │ │ ├── recycle_view_textview.xml │ │ │ │ ├── layout_textview.xml │ │ │ │ ├── progress_view.xml │ │ │ │ ├── layout_keystoreverifier.xml │ │ │ │ ├── recycle_view_stringviewer.xml │ │ │ │ ├── progress_layout.xml │ │ │ │ ├── recycle_view_apkdetails.xml │ │ │ │ ├── activity_apkexplorer.xml │ │ │ │ ├── layout_imagepicker.xml │ │ │ │ ├── activity_settings.xml │ │ │ │ ├── layout_resviewer.xml │ │ │ │ ├── recycle_view_batch_options.xml │ │ │ │ ├── recycle_view_exploreinfo.xml │ │ │ │ ├── recycle_view_about.xml │ │ │ │ ├── activity_quickedits.xml │ │ │ │ ├── permission_layout.xml │ │ │ │ ├── layout_batchoptions.xml │ │ │ │ ├── activity_start.xml │ │ │ │ ├── activity_main.xml │ │ │ │ ├── fragment_about.xml │ │ │ │ ├── layout_xml_editor.xml │ │ │ │ ├── activity_exploring.xml │ │ │ │ ├── recycle_view_quickedits.xml │ │ │ │ ├── recycle_view_apkexplorer.xml │ │ │ │ ├── activity_imageview.xml │ │ │ │ ├── app_title_layout.xml │ │ │ │ ├── recycle_view_apkpicker.xml │ │ │ │ ├── activity_texteditor.xml │ │ │ │ ├── recycle_view_resviewer.xml │ │ │ │ ├── activity_textview.xml │ │ │ │ └── activity_xmleditor.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ ├── drawable │ │ │ │ ├── ic_installer.xml │ │ │ │ ├── ic_back.xml │ │ │ │ ├── ic_check.xml │ │ │ │ ├── ic_sort.xml │ │ │ │ ├── ic_start.xml │ │ │ │ ├── ic_file.xml │ │ │ │ ├── ic_export.xml │ │ │ │ ├── ic_about.xml │ │ │ │ ├── ic_clear.xml │ │ │ │ ├── ic_image.xml │ │ │ │ ├── ic_batch.xml │ │ │ │ ├── ic_bundle.xml │ │ │ │ ├── ic_settings.xml │ │ │ │ ├── ic_template.xml │ │ │ │ ├── ic_classes.xml │ │ │ │ ├── ic_manifest.xml │ │ │ │ ├── ic_open.xml │ │ │ │ ├── ic_add.xml │ │ │ │ ├── ic_folder.xml │ │ │ │ ├── ic_apps.xml │ │ │ │ ├── ic_select.xml │ │ │ │ ├── ic_export_file.xml │ │ │ │ ├── ic_edit.xml │ │ │ │ ├── ic_key.xml │ │ │ │ ├── ic_check_circle.xml │ │ │ │ ├── ic_rate.xml │ │ │ │ ├── ic_cancel.xml │ │ │ │ ├── ic_explore.xml │ │ │ │ ├── ic_save.xml │ │ │ │ ├── ic_projects.xml │ │ │ │ ├── ic_delete.xml │ │ │ │ ├── ic_expand.xml │ │ │ │ ├── ic_dots.xml │ │ │ │ ├── ic_reset.xml │ │ │ │ ├── ic_search.xml │ │ │ │ ├── ic_select_all.xml │ │ │ │ ├── ic_xml.xml │ │ │ │ ├── ic_sort_az.xml │ │ │ │ ├── ic_support.xml │ │ │ │ ├── ic_sort_time.xml │ │ │ │ ├── ic_delete_file.xml │ │ │ │ ├── ic_res.xml │ │ │ │ ├── ic_translate.xml │ │ │ │ ├── ic_delete_folder.xml │ │ │ │ ├── ic_privacy.xml │ │ │ │ ├── ic_string.xml │ │ │ │ ├── ic_search_folder.xml │ │ │ │ ├── ic_share.xml │ │ │ │ ├── ic_donate.xml │ │ │ │ ├── ic_issue.xml │ │ │ │ ├── ic_android_app.xml │ │ │ │ ├── ic_build.xml │ │ │ │ ├── ic_book.xml │ │ │ │ └── ic_github.xml │ │ │ ├── values-v35 │ │ │ │ └── styles.xml │ │ │ └── menu │ │ │ │ └── navigation_main.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── apk │ │ │ │ └── editor │ │ │ │ ├── services │ │ │ │ └── InstallerService.java │ │ │ │ ├── utils │ │ │ │ ├── SerializableItems │ │ │ │ │ ├── QuickEditsItems.java │ │ │ │ │ ├── APKPickerItems.java │ │ │ │ │ └── PackageItems.java │ │ │ │ ├── menus │ │ │ │ │ └── BundleOptionsMenu.java │ │ │ │ ├── dialogs │ │ │ │ │ ├── SignatureMismatchDialog.java │ │ │ │ │ ├── ClearAppSettingsDialog.java │ │ │ │ │ ├── InvalidFileDialog.java │ │ │ │ │ ├── BatchSigningOptionsDialog.java │ │ │ │ │ ├── SigningOptionsDialog.java │ │ │ │ │ ├── ProgressDialog.java │ │ │ │ │ └── XMLEditorDialog.java │ │ │ │ ├── APKPicker.java │ │ │ │ ├── PK8File.java │ │ │ │ ├── tasks │ │ │ │ │ ├── DeleteProject.java │ │ │ │ │ ├── ShareBundle.java │ │ │ │ │ ├── ClearAppSettings.java │ │ │ │ │ ├── TransferApps.java │ │ │ │ │ ├── ExportProject.java │ │ │ │ │ ├── ExportToStorage.java │ │ │ │ │ └── ExportApp.java │ │ │ │ ├── Common.java │ │ │ │ └── APKEditorUtils.java │ │ │ │ ├── activities │ │ │ │ ├── StartActivity.java │ │ │ │ └── ExploringActivity.java │ │ │ │ ├── fragments │ │ │ │ ├── CertificateFragment.java │ │ │ │ ├── ManifestFragment.java │ │ │ │ ├── APKDetailsFragment.java │ │ │ │ └── PermissionsFragment.java │ │ │ │ ├── interfaces │ │ │ │ ├── KeyStoreAliasChoiceDialog.java │ │ │ │ └── KeyStoreVerifierInterface.java │ │ │ │ └── adapters │ │ │ │ ├── APKDetailsAdapter.java │ │ │ │ ├── StringViewAdapter.java │ │ │ │ ├── ExploredInfoAdapter.java │ │ │ │ ├── TextViewAdapter.java │ │ │ │ ├── BatchOptionsAdapter.java │ │ │ │ └── SettingsAdapter.java │ │ └── AndroidManifest.xml │ └── play │ │ ├── res │ │ └── values │ │ │ └── strings.xml │ │ └── java │ │ └── com │ │ └── apk │ │ └── editor │ │ └── utils │ │ └── menu │ │ └── ExploreOptionsMenu.java ├── proguard-rules.pro └── build.gradle ├── fastlane └── metadata │ └── android │ ├── de │ └── short_description.txt │ ├── en-US │ ├── short_description.txt │ ├── images │ │ ├── icon.png │ │ └── phoneScreenshots │ │ │ ├── 1.png │ │ │ ├── 2.png │ │ │ ├── 3.png │ │ │ ├── 4.png │ │ │ ├── 5.png │ │ │ ├── 6.png │ │ │ ├── 7.png │ │ │ ├── 8.png │ │ │ ├── 9.png │ │ │ ├── 10.png │ │ │ ├── 11.png │ │ │ └── 12.png │ ├── changelogs │ │ └── 32.txt │ └── full_description.txt │ ├── es │ ├── short_description.txt │ └── full_description.txt │ └── pt-BR │ ├── short_description.txt │ └── full_description.txt ├── gradle ├── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties └── libs.versions.toml ├── gradle.properties ├── .gitignore ├── .github ├── FUNDING.yml └── workflows │ └── android.yml ├── settings.gradle ├── privacy-policy.md ├── Credits.md └── gradlew.bat /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /release 3 | /full 4 | /play 5 | /src/main/gen 6 | *.jks -------------------------------------------------------------------------------- /fastlane/metadata/android/de/short_description.txt: -------------------------------------------------------------------------------- 1 | quelloffener APK Explorer/Editor & Split APK/App Bundle Installer 2 | -------------------------------------------------------------------------------- /app/src/full/assets/APKEditor.pk8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/app/src/full/assets/APKEditor.pk8 -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/short_description.txt: -------------------------------------------------------------------------------- 1 | An open-source APK explorer/Editor & Split APK/App bundle Installer for Android! -------------------------------------------------------------------------------- /fastlane/metadata/android/es/short_description.txt: -------------------------------------------------------------------------------- 1 | An open-source APK explorer/Editor & Split APK/App bundle Installer for Android! -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /fastlane/metadata/android/pt-BR/short_description.txt: -------------------------------------------------------------------------------- 1 | Instalador/explorador/editor de APKS e App bundles de código aberto para Android 2 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/fastlane/metadata/android/en-US/images/icon.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #000000 4 | -------------------------------------------------------------------------------- /app/src/main/res/xml/provider_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/7.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/8.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/9.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/10.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/11.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apk-editor/APK-Explorer-Editor/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/12.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #121212 4 | #FFFFFF 5 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | android.nonFinalResIds=false 2 | android.nonTransitiveRClass=false 3 | org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 4 | android.useAndroidX=true -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_recyclerview.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | .idea 4 | /local.properties 5 | /.idea/caches 6 | /.idea/libraries 7 | /.idea/modules.xml 8 | /.idea/workspace.xml 9 | /.idea/navEditor.xml 10 | /.idea/assetWizardSettings.xml 11 | .DS_Store 12 | /build 13 | /captures 14 | .externalNativeBuild 15 | .cxx 16 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun Nov 12 18:18:44 CET 2023 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_installer.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_back.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_check.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_sort.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_start.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_file.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_export.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_about.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_clear.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_image.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_batch.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_bundle.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_template.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_classes.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_manifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_open.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/layout/recycle_view_xmleditor.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_add.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_folder.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout/recycle_view_textview.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_apps.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_select.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values-v35/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_export_file.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_edit.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_textview.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/src/full/res/values-zh-rCN/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | APK 浏览 & 编辑器 (AEE), 一个开源的可反编译apk的工具,支持查看已安装的应用 3 | APK 浏览 & 编辑器 (AEE) %s GitHub 项目地址: https://github.com/apk-editor/APK-Explorer-Editor/releases 4 | 欢迎来到APK 浏览&编辑器,一个强大的反编译APK的工具!\n\n注意:\nAPK 浏览&编辑器 严格遵守协议。点击“接受”按钮即代表您同意不使用此应用进行违法行为 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_key.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_check_circle.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_rate.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cancel.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_explore.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_save.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_projects.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout/progress_view.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_delete.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_expand.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_dots.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_reset.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_search.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_select_all.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_xml.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_sort_az.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_support.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_sort_time.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: sunilpaulmathew 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: sunilpaulmathew 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: ['https://www.paypal.me/menacherry'] 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_delete_file.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_res.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_translate.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_delete_folder.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_privacy.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | google { 4 | content { 5 | includeGroupByRegex("com\\.android.*") 6 | includeGroupByRegex("com\\.google.*") 7 | includeGroupByRegex("androidx.*") 8 | } 9 | } 10 | mavenCentral() 11 | gradlePluginPortal() 12 | } 13 | } 14 | dependencyResolutionManagement { 15 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 16 | repositories { 17 | google() 18 | mavenCentral() 19 | maven { 20 | url "https://jitpack.io" 21 | } 22 | } 23 | } 24 | 25 | include ':app' 26 | rootProject.name = "APK Editor" -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_search_folder.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/menu/navigation_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 12 | 16 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_share.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/32.txt: -------------------------------------------------------------------------------- 1 | * Resource Viewer: New option to export supported resources to storage. 2 | * Main: AEE now exports APKs and other resources to sdcard > Download > AEE. 3 | * Installer: Improved Split APK Installer — AEE now suggests the required split APKs automatically. 4 | * Quick Edits: Added support for split APKs and improved file compression when adding content. 5 | * App Icons: Added support for replacing app icons for many apps. 6 | * APK Explorer: Enhanced main view with new pages (e.g., App Info and Strings). 7 | * Text Editor: Fixed crashes in specific scenarios. 8 | * UI & Performance: Updated RecyclerView handling, improved progress dialogs, added new downloads icon, and general refinements. 9 | * Miscellaneous: Updated import translations and proguard rules for the apksig library. -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_donate.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_issue.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/play/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | APK Explorer 3 | APK Explorer (AEE), an open-source tool to explore the contents of an installed APK, is strictly made with an aim to inspect installed APK\'s. 4 | APK Explorer (AEE) %s can be obtained from Google Play: https://play.google.com/store/apps/details?id=com.apk.explorer 5 | Welcome to APK Explorer, a powerful tool to explore the contents of an installed APK!\n\nImportant\nAPK Explorer is strictly made with good intentions. Please do not use this tool for any kind of illegal or inappropriate activities. 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_keystoreverifier.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/recycle_view_stringviewer.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/services/InstallerService.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.services; 2 | 3 | import android.app.Service; 4 | import android.content.Intent; 5 | import android.content.pm.PackageInstaller; 6 | import android.os.IBinder; 7 | 8 | import in.sunilpaulmathew.sCommon.InstallerUtils.sInstallerUtils; 9 | 10 | /* 11 | * Created by APK Explorer & Editor on March 04, 2021 12 | */ 13 | public class InstallerService extends Service { 14 | 15 | @Override 16 | public int onStartCommand(Intent intent, int flags, int startId) { 17 | sInstallerUtils.setStatus(intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -999), intent, this); 18 | stopSelf(); 19 | return START_NOT_STICKY; 20 | } 21 | 22 | @Override 23 | public IBinder onBind(Intent intent) { 24 | return null; 25 | } 26 | } -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 17 | -------------------------------------------------------------------------------- /app/src/full/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | APK Explorer & Editor 3 | APK Explorer & Editor (AEE), an open-source tool to explore the contents of an installed APK, is strictly made with an aim to inspect installed APK\'s. 4 | APK Explorer & Editor (AEE) %s can be obtained from GitHub: https://github.com/apk-editor/APK-Explorer-Editor/releases 5 | Welcome to APK Explorer & Editor, a powerful tool to explore the contents of an installed APK!\n\nImportant\nAPK Explorer & Editor is strictly made with good intentions. Please do not use this tool for any kind of illegal or inappropriate activities. 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout/progress_layout.xml: -------------------------------------------------------------------------------- 1 | 11 | 12 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/recycle_view_apkdetails.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_android_app.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | 23 | -keep class com.apk.axml.** { *; } 24 | -keep class com.android.apksig.** { *; } 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/SerializableItems/QuickEditsItems.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils.SerializableItems; 2 | 3 | import java.io.Serializable; 4 | 5 | /* 6 | * Created by APK Explorer & Editor on March. 11, 2025 7 | */ 8 | public class QuickEditsItems implements Serializable { 9 | 10 | private boolean mEdited = false; 11 | private final String mName; 12 | private String mValue; 13 | 14 | public QuickEditsItems(String name, String value) { 15 | this.mName = name; 16 | this.mValue = value; 17 | } 18 | 19 | public boolean isEdited() { 20 | return mEdited; 21 | } 22 | 23 | public String getName() { 24 | return mName; 25 | } 26 | 27 | public String getValue() { 28 | return mValue; 29 | } 30 | 31 | public void setValue(String value) { 32 | mValue = value; 33 | mEdited = true; 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/menus/BundleOptionsMenu.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils.menus; 2 | 3 | import android.view.Menu; 4 | import android.view.View; 5 | 6 | import androidx.appcompat.widget.PopupMenu; 7 | 8 | import com.apk.editor.R; 9 | import com.apk.editor.utils.tasks.ShareBundle; 10 | 11 | /* 12 | * Created by APK Explorer & Editor on February 03, 2023 13 | */ 14 | public class BundleOptionsMenu extends PopupMenu { 15 | 16 | public BundleOptionsMenu(String bundlePath, View view) { 17 | super(view.getContext(), view); 18 | Menu menu = getMenu(); 19 | menu.add(Menu.NONE, 0, Menu.NONE, R.string.share); 20 | setOnMenuItemClickListener(item -> { 21 | if (item.getItemId() == 0) { 22 | new ShareBundle(bundlePath, view.getContext()).execute(); 23 | } 24 | return false; 25 | }); 26 | show(); 27 | } 28 | 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/dialogs/SignatureMismatchDialog.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils.dialogs; 2 | 3 | import android.content.Context; 4 | 5 | import com.apk.editor.R; 6 | import com.google.android.material.dialog.MaterialAlertDialogBuilder; 7 | 8 | import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils; 9 | 10 | /* 11 | * Created by APK Explorer & Editor on January 30, 2023 12 | */ 13 | public class SignatureMismatchDialog { 14 | 15 | public SignatureMismatchDialog(Context context) { 16 | new MaterialAlertDialogBuilder(context) 17 | .setIcon(R.mipmap.ic_launcher) 18 | .setTitle(R.string.app_name) 19 | .setMessage(context.getString(R.string.signature_warning)) 20 | .setPositiveButton(R.string.got_it, (dialog, id) -> 21 | sCommonUtils.saveBoolean("signature_warning", true, context)).show(); 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/dialogs/ClearAppSettingsDialog.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils.dialogs; 2 | 3 | import android.app.Activity; 4 | 5 | import com.apk.editor.R; 6 | import com.apk.editor.utils.tasks.ClearAppSettings; 7 | import com.google.android.material.dialog.MaterialAlertDialogBuilder; 8 | 9 | /* 10 | * Created by APK Explorer & Editor on January 30, 2023 11 | */ 12 | public class ClearAppSettingsDialog { 13 | 14 | public ClearAppSettingsDialog(Activity activity) { 15 | new MaterialAlertDialogBuilder(activity) 16 | .setIcon(R.mipmap.ic_launcher) 17 | .setTitle(R.string.warning) 18 | .setMessage(activity.getString(R.string.clear_cache_message)) 19 | .setNegativeButton(R.string.cancel, (dialog, id) -> { 20 | }) 21 | .setPositiveButton(R.string.delete, (dialog, id) -> 22 | new ClearAppSettings(activity).execute() 23 | ).show(); 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/dialogs/InvalidFileDialog.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils.dialogs; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.app.Activity; 5 | 6 | import com.apk.editor.R; 7 | import com.google.android.material.dialog.MaterialAlertDialogBuilder; 8 | 9 | /* 10 | * Created by APK Explorer & Editor on January 30, 2023 11 | */ 12 | public class InvalidFileDialog { 13 | 14 | @SuppressLint("StringFormatInvalid") 15 | public InvalidFileDialog(boolean exit, Activity activity) { 16 | new MaterialAlertDialogBuilder(activity) 17 | .setIcon(R.mipmap.ic_launcher) 18 | .setTitle(R.string.split_apk_installer) 19 | .setMessage(activity.getString(R.string.wrong_extension, ".apks/.apkm/.xapk")) 20 | .setCancelable(false) 21 | .setPositiveButton(R.string.cancel, (dialogInterface, i) -> { 22 | if (exit) { 23 | activity.finish(); 24 | } 25 | }).show(); 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/activities/StartActivity.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.activities; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | 6 | import androidx.appcompat.app.AppCompatActivity; 7 | 8 | import com.apk.editor.MainActivity; 9 | import com.apk.editor.R; 10 | import com.google.android.material.button.MaterialButton; 11 | 12 | import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils; 13 | 14 | /* 15 | * Created by APK Explorer & Editor on March 04, 2021 16 | */ 17 | public class StartActivity extends AppCompatActivity { 18 | 19 | @Override 20 | protected void onCreate(Bundle savedInstanceState) { 21 | super.onCreate(savedInstanceState); 22 | setContentView(R.layout.activity_start); 23 | 24 | MaterialButton mStart = findViewById(R.id.start); 25 | 26 | mStart.setOnClickListener(v -> { 27 | sCommonUtils.saveBoolean("welcome_message", true, this); 28 | Intent intent = new Intent(this, MainActivity.class); 29 | startActivity(intent); 30 | finish(); 31 | }); 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_apkexplorer.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | 12 | 13 | 14 | 19 | 20 | 21 | 27 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_build.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/fragments/CertificateFragment.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.fragments; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import androidx.annotation.Nullable; 9 | import androidx.fragment.app.Fragment; 10 | 11 | import com.apk.axml.APKParser; 12 | import com.apk.editor.R; 13 | import com.google.android.material.textview.MaterialTextView; 14 | 15 | /* 16 | * Created by APK Explorer & Editor on November 07, 2021 17 | */ 18 | public class CertificateFragment extends Fragment { 19 | 20 | @Nullable 21 | @Override 22 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 23 | View mRootView = inflater.inflate(R.layout.layout_textview, container, false); 24 | 25 | MaterialTextView mText = mRootView.findViewById(R.id.text); 26 | 27 | APKParser mAPKParser = new APKParser(); 28 | 29 | if (mAPKParser.getCertificate() != null) { 30 | try { 31 | mText.setText(mAPKParser.getCertificate()); 32 | } catch (Exception ignored) { 33 | } 34 | } 35 | 36 | return mRootView; 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/APKPicker.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils; 2 | 3 | import android.content.Context; 4 | import android.os.Build; 5 | 6 | import java.io.File; 7 | import java.util.Locale; 8 | 9 | /* 10 | * Created by APK Explorer & Editor on Sept. 22, 2025 11 | */ 12 | public class APKPicker { 13 | 14 | public static boolean isSelectedAPK(File file, Context context) { 15 | return file.getName().endsWith(".apk") && file.getName().contains(Build.SUPPORTED_ABIS[0].replace("-","_")) 16 | || file.getName().contains(Locale.getDefault().getLanguage()) || file.getName().contains("base.apk") 17 | || file.getName().contains(getScreenDensity(context)); 18 | } 19 | 20 | private static String getScreenDensity(Context context) { 21 | int screenDPI = context.getResources().getDisplayMetrics().densityDpi; 22 | if (screenDPI <= 140) { 23 | return "ldpi"; 24 | } else if (screenDPI <= 200) { 25 | return "mdpi"; 26 | } else if (screenDPI <= 280) { 27 | return "hdpi"; 28 | } else if (screenDPI <= 400) { 29 | return "xhdpi"; 30 | } else if (screenDPI <= 560) { 31 | return "xxhdpi"; 32 | } else { 33 | return "xxxhdpi"; 34 | } 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/PK8File.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils; 2 | 3 | import java.io.DataInputStream; 4 | import java.io.File; 5 | import java.io.FileInputStream; 6 | import java.io.IOException; 7 | import java.security.KeyFactory; 8 | import java.security.NoSuchAlgorithmException; 9 | import java.security.PrivateKey; 10 | import java.security.spec.InvalidKeySpecException; 11 | import java.security.spec.PKCS8EncodedKeySpec; 12 | 13 | /* 14 | * Created by APK Explorer & Editor on Oct 10, 2024 15 | */ 16 | public class PK8File extends File { 17 | 18 | public PK8File(File keyFile) { 19 | super(keyFile.toURI()); 20 | } 21 | 22 | public PrivateKey getPrivateKey() { 23 | try { 24 | FileInputStream fis = new FileInputStream(getAbsoluteFile()); 25 | DataInputStream dis = new DataInputStream(fis); 26 | byte[] keyBytes = new byte[(int) getAbsoluteFile().length()]; 27 | dis.readFully(keyBytes); 28 | dis.close(); 29 | PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes); 30 | KeyFactory kf = KeyFactory.getInstance("RSA"); 31 | return kf.generatePrivate(spec); 32 | } catch (IOException | InvalidKeySpecException | NoSuchAlgorithmException ignored) { 33 | return null; 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_book.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_imagepicker.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 18 | 19 | 26 | 27 | 34 | -------------------------------------------------------------------------------- /.github/workflows/android.yml: -------------------------------------------------------------------------------- 1 | name: Android CI 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | 17 | # Set Current Date As Env Variable 18 | - name: Set current date as env variable 19 | run: echo "date_today=$(date +'%Y-%m-%d')" >> $GITHUB_ENV 20 | 21 | # Set App Name As Env Variable 22 | - name: Set repository name as env variable 23 | run: echo "repository_name=AEE" >> $GITHUB_ENV 24 | 25 | - name: set up JDK 17 26 | uses: actions/setup-java@v4 27 | with: 28 | java-version: '17' 29 | distribution: 'temurin' 30 | cache: gradle 31 | 32 | - name: Grant execute permission for gradlew 33 | run: chmod +x ./gradlew 34 | 35 | # Run Tests Build 36 | - name: Run gradle tests 37 | run: ./gradlew test 38 | 39 | # Run Build Project 40 | - name: Build gradle project 41 | run: ./gradlew build 42 | 43 | # Create APK Release 44 | - name: Build apk release project (APK) - ${{ env.main_project_module }} module 45 | run: ./gradlew assemble 46 | 47 | # Upload Artifact Build 48 | - name: Upload APK Release - ${{ env.repository_name }} 49 | uses: actions/upload-artifact@v4 50 | with: 51 | name: ${{ env.repository_name }} - ${{ env.date_today }} - APK release generated 52 | path: app/build/outputs/apk/full/release/ -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/fragments/ManifestFragment.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.fragments; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import androidx.annotation.Nullable; 9 | import androidx.fragment.app.Fragment; 10 | import androidx.recyclerview.widget.LinearLayoutManager; 11 | import androidx.recyclerview.widget.RecyclerView; 12 | 13 | import com.apk.axml.APKParser; 14 | import com.apk.editor.R; 15 | import com.apk.editor.adapters.TextViewAdapter; 16 | import com.apk.editor.utils.APKExplorer; 17 | 18 | /* 19 | * Created by APK Explorer & Editor on November 07, 2021 20 | */ 21 | public class ManifestFragment extends Fragment { 22 | 23 | @Nullable 24 | @Override 25 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 26 | View mRootView = inflater.inflate(R.layout.layout_recyclerview, container, false); 27 | 28 | RecyclerView mRecyclerView = mRootView.findViewById(R.id.recycler_view); 29 | mRecyclerView.setLayoutManager(new LinearLayoutManager(requireActivity())); 30 | 31 | APKParser mAPKParser = new APKParser(); 32 | 33 | if (mAPKParser.getManifest() != null) { 34 | try { 35 | mRecyclerView.setAdapter(new TextViewAdapter(APKExplorer.getTextViewData(mAPKParser.getManifestAsString(), null, true, requireActivity()), null)); 36 | } catch (Exception ignored) { 37 | } 38 | } 39 | 40 | return mRootView; 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/interfaces/KeyStoreAliasChoiceDialog.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.interfaces; 2 | 3 | import android.content.Context; 4 | 5 | import com.apk.editor.R; 6 | import com.google.android.material.dialog.MaterialAlertDialogBuilder; 7 | 8 | /* 9 | * Created by APK Explorer & Editor on Oct 10, 2024 10 | */ 11 | public abstract class KeyStoreAliasChoiceDialog { 12 | 13 | private final int mPosition; 14 | private final MaterialAlertDialogBuilder mDialogBuilder; 15 | private final String mText; 16 | private final String[] mSingleChoiceItems; 17 | 18 | public KeyStoreAliasChoiceDialog(String text, String[] singleChoiceItems, int position, Context context) { 19 | this.mText = text; 20 | this.mSingleChoiceItems = singleChoiceItems; 21 | this.mPosition = position; 22 | this.mDialogBuilder = new MaterialAlertDialogBuilder(context); 23 | } 24 | 25 | private void startDialog() { 26 | if (mText != null) { 27 | mDialogBuilder.setTitle(mText); 28 | } 29 | mDialogBuilder.setNegativeButton(R.string.cancel, (dialog, id) -> { 30 | }); 31 | mDialogBuilder.setPositiveButton(R.string.select, (dialog, id) -> onItemSelected(mPosition) 32 | ); 33 | mDialogBuilder.setSingleChoiceItems(mSingleChoiceItems, mPosition, (dialog, itemPosition) -> { 34 | onItemSelected(itemPosition); 35 | dialog.dismiss(); 36 | }).show(); 37 | } 38 | 39 | public void show() { 40 | startDialog(); 41 | } 42 | 43 | public abstract void onItemSelected(int position); 44 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_settings.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | 15 | 24 | 25 | 31 | 32 | 33 | 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/dialogs/BatchSigningOptionsDialog.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils.dialogs; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | 7 | import com.apk.editor.R; 8 | import com.apk.editor.activities.APKSignActivity; 9 | import com.apk.editor.utils.tasks.ResignAPKs; 10 | import com.apk.editor.utils.tasks.ResignBatchAPKs; 11 | 12 | import java.util.List; 13 | 14 | import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils; 15 | import in.sunilpaulmathew.sCommon.Dialog.sSingleItemDialog; 16 | 17 | /* 18 | * Created by APK Explorer & Editor on January 24, 2025 19 | */ 20 | public class BatchSigningOptionsDialog extends sSingleItemDialog { 21 | 22 | private final Context mContext; 23 | private final List mPackageNames; 24 | 25 | public BatchSigningOptionsDialog(List packageNames, Context context) { 26 | super(0, null, new String[] { 27 | context.getString(R.string.signing_default), 28 | context.getString(R.string.signing_custom) 29 | }, context); 30 | mPackageNames = packageNames; 31 | mContext = context; 32 | } 33 | 34 | @Override 35 | public void onItemSelected(int position) { 36 | sCommonUtils.saveBoolean("firstSigning", true, mContext); 37 | if (position == 0) { 38 | new ResignBatchAPKs(mPackageNames, (Activity) mContext).execute(); 39 | } else { 40 | Intent signing = new Intent(mContext, APKSignActivity.class); 41 | mContext.startActivity(signing); 42 | } 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_resviewer.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 13 | 14 | 25 | 26 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/adapters/APKDetailsAdapter.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.adapters; 2 | 3 | import android.view.LayoutInflater; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | 7 | import androidx.annotation.NonNull; 8 | import androidx.recyclerview.widget.RecyclerView; 9 | 10 | import com.apk.editor.R; 11 | import com.google.android.material.textview.MaterialTextView; 12 | 13 | import java.util.List; 14 | 15 | /* 16 | * Created by APK Explorer & Editor on November 07, 2021 17 | */ 18 | public class APKDetailsAdapter extends RecyclerView.Adapter { 19 | 20 | private static List data; 21 | 22 | public APKDetailsAdapter(List data) { 23 | APKDetailsAdapter.data = data; 24 | } 25 | 26 | @NonNull 27 | @Override 28 | public APKDetailsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 29 | View rowItem = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_view_apkdetails, parent, false); 30 | return new APKDetailsAdapter.ViewHolder(rowItem); 31 | } 32 | 33 | @Override 34 | public void onBindViewHolder(@NonNull APKDetailsAdapter.ViewHolder holder, int position) { 35 | holder.mText.setText(data.get(position)); 36 | } 37 | 38 | @Override 39 | public int getItemCount() { 40 | return data.size(); 41 | } 42 | 43 | public static class ViewHolder extends RecyclerView.ViewHolder { 44 | private final MaterialTextView mText; 45 | 46 | public ViewHolder(View view) { 47 | super(view); 48 | this.mText = view.findViewById(R.id.text); 49 | } 50 | } 51 | 52 | } -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/dialogs/SigningOptionsDialog.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils.dialogs; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | 7 | import com.apk.editor.R; 8 | import com.apk.editor.activities.APKSignActivity; 9 | import com.apk.editor.utils.tasks.ResignAPKs; 10 | 11 | import java.util.List; 12 | 13 | import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils; 14 | import in.sunilpaulmathew.sCommon.Dialog.sSingleItemDialog; 15 | 16 | /* 17 | * Created by APK Explorer & Editor on January 30, 2023 18 | */ 19 | public class SigningOptionsDialog extends sSingleItemDialog { 20 | 21 | private final Context mContext; 22 | private final boolean mExit; 23 | private final List mAPKs; 24 | private final String mPackageName; 25 | 26 | public SigningOptionsDialog(String packageName, List apks, boolean exit, Context context) { 27 | super(0, null, new String[] { 28 | context.getString(R.string.signing_default), 29 | context.getString(R.string.signing_custom) 30 | }, context); 31 | mPackageName = packageName; 32 | mAPKs = apks; 33 | mExit = exit; 34 | mContext = context; 35 | } 36 | 37 | @Override 38 | public void onItemSelected(int position) { 39 | sCommonUtils.saveBoolean("firstSigning", true, mContext); 40 | if (position == 0) { 41 | new ResignAPKs(mPackageName,mAPKs, false, mExit, (Activity) mContext).execute(); 42 | } else { 43 | Intent signing = new Intent(mContext, APKSignActivity.class); 44 | mContext.startActivity(signing); 45 | } 46 | } 47 | 48 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/recycle_view_batch_options.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 18 | 19 | 23 | 24 | 30 | 31 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/tasks/DeleteProject.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils.tasks; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.app.Activity; 5 | 6 | import com.apk.editor.R; 7 | import com.apk.editor.utils.APKExplorer; 8 | import com.apk.editor.utils.dialogs.ProgressDialog; 9 | 10 | import java.io.File; 11 | 12 | import in.sunilpaulmathew.sCommon.CommonUtils.sExecutor; 13 | import in.sunilpaulmathew.sCommon.FileUtils.sFileUtils; 14 | 15 | /* 16 | * Created by APK Explorer & Editor on January 28, 2023 17 | */ 18 | public class DeleteProject extends sExecutor { 19 | 20 | private final Activity mActivity; 21 | private final boolean mSetSuccess; 22 | private final File mFile; 23 | private ProgressDialog mProgressDialog; 24 | 25 | public DeleteProject(File file, Activity activity, boolean setSuccess) { 26 | mFile = file; 27 | mActivity = activity; 28 | mSetSuccess = setSuccess; 29 | } 30 | 31 | @SuppressLint("StringFormatInvalid") 32 | @Override 33 | public void onPreExecute() { 34 | mProgressDialog = new ProgressDialog(mActivity); 35 | mProgressDialog.setTitle(mActivity.getString(R.string.deleting, mFile.getName())); 36 | mProgressDialog.setIcon(R.mipmap.ic_launcher); 37 | mProgressDialog.setIndeterminate(true); 38 | mProgressDialog.show(); 39 | } 40 | 41 | @Override 42 | public void doInBackground() { 43 | sFileUtils.delete(mFile); 44 | } 45 | 46 | @Override 47 | public void onPostExecute() { 48 | try { 49 | mProgressDialog.dismiss(); 50 | } catch (IllegalArgumentException ignored) { 51 | } 52 | if (mSetSuccess) { 53 | APKExplorer.setSuccessIntent(true, mActivity); 54 | } 55 | } 56 | 57 | } -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/fragments/APKDetailsFragment.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.fragments; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import androidx.annotation.Nullable; 9 | import androidx.fragment.app.Fragment; 10 | import androidx.recyclerview.widget.LinearLayoutManager; 11 | import androidx.recyclerview.widget.RecyclerView; 12 | 13 | import com.apk.editor.R; 14 | import com.apk.editor.adapters.APKDetailsAdapter; 15 | import com.apk.editor.utils.ExternalAPKData; 16 | 17 | import in.sunilpaulmathew.sCommon.CommonUtils.sExecutor; 18 | 19 | /* 20 | * Created by APK Explorer & Editor on November 07, 2021 21 | */ 22 | public class APKDetailsFragment extends Fragment { 23 | 24 | @Nullable 25 | @Override 26 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 27 | View mRootView = inflater.inflate(R.layout.layout_recyclerview, container, false); 28 | 29 | RecyclerView mRecyclerView = mRootView.findViewById(R.id.recycler_view); 30 | mRecyclerView.setLayoutManager(new LinearLayoutManager(requireActivity())); 31 | 32 | new sExecutor() { 33 | private APKDetailsAdapter mAdapter; 34 | @Override 35 | public void onPreExecute() { 36 | } 37 | 38 | @Override 39 | public void doInBackground() { 40 | mAdapter = new APKDetailsAdapter(ExternalAPKData.getData(requireActivity())); 41 | } 42 | 43 | @Override 44 | public void onPostExecute() { 45 | mRecyclerView.setAdapter(mAdapter); 46 | 47 | } 48 | }.execute(); 49 | 50 | return mRootView; 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/recycle_view_exploreinfo.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 18 | 19 | 29 | 30 | 40 | 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/SerializableItems/APKPickerItems.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils.SerializableItems; 2 | 3 | import android.content.Context; 4 | import android.graphics.drawable.Drawable; 5 | 6 | import com.apk.editor.R; 7 | 8 | import java.io.File; 9 | import java.io.Serializable; 10 | 11 | import in.sunilpaulmathew.sCommon.APKUtils.sAPKUtils; 12 | import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils; 13 | 14 | /* 15 | * Created by APK Explorer & Editor on Sept. 22, 2025 16 | */ 17 | public class APKPickerItems implements Serializable { 18 | 19 | private boolean selected; 20 | private final File apkFile; 21 | 22 | public APKPickerItems(File apkFile, boolean selected) { 23 | this.apkFile = apkFile; 24 | this.selected = selected; 25 | } 26 | 27 | public boolean isSelected() { 28 | return apkFile.exists() && apkFile.isFile() && apkFile.getName().endsWith(".apk") && selected; 29 | } 30 | 31 | public Drawable getImageDrawable(Context context) { 32 | if (sAPKUtils.getAPKIcon(apkFile.getAbsolutePath(), context) != null) { 33 | return sAPKUtils.getAPKIcon(apkFile.getAbsolutePath(), context); 34 | } else { 35 | return sCommonUtils.getDrawable(R.drawable.ic_android_app, context); 36 | } 37 | } 38 | 39 | public String getAPKName() { 40 | return apkFile.getName(); 41 | } 42 | 43 | public String getAPKSize() { 44 | return sAPKUtils.getAPKSize(apkFile.length()); 45 | } 46 | 47 | public String getPackageName(Context context) { 48 | return sAPKUtils.getPackageName(apkFile.getAbsolutePath(), context); 49 | } 50 | 51 | public String getAPKPath() { 52 | return apkFile.getAbsolutePath(); 53 | } 54 | 55 | public void isSelected(boolean b) { 56 | selected = b; 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/interfaces/KeyStoreVerifierInterface.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.interfaces; 2 | 3 | import android.app.Activity; 4 | import android.text.Editable; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | 8 | import com.apk.editor.R; 9 | import com.google.android.material.dialog.MaterialAlertDialogBuilder; 10 | import com.google.android.material.textfield.MaterialAutoCompleteTextView; 11 | 12 | /* 13 | * Created by APK Explorer & Editor on Oct 10, 2024 14 | */ 15 | public abstract class KeyStoreVerifierInterface { 16 | 17 | private final Activity mActivity; 18 | private final MaterialAlertDialogBuilder mDialogBuilder; 19 | private final String mText; 20 | 21 | public KeyStoreVerifierInterface(String text, Activity activity) { 22 | this.mText = text; 23 | this.mActivity = activity; 24 | this.mDialogBuilder = new MaterialAlertDialogBuilder(activity); 25 | } 26 | 27 | private void startDialog() { 28 | LayoutInflater mLayoutInflator = LayoutInflater.from(mActivity); 29 | View layout = mLayoutInflator.inflate(R.layout.layout_keystoreverifier, null); 30 | MaterialAutoCompleteTextView editText = layout.findViewById(R.id.text); 31 | 32 | editText.setSingleLine(true); 33 | editText.requestFocus(); 34 | 35 | mDialogBuilder.setView(layout); 36 | if (mText != null) { 37 | mDialogBuilder.setTitle(mText); 38 | } 39 | mDialogBuilder.setNegativeButton(R.string.cancel, (dialog, id) -> { 40 | }); 41 | mDialogBuilder.setPositiveButton(R.string.ok, (dialog, id) -> 42 | positiveButtonLister(editText.getText()) 43 | ).show(); 44 | } 45 | 46 | public void show() { 47 | startDialog(); 48 | } 49 | 50 | public abstract void positiveButtonLister(Editable s); 51 | 52 | } -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/fragments/PermissionsFragment.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.fragments; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import androidx.annotation.Nullable; 9 | import androidx.fragment.app.Fragment; 10 | 11 | import com.apk.axml.APKParser; 12 | import com.apk.editor.R; 13 | import com.google.android.material.textview.MaterialTextView; 14 | 15 | import in.sunilpaulmathew.sCommon.PermissionUtils.sPermissionUtils; 16 | 17 | /* 18 | * Created by APK Explorer & Editor on November 07, 2021 19 | */ 20 | public class PermissionsFragment extends Fragment { 21 | 22 | @Nullable 23 | @Override 24 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 25 | View mRootView = inflater.inflate(R.layout.layout_textview, container, false); 26 | 27 | MaterialTextView mText = mRootView.findViewById(R.id.text); 28 | 29 | APKParser mAPKParser = new APKParser(); 30 | 31 | if (mAPKParser.getPermissions() != null) { 32 | try { 33 | StringBuilder sb = new StringBuilder(); 34 | for (String permission : mAPKParser.getPermissions()) { 35 | sb.append(getNameAdjusted(permission)).append("\n").append(sPermissionUtils.getDescription(getNameAdjusted( 36 | permission.replace("android.permission.","")), requireActivity())).append("\n\n"); 37 | } 38 | mText.setText(sb.toString()); 39 | } catch (Exception ignored) { 40 | } 41 | } 42 | 43 | return mRootView; 44 | } 45 | 46 | private String getNameAdjusted(String string) { 47 | if (string.endsWith("/>")) { 48 | return string.replace("/>", ""); 49 | } 50 | return string; 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /app/src/full/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 25 | 26 | 28 | 29 | 31 | 32 | 35 | 36 | 38 | 39 | 41 | 42 | -------------------------------------------------------------------------------- /app/src/main/res/layout/recycle_view_about.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 17 | 18 | 25 | 26 | 34 | 35 | 41 | 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/tasks/ShareBundle.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils.tasks; 2 | 3 | import android.content.Context; 4 | import android.os.Build; 5 | 6 | import androidx.annotation.RequiresApi; 7 | 8 | import com.apk.editor.R; 9 | import com.apk.editor.utils.APKData; 10 | import com.apk.editor.utils.APKEditorUtils; 11 | import com.apk.editor.utils.dialogs.ProgressDialog; 12 | 13 | import java.io.File; 14 | 15 | import in.sunilpaulmathew.sCommon.CommonUtils.sExecutor; 16 | import in.sunilpaulmathew.sCommon.FileUtils.sFileUtils; 17 | 18 | /* 19 | * Created by APK Explorer & Editor on January 28, 2023 20 | */ 21 | public class ShareBundle extends sExecutor { 22 | 23 | private final Context mContext; 24 | private File mFile; 25 | private ProgressDialog mProgressDialog; 26 | private final String mPath; 27 | 28 | public ShareBundle(String path, Context context) { 29 | mPath = path; 30 | mContext = context; 31 | } 32 | 33 | @Override 34 | public void onPreExecute() { 35 | mProgressDialog = new ProgressDialog(mContext); 36 | mProgressDialog.setTitle(mContext.getString(R.string.preparing_bundle)); 37 | mProgressDialog.setIcon(R.mipmap.ic_launcher); 38 | mProgressDialog.setIndeterminate(true); 39 | mProgressDialog.show(); 40 | mFile = new File(mContext.getExternalFilesDir("APK"), new File(mPath).getName() + ".xapk"); 41 | } 42 | 43 | @RequiresApi(api = Build.VERSION_CODES.Q) 44 | @Override 45 | public void doInBackground() { 46 | if (mFile.exists()) { 47 | sFileUtils.delete(mFile); 48 | } 49 | APKEditorUtils.zip(new File(mPath), mFile); 50 | } 51 | 52 | @Override 53 | public void onPostExecute() { 54 | try { 55 | mProgressDialog.dismiss(); 56 | } catch (IllegalArgumentException ignored) { 57 | } 58 | APKData.shareFile(mFile, "application/zip", mContext); 59 | } 60 | 61 | } -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/adapters/StringViewAdapter.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.adapters; 2 | 3 | import android.view.LayoutInflater; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | 7 | import androidx.annotation.NonNull; 8 | import androidx.recyclerview.widget.RecyclerView; 9 | 10 | import com.apk.axml.serializableItems.ResEntry; 11 | import com.apk.editor.R; 12 | import com.google.android.material.textfield.TextInputEditText; 13 | import com.google.android.material.textfield.TextInputLayout; 14 | 15 | import java.util.List; 16 | 17 | /* 18 | * Created by APK Explorer & Editor on Sept. 25, 2025 19 | */ 20 | public class StringViewAdapter extends RecyclerView.Adapter { 21 | 22 | private final List data; 23 | 24 | public StringViewAdapter(List data) { 25 | this.data = data; 26 | } 27 | 28 | @NonNull 29 | @Override 30 | public StringViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 31 | View rowItem = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_view_stringviewer, parent, false); 32 | return new StringViewAdapter.ViewHolder(rowItem); 33 | } 34 | 35 | @Override 36 | public void onBindViewHolder(@NonNull StringViewAdapter.ViewHolder holder, int position) { 37 | holder.mTitle.setHint(data.get(position).getName()); 38 | holder.mValue.setText(data.get(position).getValue()); 39 | } 40 | 41 | @Override 42 | public int getItemCount() { 43 | return data.size(); 44 | } 45 | 46 | public static class ViewHolder extends RecyclerView.ViewHolder { 47 | private final TextInputEditText mValue; 48 | private final TextInputLayout mTitle; 49 | 50 | public ViewHolder(View view) { 51 | super(view); 52 | this.mTitle = view.findViewById(R.id.title); 53 | this.mValue = view.findViewById(R.id.value); 54 | } 55 | } 56 | 57 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_quickedits.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 22 | 23 | 31 | 32 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/res/layout/permission_layout.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 22 | 23 | 30 | 31 | 41 | 42 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_batchoptions.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 19 | 20 | 33 | 34 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /privacy-policy.md: -------------------------------------------------------------------------------- 1 | # Privacy Policy 2 | 3 | ## General 4 | 5 | APK Explorer (AEE) is developed by one main developer with a significant amount of code taken from a number of other open-source projects. This Privacy Policy (Policy) explains how the developer treats the privacy of users. This policy applies to the original version of the application published by the developer exclusively on [Google Play](https://play.google.com/store/apps/details?id=com.apk.explorer). 6 | 7 | ## Policy 8 | 9 | The developer of AEE does not collect, store or share any personal information about the users. The identities of the users are completely unknown. If any personal information about a user is ever received, it will not be disclosed or shared with a third-party. 10 | 11 | ## Permissions explained 12 | 13 | AEE is made with a special focus on the privacy of end-users. As a result, AEE only demands very necessary permissions to offer the promised features to the users and are explained below.

MANAGE_EXTERNAL_STORAGE
Necessary to export APK's, and other resources to device storage, pick APK's & app bundles for Split APK Installer, etc (Android 11 and above).

REQUEST_INSTALL_PACKAGES
Necessary to install APK, Split APK's, and app bundles.

WRITE_EXTERNAL_STORAGE
Necessary to export APK's, and other resources to device storage, pick APK's & app bundles for Split APK Installer, etc (Android 10 and above).

QUERY_ALL_PACKAGES
Necessary permission to get most applications visible in Android 11 and above. 14 | 15 | ## Changes 16 | 17 | If the above-written Policy ever changes, the "Last updated" date provided on the bottom of this page will be updated. The Policy may change from time to time, so please be sure to check back periodically. 18 | 19 | ## Contact developer 20 | 21 | If you have any questions about this Privacy Policy, please don't hesitate to contact the developer at apkeditor@protonmail.com 22 | 23 | ### Last updated 24 | _March 15, 2021_ 25 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/full_description.txt: -------------------------------------------------------------------------------- 1 | APK Explorer & Editor (AEE) includes a set of open-source tools mainly designed to explore the contents of an installed application on an Android device. Additionally, AEE offers a feature-rich APK/Split APK's/App bundle installer which allows users to pick and install files from device storage. Please Note: This is the full version of AEE. The Google Play version lacks editing capabilities as well as features such as APK/App Bundle signing. 2 | 3 | Features 4 | 5 | * A beautifully designed list view of installed applications. 6 | * Explore an installed application or APK file picked from the device storage and navigate through its contents. 7 | * Export and easily manage (install, share etc.) APK's/Split APK's into device storage. 8 | * Includes a feature-rich APK/Split APK/App bundle installer (easily pick and install files from device storage) 9 | * Easily extract app icons by single-clicking on them. 10 | * Provides basic information about important resource files. 11 | * View graphics, texts, binary XML, and many more. 12 | * Save/Export individual resource files to device storage. 13 | * Edit text/binary XML files using an in-built text editor (still, a bit buggy when working with too huge APK's). 14 | * Delete or replaces resources. 15 | * Assemble modified smali files into new classes (.dex). 16 | * Decode and view the contents of "resources.arsc". 17 | * Create signed APK's/App Bundles after the above-mentioned processes. 18 | * Resign APK's/bundles with AEE custom key. 19 | * Elegantly designed user interface with an auto-dark/light theme. 20 | * A lot more. 21 | 22 | Translations 23 | 24 | Please help me to translate this application via POEditor. You may also translate after downloading the original language string available GitHub. 25 | 26 | Documentation 27 | 28 | - How-To -------------------------------------------------------------------------------- /fastlane/metadata/android/pt-BR/full_description.txt: -------------------------------------------------------------------------------- 1 | APK Explorador & Editor (AEE) inclui um conjunto de ferramentas de software livre usado principalmente para explorar o conteúdo de aplicativos instalados nos dispositivos de Android. Além disso, o AEE oferece um instalador de APKs/pacotes divididos que permite ao usuário escolher e instalar os arquivos do armazenamento. Por favor, considere que: esta é a versão completa do AEE. A versão do Google Play não possui recursos de edição nem a funcionalidade de assinaturas do APK/Pacote de Apps. 2 | 3 | 4 | Funcionalidades 5 | 6 | * Lindamente feita lista de apps instalados 7 | * Explore e navegue através do conteúdo de apps instalados. 8 | * Exportar e facilmente gerenciar (instalar, compartilhar, etc.) APK/Pacote dividido no armazenamento de dispositivo. 9 | * Inclui um instalador de pacotes divididos de APK (facilmente escolha e instale os arquivos do armazenamento). 10 | * Extraia facilmente um ícone de aplicativo com um único clique. 11 | * Fornece informações básicas sobre recursos importantes de arquivos. 12 | * Visualiza gráficos, textos, XML binário e muito mais. 13 | * Salvar/Exportar recursos de arquivos individuais para o armazenamento do dispositivo. 14 | * Fornece possibilidade de editar arquivos XML de texto/binário usando um editor de texto próprio (desabilitado por padrão no menu em Configurações). 15 | * Exclua ou substitua os recursos. 16 | * Crie APK/Pacotes de Apps assinados após os processos acima mencionados. 17 | * Reassinar APKs/Pacotes com a chave personalizada do AEE. 18 | * Interface de usuário lindamente desenvolvida com um tema escuro e claro. 19 | * E muito mais. 20 | 21 | 22 | Traduções 23 | 24 | Por favor, ajude a traduzir este App no sitePOEditor. Você também pode traduzir após baixar o conjunto de frases em idioma original viaGitHub. 25 | 26 | Documentação 27 | 28 | - Como fazer 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/tasks/ClearAppSettings.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils.tasks; 2 | 3 | import android.app.Activity; 4 | 5 | import com.apk.editor.R; 6 | import com.apk.editor.utils.APKEditorUtils; 7 | import com.apk.editor.utils.AppSettings; 8 | import com.apk.editor.utils.dialogs.ProgressDialog; 9 | 10 | import java.io.File; 11 | 12 | import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils; 13 | import in.sunilpaulmathew.sCommon.CommonUtils.sExecutor; 14 | import in.sunilpaulmathew.sCommon.FileUtils.sFileUtils; 15 | 16 | /* 17 | * Created by APK Explorer & Editor on January 28, 2023 18 | */ 19 | public class ClearAppSettings extends sExecutor { 20 | 21 | private final Activity mActivity; 22 | private ProgressDialog mProgressDialog; 23 | 24 | public ClearAppSettings(Activity activity) { 25 | mActivity = activity; 26 | } 27 | 28 | @Override 29 | public void onPreExecute() { 30 | mProgressDialog = new ProgressDialog(mActivity); 31 | mProgressDialog.setTitle(mActivity.getString(R.string.clearing_cache_message)); 32 | mProgressDialog.setIcon(R.mipmap.ic_launcher); 33 | mProgressDialog.setIndeterminate(true); 34 | mProgressDialog.show(); 35 | } 36 | 37 | @Override 38 | public void doInBackground() { 39 | sFileUtils.delete(mActivity.getCacheDir()); 40 | sFileUtils.delete(mActivity.getFilesDir()); 41 | if (APKEditorUtils.isFullVersion(mActivity) && AppSettings.isCustomKey(mActivity)) { 42 | sCommonUtils.saveString("PrivateKey", null, mActivity); 43 | sFileUtils.delete(new File(mActivity.getFilesDir(), "signing/APKEditor.pk8")); 44 | sCommonUtils.saveString("X509Certificate", null, mActivity); 45 | sFileUtils.delete(new File(mActivity.getFilesDir(), "signing/APKEditorCert")); 46 | } 47 | } 48 | 49 | @Override 50 | public void onPostExecute() { 51 | try { 52 | mProgressDialog.dismiss(); 53 | } catch (IllegalArgumentException ignored) { 54 | } 55 | mActivity.finish(); 56 | } 57 | 58 | } -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/tasks/TransferApps.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils.tasks; 2 | 3 | import android.content.Context; 4 | import android.os.Environment; 5 | 6 | import com.apk.editor.R; 7 | import com.apk.editor.utils.dialogs.ProgressDialog; 8 | 9 | import java.io.File; 10 | import java.util.Objects; 11 | 12 | import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils; 13 | import in.sunilpaulmathew.sCommon.CommonUtils.sExecutor; 14 | import in.sunilpaulmathew.sCommon.FileUtils.sFileUtils; 15 | 16 | /* 17 | * Created by APK Explorer & Editor on January 28, 2023 18 | */ 19 | public class TransferApps extends sExecutor { 20 | 21 | private final Context mContext; 22 | private File mSourceFile; 23 | private ProgressDialog mProgressDialog; 24 | 25 | public TransferApps(Context context) { 26 | mContext = context; 27 | } 28 | 29 | @Override 30 | public void onPreExecute() { 31 | mProgressDialog = new ProgressDialog(mContext); 32 | mProgressDialog.setTitle(mContext.getString(R.string.transfer_exported_apk)); 33 | mProgressDialog.setIcon(R.mipmap.ic_launcher); 34 | mProgressDialog.setIndeterminate(true); 35 | mProgressDialog.show(); 36 | } 37 | 38 | @Override 39 | public void doInBackground() { 40 | File destDir; 41 | if (sCommonUtils.getString("exportAPKsPath", "externalFiles", mContext).equals("internalStorage")) { 42 | mSourceFile = mContext.getExternalFilesDir(""); 43 | destDir = new File(Environment.getExternalStorageDirectory(), "/AEE/exportedAPKs"); 44 | } else { 45 | destDir = mContext.getExternalFilesDir(""); 46 | mSourceFile = new File(Environment.getExternalStorageDirectory(), "/AEE/exportedAPKs"); 47 | } 48 | sFileUtils.copyDir(mSourceFile, Objects.requireNonNull(destDir)); 49 | } 50 | 51 | @Override 52 | public void onPostExecute() { 53 | sFileUtils.delete(mSourceFile); 54 | try { 55 | mProgressDialog.dismiss(); 56 | } catch (IllegalArgumentException ignored) { 57 | } 58 | } 59 | 60 | } -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | apksigVersion = "8.13.0" 3 | aXMLVersion = "42ad3160e5" 4 | baksmaliVersion = "2.5.2" 5 | crashreporterVersion = "6b6c74abaa" 6 | documentfileVersion = "1.1.0" 7 | sCommonVersion = "0a9f4f410f" 8 | agpVersion = "8.13.0" 9 | materialVersion = "1.13.0" 10 | zip4jVersion = "2.11.5" 11 | 12 | [libraries] 13 | apksig = { module = "com.android.tools.build:apksig", version.ref = "apksigVersion" } 14 | axml = { module = "com.github.apk-editor:aXML", version.ref = "aXMLVersion" } 15 | adapters = { module = "com.github.sunilpaulmathew.sCommon:adapters", version.ref = "sCommonVersion" } 16 | apkutils = { module = "com.github.sunilpaulmathew.sCommon:apkutils", version.ref = "sCommonVersion" } 17 | baksmali = { module = "org.smali:baksmali", version.ref = "baksmaliVersion" } 18 | crashReporter = { module = "com.github.sunilpaulmathew:CrashReporter", version.ref = "crashreporterVersion" } 19 | credits = { module = "com.github.sunilpaulmathew.sCommon:credits", version.ref = "sCommonVersion" } 20 | documentfile = { module = "androidx.documentfile:documentfile", version.ref = "documentfileVersion" } 21 | fileutils = { module = "com.github.sunilpaulmathew.sCommon:fileutils", version.ref = "sCommonVersion" } 22 | installerutils = { module = "com.github.sunilpaulmathew.sCommon:installerutils", version.ref = "sCommonVersion" } 23 | packageutils = { module = "com.github.sunilpaulmathew.sCommon:packageutils", version.ref = "sCommonVersion" } 24 | permissionutils = { module = "com.github.sunilpaulmathew.sCommon:permissionutils", version.ref = "sCommonVersion" } 25 | smali = { module = "org.smali:smali", version.ref = "baksmaliVersion" } 26 | themeutils = { module = "com.github.sunilpaulmathew.sCommon:themeutils", version.ref = "sCommonVersion" } 27 | translatorutils = { module = "com.github.sunilpaulmathew.sCommon:translatorutils", version.ref = "sCommonVersion" } 28 | material = { group = "com.google.android.material", name = "material", version.ref = "materialVersion" } 29 | zip4j = { module = "net.lingala.zip4j:zip4j", version.ref = "zip4jVersion" } 30 | 31 | [plugins] 32 | androidApplication = { id = "com.android.application", version.ref = "agpVersion" } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_start.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 14 | 15 | 22 | 23 | 32 | 33 | 48 | 49 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.androidApplication) 3 | } 4 | 5 | android { 6 | dependenciesInfo { 7 | // Disables dependency metadata when building APKs. 8 | includeInApk = false 9 | // Disables dependency metadata when building Android App Bundles. 10 | includeInBundle = false 11 | } 12 | 13 | compileSdk 36 14 | namespace 'com.apk.editor' 15 | 16 | defaultConfig { 17 | minSdkVersion 23 18 | targetSdk 35 19 | versionCode 32 20 | versionName "v0.32" 21 | vectorDrawables.useSupportLibrary = true 22 | testFunctionalTest = false 23 | testHandleProfiling = false 24 | 25 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 26 | } 27 | 28 | buildTypes { 29 | debug { 30 | applicationIdSuffix '.debug' 31 | } 32 | 33 | release { 34 | minifyEnabled true 35 | shrinkResources true 36 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 37 | } 38 | } 39 | 40 | buildFeatures { 41 | buildConfig = true 42 | } 43 | 44 | flavorDimensions.add("release") 45 | productFlavors { 46 | play { 47 | applicationId "com.apk.explorer" 48 | dimension "release" 49 | } 50 | full { 51 | applicationId "com.apk.editor" 52 | dimension "release" 53 | } 54 | } 55 | lint { 56 | abortOnError false 57 | } 58 | 59 | } 60 | 61 | dependencies { 62 | implementation libs.apksig 63 | implementation libs.axml 64 | implementation libs.crashReporter 65 | 66 | implementation libs.apkutils 67 | implementation libs.adapters 68 | implementation libs.credits 69 | implementation libs.fileutils 70 | implementation libs.installerutils 71 | implementation libs.packageutils 72 | implementation libs.permissionutils 73 | implementation libs.themeutils 74 | implementation libs.translatorutils 75 | 76 | implementation libs.documentfile 77 | implementation libs.material 78 | implementation libs.zip4j 79 | implementation libs.baksmali 80 | implementation libs.smali 81 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | 12 | 17 | 18 | 19 | 24 | 25 | 34 | 35 | 49 | 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/adapters/ExploredInfoAdapter.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.adapters; 2 | 3 | import static android.view.View.GONE; 4 | import static android.view.View.VISIBLE; 5 | 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | import androidx.annotation.NonNull; 11 | import androidx.recyclerview.widget.RecyclerView; 12 | 13 | import com.apk.editor.R; 14 | import com.google.android.material.textview.MaterialTextView; 15 | 16 | import java.util.HashMap; 17 | import java.util.List; 18 | 19 | /* 20 | * Created by APK Explorer & Editor on Sept. 25, 2025 21 | */ 22 | public class ExploredInfoAdapter extends RecyclerView.Adapter { 23 | 24 | private final List> data; 25 | 26 | public ExploredInfoAdapter(List> data) { 27 | this.data = data; 28 | } 29 | 30 | @NonNull 31 | @Override 32 | public ExploredInfoAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 33 | View rowItem = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_view_exploreinfo, parent, false); 34 | return new ExploredInfoAdapter.ViewHolder(rowItem); 35 | } 36 | 37 | @Override 38 | public void onBindViewHolder(@NonNull ExploredInfoAdapter.ViewHolder holder, int position) { 39 | holder.mTitle.setText(data.get(position).get("title")); 40 | if (data.get(position).get("description") != null) { 41 | holder.mDescription.setText(data.get(position).get("description")); 42 | holder.mDescription.setVisibility(VISIBLE); 43 | } else { 44 | holder.mDescription.setVisibility(GONE); 45 | } 46 | } 47 | 48 | @Override 49 | public int getItemCount() { 50 | return data.size(); 51 | } 52 | 53 | public static class ViewHolder extends RecyclerView.ViewHolder { 54 | private final MaterialTextView mTitle, mDescription; 55 | 56 | public ViewHolder(View view) { 57 | super(view); 58 | this.mTitle = view.findViewById(R.id.title); 59 | this.mDescription = view.findViewById(R.id.description); 60 | } 61 | } 62 | 63 | } -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/adapters/TextViewAdapter.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.adapters; 2 | 3 | import android.graphics.Color; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import androidx.annotation.NonNull; 9 | import androidx.recyclerview.widget.RecyclerView; 10 | 11 | import com.apk.editor.R; 12 | import com.apk.editor.utils.APKEditorUtils; 13 | import com.apk.editor.utils.Common; 14 | import com.google.android.material.textview.MaterialTextView; 15 | 16 | import java.util.List; 17 | 18 | /* 19 | * Created by APK Explorer & Editor on November 07, 2021 20 | */ 21 | public class TextViewAdapter extends RecyclerView.Adapter { 22 | 23 | private static List data; 24 | private static String searchWord; 25 | 26 | public TextViewAdapter(List data, String searchWord) { 27 | TextViewAdapter.data = data; 28 | TextViewAdapter.searchWord = searchWord; 29 | } 30 | 31 | @NonNull 32 | @Override 33 | public TextViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 34 | View rowItem = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_view_textview, parent, false); 35 | return new TextViewAdapter.ViewHolder(rowItem); 36 | } 37 | 38 | @Override 39 | public void onBindViewHolder(@NonNull TextViewAdapter.ViewHolder holder, int position) { 40 | if (searchWord != null && Common.isTextMatched(data.get(position), searchWord)) { 41 | holder.mText.setText(APKEditorUtils.fromHtml(data.get(position).replace(searchWord, 42 | "" + searchWord + ""))); 43 | } else { 44 | holder.mText.setText(data.get(position)); 45 | } 46 | } 47 | 48 | @Override 49 | public int getItemCount() { 50 | return data.size(); 51 | } 52 | 53 | public static class ViewHolder extends RecyclerView.ViewHolder { 54 | private final MaterialTextView mText; 55 | 56 | public ViewHolder(View view) { 57 | super(view); 58 | this.mText = view.findViewById(R.id.text); 59 | } 60 | } 61 | 62 | } -------------------------------------------------------------------------------- /fastlane/metadata/android/es/full_description.txt: -------------------------------------------------------------------------------- 1 | APK Explorer & Editor (AEE) incluye un conjunto de herramientas de código abierto diseñadas principalmente para explorar el contenido de una aplicación instalada en un dispositivo Android. Además, AEE ofrece un instalador de APK/APKs modulares/paquetes de aplicaciones con muchas funciones que permite a los usuarios elegir e instalar archivos desde el almacenamiento del dispositivo. Nota: Esta es la versión completa de AEE. La versión de Google Play carece de capacidades de edición, así como de características tales como la firma de APK / App Bundle. 2 | 3 | Características 4 | 5 | * Una vista de lista de las aplicaciones instaladas muy bien diseñada. 6 | * Explora y navega a través de los contenidos de una aplicación instalada. 7 | * Exporta y gestiona fácilmente (instala, comparte, etc.) APK's/Split APK's en el almacenamiento del dispositivo. 8 | * Incluye un instalador de APK/APK modular/paquetes de aplicaciones con muchas funciones (elige e instala fácilmente los archivos desde el almacenamiento del dispositivo) 9 | * Extrae fácilmente el icono de una aplicación haciendo un solo clic sobre él. 10 | * Proporciona información básica sobre los archivos de recursos importantes. 11 | * Ver gráficos, textos, XML binario, y muchos más. 12 | * Guarda/exporta archivos de recursos individuales al almacenamiento del dispositivo. 13 | * También es posible editar archivos de texto/XML binario utilizando un editor de texto incorporado (desactivado por defecto en el menú Ajustes). 14 | * Borra o reemplaza recursos. 15 | * Crea APK's/App Bundles firmados después de los procesos mencionados. 16 | * Firma APK's/paquetes con la clave personalizada de AEE. 17 | * Interfaz de usuario elegantemente diseñada con un tema auto-oscuro y claro. 18 | * Mucho más. 19 | 20 | Traducciones 21 | 22 | Por favor, ayúdame a traducir esta aplicación vía POEditor. También puedes traducir después de descargar la cadena de idiomas original disponible GitHub. 23 | 24 | Documentación 25 | 26 | - Lista de cómos 27 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_about.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 13 | 14 | 19 | 20 | 25 | 26 | 33 | 34 | 43 | 44 | 45 | 46 | 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/tasks/ExportProject.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils.tasks; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.content.Context; 5 | 6 | import com.apk.editor.R; 7 | import com.apk.editor.utils.APKData; 8 | import com.apk.editor.utils.dialogs.ProgressDialog; 9 | 10 | import java.io.File; 11 | import java.util.Objects; 12 | 13 | import in.sunilpaulmathew.sCommon.CommonUtils.sExecutor; 14 | import in.sunilpaulmathew.sCommon.FileUtils.sFileUtils; 15 | 16 | /* 17 | * Created by APK Explorer & Editor on January 28, 2023 18 | */ 19 | public class ExportProject extends sExecutor { 20 | 21 | private final Context mContext; 22 | private final File mFile; 23 | private ProgressDialog mProgressDialog; 24 | private final String mName; 25 | 26 | public ExportProject(File file, String name, Context context) { 27 | mFile = file; 28 | mName = name; 29 | mContext = context; 30 | } 31 | 32 | @SuppressLint("StringFormatInvalid") 33 | @Override 34 | public void onPreExecute() { 35 | mProgressDialog = new ProgressDialog(mContext); 36 | mProgressDialog.setTitle(mContext.getString(R.string.exporting, mFile.getName())); 37 | mProgressDialog.setIcon(R.mipmap.ic_launcher); 38 | mProgressDialog.setIndeterminate(true); 39 | mProgressDialog.show(); 40 | } 41 | 42 | @Override 43 | public void doInBackground() { 44 | File outputDir = new File(APKData.getExportPath(mContext), mName); 45 | if (outputDir.exists()) { 46 | sFileUtils.delete(outputDir); 47 | } 48 | sFileUtils.mkdir(outputDir); 49 | 50 | File[] files = mFile.listFiles(); 51 | mProgressDialog.setMax(Objects.requireNonNull(files).length); 52 | for (File file : files) { 53 | if (file.isDirectory()) { 54 | sFileUtils.copyDir(file, new File(outputDir, file.getName())); 55 | } else { 56 | sFileUtils.copy(file, new File(outputDir, file.getName())); 57 | } 58 | mProgressDialog.updateProgress(1); 59 | } 60 | } 61 | 62 | @Override 63 | public void onPostExecute() { 64 | try { 65 | mProgressDialog.dismiss(); 66 | } catch (IllegalArgumentException ignored) { 67 | } 68 | } 69 | 70 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_xml_editor.xml: -------------------------------------------------------------------------------- 1 | 12 | 13 | 19 | 20 | 30 | 31 | 40 | 41 | 42 | 54 | -------------------------------------------------------------------------------- /Credits.md: -------------------------------------------------------------------------------- 1 | # Credits 2 | APK Explorer & Editor (AEE) is, and as always, an open-source project which is ready to accept contributions from the development community. The application gladly received contributions from a number of people from time to time, mostly with translations. This page provides an incomplete list of people who contributed to this project, directly or indirectly. 3 | 4 | ## Code 5 | * [Grarak](https://github.com/Grarak/) - Kernel Adiutor 6 | * [Aefyr](https://github.com/Aefyr) - SAI 7 | * [Srikanth Reddy Lingala](https://github.com/srikanth-lingala) - zip4j 8 | * [Nitin Kalra](https://github.com/nkalra0123/) - Split App Share & Install 9 | * [Connor Tumbleson](https://github.com/iBotPeaches/Apktool/) - Apktool 10 | * [Ben Gruver](https://github.com/JesusFreke/smali/) - smali/baksmali 11 | * [Google](https://android.googlesource.com/platform/tools/apksig) - apksig 12 | * [sunilpaulmathew](https://github.com/SmartPack/PackageManager/) - Package Manager 13 | 14 | ## Icon 15 | * [Gospel Gilbert](https://t.me/gilgreat0295) - App Icon 16 | 17 | ## Translations 18 | * [Mohammed Qubati](https://t.me/Alqubati_MrK) & Jander Mander - Arabic Translation 19 | * [wushidi](https://t.me/wushidi) - Chinese (Simplified) Translation 20 | * [fossdd](https://chaos.social/@fossdd) - German Translation 21 | * bruh & Hoa Gia Đại Thiếu - Vietnamese Translation 22 | * Bruno Berteau & 2BiaW - French Translation 23 | * Miloš Koliáš - Czech Translation 24 | * Mehmet Un, Kyoya, & Batuhanakkurt000 - Turkish Translation 25 | * [Diego](https://github.com/sguinetti) - Spanish Translation 26 | * tommynok, hinteor, Roman, Artem & Alexander Steiner - Russian Translation 27 | * [mezysinc](https://github.com/mezysinc) - Portuguese (Brazilian) Translation 28 | * Andreaugustoqueiroz999 - Portuguese (Portugal) Translation 29 | * Dodi Studio - Indonesian Translation 30 | * Cooky & Adrian - Polish Translation 31 | * Erős Pista - Hungarian Translation 32 | * Andrii Chvalov & Veydzher - Ukrainian Translation 33 | * يمني - Arabic (UAE) Translation 34 | * Thibault Pitoiset - French (Belgium) Translation 35 | * Mohd Ayan - Hindi Translation 36 | * tas - Lithuanian Translation 37 | * vuvov11 - Thai Translation 38 | * Me - Arabic (SA) Translation 39 | * asdfqw, Fsotm. mai, sardonicdozen, & 始 - Chinese (zh-Hans) Translation 40 | * [VisionR1](https://github.com/VisionR1) - Greek Translation 41 | 42 | _If you think I missed your name, please let me know._ -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_exploring.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 17 | 18 | 26 | 27 | 37 | 38 | 54 | -------------------------------------------------------------------------------- /app/src/play/java/com/apk/editor/utils/menu/ExploreOptionsMenu.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils.menu; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.net.Uri; 6 | 7 | import com.apk.editor.R; 8 | import com.apk.editor.utils.tasks.ExploreAPK; 9 | 10 | import java.io.File; 11 | import java.util.Objects; 12 | 13 | import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils; 14 | import in.sunilpaulmathew.sCommon.Dialog.sSingleItemDialog; 15 | import in.sunilpaulmathew.sCommon.FileUtils.sFileUtils; 16 | 17 | /* 18 | * Created by APK Explorer & Editor on March 16, 2025 19 | */ 20 | public class ExploreOptionsMenu { 21 | 22 | public static String[] getOption(Context context) { 23 | return new String[] { 24 | context.getString(R.string.explore_options_simple), 25 | context.getString(R.string.explore_options_full), 26 | context.getString(R.string.prompt) 27 | }; 28 | } 29 | 30 | public static void getMenu(String packageName, File apkFile, Uri uri, boolean exit, Activity activity) { 31 | if (sFileUtils.exist(new File(activity.getCacheDir().getPath(), uri != null ? new File(Objects.requireNonNull(uri.getPath())).getName() : packageName != null ? packageName : apkFile.getName()))) { 32 | new ExploreAPK(packageName, apkFile, uri, -1, activity).execute(); 33 | } else if (sCommonUtils.getString("decompileSetting", null, activity) == null) { 34 | new sSingleItemDialog(0, null, new String[] { 35 | activity.getString(R.string.explore_options_simple), 36 | activity.getString(R.string.explore_options_full) 37 | }, activity) { 38 | 39 | @Override 40 | public void onItemSelected(int itemPosition) { 41 | new ExploreAPK(packageName, apkFile, uri, itemPosition, activity).execute(); 42 | if (exit) { 43 | activity.finish(); 44 | } 45 | } 46 | }.show(); 47 | } else if (sCommonUtils.getString("decompileSetting", null, activity).equals(activity.getString(R.string.explore_options_full))) { 48 | new ExploreAPK(packageName, apkFile, uri, 1, activity).execute(); 49 | } else { 50 | new ExploreAPK(packageName, apkFile, uri, 0, activity).execute(); 51 | } 52 | } 53 | 54 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/recycle_view_quickedits.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 19 | 20 | 35 | 36 | 37 | 49 | -------------------------------------------------------------------------------- /app/src/main/res/layout/recycle_view_apkexplorer.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 19 | 20 | 28 | 29 | 37 | 38 | 45 | 46 | 47 | 54 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_imageview.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 13 | 14 | 23 | 24 | 33 | 34 | 42 | 43 | 44 | 49 | 50 | 56 | 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/SerializableItems/PackageItems.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils.SerializableItems; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.graphics.drawable.Drawable; 6 | import android.os.Handler; 7 | import android.os.Looper; 8 | import android.widget.ImageView; 9 | 10 | import com.apk.editor.utils.AppData; 11 | 12 | import java.io.File; 13 | import java.io.Serializable; 14 | import java.util.Objects; 15 | import java.util.concurrent.ExecutorService; 16 | import java.util.concurrent.Executors; 17 | 18 | import in.sunilpaulmathew.sCommon.APKUtils.sAPKUtils; 19 | import in.sunilpaulmathew.sCommon.PackageUtils.sPackageUtils; 20 | 21 | /* 22 | * Created by APK Explorer & Editor on September 05, 2021 23 | */ 24 | public class PackageItems implements Serializable { 25 | 26 | private final String mPackageName; 27 | private final Context mContext; 28 | 29 | public PackageItems(String packageName, Context context) { 30 | this.mPackageName = packageName; 31 | this.mContext = context; 32 | } 33 | 34 | public Intent launchIntent(Context context) { 35 | return context.getPackageManager().getLaunchIntentForPackage(mPackageName); 36 | } 37 | 38 | public long getInstalledTime() { 39 | return Objects.requireNonNull(AppData.getPackageInfo(mPackageName, mContext)).firstInstallTime; 40 | } 41 | 42 | public long getUpdatedTime() { 43 | return Objects.requireNonNull(AppData.getPackageInfo(mPackageName, mContext)).lastUpdateTime; 44 | } 45 | 46 | public String getAppName() { 47 | return sPackageUtils.getAppName(mPackageName, mContext).toString(); 48 | } 49 | 50 | public long getAPKSize() { 51 | return new File(sPackageUtils.getSourceDir(mPackageName, mContext)).length(); 52 | } 53 | 54 | public String getAppVersion() { 55 | return sAPKUtils.getVersionName(sPackageUtils.getSourceDir(mPackageName, mContext), mContext); 56 | } 57 | 58 | public String getPackageName() { 59 | return mPackageName; 60 | } 61 | 62 | public void loadAppIcon(ImageView view) { 63 | try (ExecutorService executor = Executors.newSingleThreadExecutor()) { 64 | Handler handler = new Handler(Looper.getMainLooper()); 65 | 66 | executor.execute(() -> { 67 | Drawable drawable = sPackageUtils.getAppIcon(mPackageName, mContext); 68 | 69 | handler.post(() -> view.setImageDrawable(drawable)); 70 | }); 71 | } 72 | } 73 | 74 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/app_title_layout.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 17 | 18 | 24 | 25 | 29 | 30 | 36 | 37 | 46 | 47 | 48 | 49 | 60 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_github.xml: -------------------------------------------------------------------------------- 1 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 9 | 11 | 12 | 19 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 33 | 34 | 36 | 37 | 39 | 40 | 42 | 43 | 45 | 46 | 48 | 49 | 52 | 53 | 58 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/dialogs/ProgressDialog.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils.dialogs; 2 | 3 | import android.content.Context; 4 | import android.graphics.drawable.Drawable; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | 8 | import androidx.appcompat.app.AlertDialog; 9 | import androidx.core.widget.ContentLoadingProgressBar; 10 | 11 | import com.apk.editor.R; 12 | import com.google.android.material.dialog.MaterialAlertDialogBuilder; 13 | 14 | /* 15 | * Created by APK Explorer & Editor on January 19, 2025 16 | */ 17 | public class ProgressDialog { 18 | 19 | private static AlertDialog mAlertDialog = null; 20 | private static ContentLoadingProgressBar mProgressBar = null; 21 | private static MaterialAlertDialogBuilder mDialogBuilder = null; 22 | 23 | public ProgressDialog(Context context) { 24 | LayoutInflater layoutInflater = LayoutInflater.from(context); 25 | View progressLayout = layoutInflater.inflate(R.layout.progress_layout, null); 26 | mProgressBar = progressLayout.findViewById(R.id.progress); 27 | mDialogBuilder = new MaterialAlertDialogBuilder(context) 28 | .setView(progressLayout) 29 | .setCancelable(false); 30 | } 31 | 32 | public int getProgress() { 33 | return mProgressBar.getProgress(); 34 | } 35 | 36 | public void show() { 37 | mAlertDialog = mDialogBuilder.create(); 38 | mAlertDialog.show(); 39 | } 40 | 41 | public void dismiss() { 42 | mAlertDialog.dismiss(); 43 | } 44 | 45 | public void setIcon(int resourceID) { 46 | mDialogBuilder.setIcon(resourceID); 47 | } 48 | 49 | public void setIcon(Drawable icon) { 50 | mDialogBuilder.setIcon(icon); 51 | } 52 | 53 | public void setMessage(int resourceID) { 54 | mDialogBuilder.setMessage(resourceID); 55 | } 56 | 57 | public void setMessage(CharSequence charSequence) { 58 | mDialogBuilder.setMessage(charSequence); 59 | } 60 | 61 | public void setTitle(int resourceID) { 62 | mDialogBuilder.setTitle(resourceID); 63 | } 64 | 65 | public void setTitle(CharSequence charSequence) { 66 | mDialogBuilder.setTitle(charSequence); 67 | } 68 | 69 | public void setIndeterminate(boolean b) { 70 | mProgressBar.setIndeterminate(b); 71 | } 72 | 73 | public void setMax(int max) { 74 | setIndeterminate(false); 75 | mProgressBar.setMax(max); 76 | } 77 | 78 | public void updateProgress(int progress) { 79 | if (mProgressBar.getProgress() < mProgressBar.getMax()) { 80 | mProgressBar.setProgress(mProgressBar.getProgress() + progress); 81 | } else { 82 | mProgressBar.setProgress(0); 83 | setIndeterminate(true); 84 | } 85 | } 86 | 87 | } -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/Common.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils; 2 | 3 | import android.content.Context; 4 | 5 | import com.apk.editor.R; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import java.util.Objects; 10 | 11 | import in.sunilpaulmathew.sCommon.CommonUtils.sCommonUtils; 12 | 13 | /* 14 | * Created by APK Explorer & Editor on June 12, 2021 15 | */ 16 | public class Common { 17 | 18 | private static final List mErrorList = new ArrayList<>(); 19 | private static int mError = 0, mSuccess = 0; 20 | private static String mFileToReplace = null; 21 | 22 | public static boolean isCancelled(Context context) { 23 | return sCommonUtils.getBoolean("cancelled", false, context); 24 | } 25 | 26 | public static boolean isFinished(Context context) { 27 | return Objects.equals(sCommonUtils.getString("exploringStatus", null, context), "finished"); 28 | } 29 | 30 | public static boolean isTextMatched(String searchText, String searchWord) { 31 | for (int a = 0; a < searchText.length() - searchWord.length() + 1; a++) { 32 | if (searchWord.equalsIgnoreCase(searchText.substring(a, a + searchWord.length()))) { 33 | return true; 34 | } 35 | } 36 | return false; 37 | } 38 | 39 | public static int getError() { 40 | return mError; 41 | } 42 | 43 | public static int getSuccess() { 44 | return mSuccess; 45 | } 46 | 47 | public static List getErrorList() { 48 | return mErrorList; 49 | } 50 | 51 | public static String getFileToReplace() { 52 | return mFileToReplace; 53 | } 54 | 55 | public static String getPackageName(Context context) { 56 | return sCommonUtils.getString("packageName", null, context); 57 | } 58 | 59 | public static String getStatus(Context context) { 60 | return isCancelled(context) ? context.getString(R.string.cancelling) : sCommonUtils.getString("exploringStatus", null, context); 61 | } 62 | 63 | public static void isCancelled(boolean b, Context context) { 64 | sCommonUtils.saveBoolean("cancelled", b, context); 65 | } 66 | 67 | public static void setFinishStatus(Context context) { 68 | if (!isFinished(context)) { 69 | sCommonUtils.saveString("exploringStatus", "finished", context); 70 | } 71 | } 72 | 73 | public static void setError(int i) { 74 | mError = i; 75 | } 76 | 77 | public static void setFileToReplace(String fileToReplace) { 78 | mFileToReplace = fileToReplace; 79 | } 80 | 81 | public static void setStatus(String status, Context context) { 82 | sCommonUtils.saveString("exploringStatus", status, context); 83 | } 84 | 85 | public static void setSuccess(int i) { 86 | mSuccess = i; 87 | } 88 | 89 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/recycle_view_apkpicker.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 15 | 16 | 23 | 24 | 33 | 34 | 42 | 43 | 51 | 52 | 53 | 61 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_texteditor.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | 15 | 24 | 25 | 34 | 35 | 43 | 44 | 45 | 46 | 47 | 52 | 53 | 57 | 58 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/activities/ExploringActivity.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.activities; 2 | 3 | import android.graphics.Color; 4 | import android.os.Bundle; 5 | import android.os.Handler; 6 | import android.view.View; 7 | import android.view.WindowManager; 8 | import android.widget.ProgressBar; 9 | 10 | import androidx.activity.OnBackPressedCallback; 11 | import androidx.annotation.Nullable; 12 | import androidx.appcompat.app.AppCompatActivity; 13 | 14 | import com.apk.editor.R; 15 | import com.apk.editor.utils.Common; 16 | import com.google.android.material.button.MaterialButton; 17 | import com.google.android.material.textview.MaterialTextView; 18 | 19 | /* 20 | * Created by APK Explorer & Editor on Feb 21, 2025 21 | */ 22 | public class ExploringActivity extends AppCompatActivity { 23 | 24 | private final Handler mHandler = new Handler(); 25 | private Runnable mRunnable; 26 | 27 | @Override 28 | protected void onCreate(@Nullable Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | setContentView(R.layout.activity_exploring); 31 | 32 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 33 | 34 | ProgressBar mProgress = findViewById(R.id.progress); 35 | MaterialButton mCancel = findViewById(R.id.cancel); 36 | MaterialTextView mTaskSummary = findViewById(R.id.task_summary); 37 | 38 | mCancel.setOnClickListener(v -> { 39 | if (!Common.isFinished(this)) { 40 | Common.isCancelled(true, this); 41 | mTaskSummary.setText(getString(R.string.cancelling)); 42 | mTaskSummary.setTextColor(Color.RED); 43 | mCancel.setVisibility(View.GONE); 44 | return; 45 | } 46 | finish(); 47 | }); 48 | 49 | mRunnable = () -> { 50 | if (Common.isFinished(this)) { 51 | if (Common.isCancelled(this)) { 52 | finish(); 53 | } 54 | mProgress.setVisibility(View.GONE); 55 | finish(); 56 | } else { 57 | if (Common.getStatus(this) != null && !Common.isFinished(this)) { 58 | mTaskSummary.setVisibility(View.VISIBLE); 59 | mTaskSummary.setText(Common.getStatus(this)); 60 | } 61 | } 62 | mHandler.postDelayed(mRunnable, 500); 63 | }; 64 | mHandler.postDelayed(mRunnable, 500); 65 | 66 | getOnBackPressedDispatcher().addCallback(new OnBackPressedCallback(true) { 67 | @Override 68 | public void handleOnBackPressed() { 69 | if (Common.isFinished(ExploringActivity.this)) { 70 | getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 71 | finish(); 72 | } 73 | } 74 | }); 75 | } 76 | 77 | } -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/adapters/BatchOptionsAdapter.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.adapters; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.graphics.drawable.Drawable; 5 | import android.os.Handler; 6 | import android.os.Looper; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | 11 | import androidx.annotation.NonNull; 12 | import androidx.appcompat.widget.AppCompatImageButton; 13 | import androidx.recyclerview.widget.RecyclerView; 14 | 15 | import com.apk.editor.R; 16 | import com.google.android.material.textview.MaterialTextView; 17 | 18 | import java.util.List; 19 | import java.util.concurrent.ExecutorService; 20 | import java.util.concurrent.Executors; 21 | 22 | import in.sunilpaulmathew.sCommon.PackageUtils.sPackageUtils; 23 | 24 | /* 25 | * Created by APK Explorer & Editor on January 23, 2025 26 | */ 27 | public class BatchOptionsAdapter extends RecyclerView.Adapter { 28 | 29 | private final List data; 30 | 31 | public BatchOptionsAdapter(List data) { 32 | this.data = data; 33 | } 34 | 35 | @NonNull 36 | @Override 37 | public BatchOptionsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 38 | View rowItem = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_view_batch_options, parent, false); 39 | return new ViewHolder(rowItem); 40 | } 41 | 42 | @SuppressLint({"StringFormatInvalid", "StringFormatMatches"}) 43 | @Override 44 | public void onBindViewHolder(@NonNull BatchOptionsAdapter.ViewHolder holder, int position) { 45 | loadAppIcon(data.get(position), holder.mAppIcon); 46 | holder.mAppID.setText(data.get(position)); 47 | holder.mAppName.setText(sPackageUtils.getAppName(data.get(position), holder.mAppName.getContext())); 48 | } 49 | 50 | private void loadAppIcon(String packageName, AppCompatImageButton view) { 51 | ExecutorService executor = Executors.newSingleThreadExecutor(); 52 | Handler handler = new Handler(Looper.getMainLooper()); 53 | 54 | executor.execute(() -> { 55 | Drawable drawable = sPackageUtils.getAppIcon(packageName, view.getContext()); 56 | 57 | handler.post(() -> view.setImageDrawable(drawable)); 58 | }); 59 | } 60 | 61 | @Override 62 | public int getItemCount() { 63 | return data.size(); 64 | } 65 | 66 | public static class ViewHolder extends RecyclerView.ViewHolder { 67 | 68 | private final AppCompatImageButton mAppIcon; 69 | private final MaterialTextView mAppID, mAppName; 70 | 71 | public ViewHolder(View view) { 72 | super(view); 73 | this.mAppIcon = view.findViewById(R.id.icon); 74 | this.mAppName = view.findViewById(R.id.title); 75 | this.mAppID = view.findViewById(R.id.description); 76 | } 77 | } 78 | 79 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/recycle_view_resviewer.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 16 | 17 | 26 | 27 | 34 | 35 | 44 | 45 | 54 | 55 | 56 | 57 | 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/tasks/ExportToStorage.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils.tasks; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.content.Context; 5 | 6 | import com.apk.editor.R; 7 | import com.apk.editor.utils.APKData; 8 | import com.apk.editor.utils.dialogs.ProgressDialog; 9 | import com.google.android.material.dialog.MaterialAlertDialogBuilder; 10 | 11 | import java.io.File; 12 | import java.util.List; 13 | 14 | import in.sunilpaulmathew.sCommon.CommonUtils.sExecutor; 15 | import in.sunilpaulmathew.sCommon.FileUtils.sFileUtils; 16 | 17 | /* 18 | * Created by APK Explorer & Editor on January 28, 2023 19 | */ 20 | public class ExportToStorage extends sExecutor { 21 | 22 | private final Context mContext; 23 | private final File mSourceFile; 24 | private final List mSourceFiles; 25 | private final String mFolder; 26 | private ProgressDialog mProgressDialog; 27 | 28 | public ExportToStorage(File sourceFile, List sourceFiles, String folder, Context context) { 29 | mSourceFile = sourceFile; 30 | mSourceFiles = sourceFiles; 31 | mFolder = folder; 32 | mContext = context; 33 | } 34 | 35 | @SuppressLint("StringFormatInvalid") 36 | @Override 37 | public void onPreExecute() { 38 | mProgressDialog = new ProgressDialog(mContext); 39 | mProgressDialog.setTitle(mContext.getString(R.string.exporting, mSourceFile != null && mSourceFile.exists() ? mSourceFile.getName() : "")); 40 | mProgressDialog.setIcon(R.mipmap.ic_launcher); 41 | mProgressDialog.setIndeterminate(true); 42 | mProgressDialog.show(); 43 | } 44 | 45 | @Override 46 | public void doInBackground() { 47 | File mExportPath = new File(APKData.getExportPath(mContext), mFolder); 48 | if (!mExportPath.exists()) { 49 | sFileUtils.mkdir(mExportPath); 50 | } 51 | if (mSourceFiles != null && !mSourceFiles.isEmpty()) { 52 | for (File file : mSourceFiles) { 53 | if (file.exists()) { 54 | sFileUtils.copy(file, new File(mExportPath, file.getName())); 55 | } 56 | } 57 | } else { 58 | sFileUtils.copy(mSourceFile, new File(mExportPath, mSourceFile.getName())); 59 | } 60 | } 61 | 62 | @SuppressLint("StringFormatInvalid") 63 | @Override 64 | public void onPostExecute() { 65 | try { 66 | mProgressDialog.dismiss(); 67 | } catch (IllegalArgumentException ignored) { 68 | } 69 | new MaterialAlertDialogBuilder(mContext) 70 | .setIcon(R.mipmap.ic_launcher) 71 | .setTitle(R.string.app_name) 72 | .setMessage(mContext.getString(R.string.export_complete_message, "Download > AEE > " + mFolder)) 73 | .setPositiveButton(mContext.getString(R.string.cancel), (dialog1, id1) -> { 74 | }).show(); 75 | } 76 | 77 | } -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/dialogs/XMLEditorDialog.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils.dialogs; 2 | 3 | import static android.view.View.GONE; 4 | import static android.view.View.VISIBLE; 5 | 6 | import android.content.Context; 7 | import android.view.View; 8 | 9 | import androidx.appcompat.app.AlertDialog; 10 | 11 | import com.apk.axml.serializableItems.XMLEntry; 12 | import com.apk.editor.R; 13 | import com.google.android.material.button.MaterialButton; 14 | import com.google.android.material.dialog.MaterialAlertDialogBuilder; 15 | import com.google.android.material.switchmaterial.SwitchMaterial; 16 | import com.google.android.material.textfield.MaterialAutoCompleteTextView; 17 | import com.google.android.material.textfield.TextInputLayout; 18 | 19 | /* 20 | * Created by APK Explorer & Editor on August 29, 2025 21 | */ 22 | public abstract class XMLEditorDialog extends MaterialAlertDialogBuilder { 23 | 24 | private static AlertDialog alertDialog = null; 25 | 26 | private static boolean modified; 27 | 28 | public XMLEditorDialog(XMLEntry xmlEntry, Context context) { 29 | super(context); 30 | View rootView = View.inflate(context, R.layout.layout_xml_editor, null); 31 | TextInputLayout layout = rootView.findViewById(R.id.text); 32 | MaterialAutoCompleteTextView value = rootView.findViewById(R.id.value); 33 | SwitchMaterial enable = rootView.findViewById(R.id.enable); 34 | MaterialButton delete = rootView.findViewById(R.id.delete); 35 | 36 | if (xmlEntry.isBoolean()) { 37 | enable.setText(xmlEntry.getTag()); 38 | enable.setChecked(xmlEntry.isChecked()); 39 | value.setVisibility(GONE); 40 | enable.setVisibility(VISIBLE); 41 | } else { 42 | layout.setHint(xmlEntry.getTag()); 43 | value.setText(xmlEntry.getValue()); 44 | value.setVisibility(VISIBLE); 45 | enable.setVisibility(GONE); 46 | } 47 | 48 | enable.setOnClickListener(v -> modified = enable.isChecked() != xmlEntry.isChecked()); 49 | 50 | delete.setOnClickListener(v -> { 51 | removeLine(); 52 | alertDialog.dismiss(); 53 | }); 54 | 55 | setView(rootView); 56 | setIcon(R.drawable.ic_edit); 57 | setTitle(R.string.xml_modify_title); 58 | setNegativeButton(R.string.cancel, (dialog, id) -> { 59 | }); 60 | setPositiveButton(R.string.apply, (dialog, id) -> { 61 | if (modified || !value.getText().toString().trim().isEmpty() && !value.getText().toString().trim().equals(xmlEntry.getValue())) { 62 | modifyLine(enable.getVisibility() == VISIBLE ? enable.isChecked() ? "true" : "false" : value.getText().toString().trim()); 63 | } 64 | }); 65 | 66 | alertDialog = create(); 67 | alertDialog.show(); 68 | } 69 | 70 | public abstract void modifyLine(String newValue); 71 | 72 | public abstract void removeLine(); 73 | 74 | } -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/adapters/SettingsAdapter.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.adapters; 2 | 3 | import android.view.LayoutInflater; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | 7 | import androidx.annotation.NonNull; 8 | import androidx.appcompat.widget.AppCompatImageButton; 9 | import androidx.recyclerview.widget.RecyclerView; 10 | 11 | import com.apk.editor.R; 12 | import com.google.android.material.textview.MaterialTextView; 13 | 14 | import java.util.ArrayList; 15 | 16 | import in.sunilpaulmathew.sCommon.CommonUtils.sSerializableItems; 17 | 18 | /* 19 | * Created by APK Explorer & Editor on March 31, 2021 20 | */ 21 | public class SettingsAdapter extends RecyclerView.Adapter { 22 | 23 | private static ClickListener clickListener; 24 | 25 | private static ArrayList data; 26 | 27 | public SettingsAdapter(ArrayList data) { 28 | SettingsAdapter.data = data; 29 | } 30 | 31 | @NonNull 32 | @Override 33 | public SettingsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 34 | View rowItem = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_view_about, parent, false); 35 | return new ViewHolder(rowItem); 36 | } 37 | 38 | @Override 39 | public void onBindViewHolder(@NonNull SettingsAdapter.ViewHolder holder, int position) { 40 | holder.Title.setText(data.get(position).getTextOne()); 41 | if (data.get(position).getTextTwo() != null) { 42 | holder.Description.setText(data.get(position).getTextTwo()); 43 | } else { 44 | holder.Description.setVisibility(View.GONE); 45 | } 46 | if (data.get(position).getIcon() != null) { 47 | holder.mIcon.setImageDrawable(data.get(position).getIcon()); 48 | } else { 49 | holder.mIcon.setVisibility(View.GONE); 50 | } 51 | } 52 | 53 | @Override 54 | public int getItemCount() { 55 | return data.size(); 56 | } 57 | 58 | public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 59 | private final AppCompatImageButton mIcon; 60 | private final MaterialTextView Description, Title; 61 | 62 | public ViewHolder(View view) { 63 | super(view); 64 | view.setOnClickListener(this); 65 | this.mIcon = view.findViewById(R.id.icon); 66 | this.Title = view.findViewById(R.id.title); 67 | this.Description = view.findViewById(R.id.description); 68 | } 69 | 70 | @Override 71 | public void onClick(View view) { 72 | clickListener.onItemClick(getBindingAdapterPosition(), view); 73 | } 74 | } 75 | 76 | public void setOnItemClickListener(ClickListener clickListener) { 77 | SettingsAdapter.clickListener = clickListener; 78 | } 79 | 80 | public interface ClickListener { 81 | void onItemClick(int position, View v); 82 | } 83 | 84 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_textview.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | 15 | 24 | 25 | 33 | 34 | 42 | 43 | 44 | 50 | 51 | 61 | 62 | 63 | 64 | 65 | 69 | -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/APKEditorUtils.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils; 2 | 3 | import android.content.Context; 4 | import android.os.Build; 5 | import android.text.Html; 6 | import android.util.TypedValue; 7 | 8 | import com.apk.editor.R; 9 | 10 | import net.lingala.zip4j.ZipFile; 11 | import net.lingala.zip4j.model.ZipParameters; 12 | import net.lingala.zip4j.model.enums.CompressionMethod; 13 | 14 | import java.io.File; 15 | import java.io.IOException; 16 | import java.util.Objects; 17 | 18 | /* 19 | * Created by APK Explorer & Editor on March 04, 2021 20 | */ 21 | public class APKEditorUtils { 22 | 23 | public static int getThemeAccentColor(Context context) { 24 | TypedValue value = new TypedValue(); 25 | context.getTheme().resolveAttribute(R.attr.colorAccent, value, true); 26 | return value.data; 27 | } 28 | 29 | public static boolean isFullVersion(Context context) { 30 | return context.getPackageName().equals("com.apk.editor") || context.getPackageName().equals("com.apk.editor.debug"); 31 | } 32 | 33 | public static CharSequence fromHtml(String text) { 34 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 35 | return Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY); 36 | } else { 37 | return Html.fromHtml(text); 38 | } 39 | } 40 | 41 | public static void unzip(String zip, String path) { 42 | try (ZipFile zipFile = new ZipFile(zip)) { 43 | zipFile.extractAll(path); 44 | } catch (IOException ignored) { 45 | } 46 | } 47 | 48 | public static void zip(File path, File zip) { 49 | try (ZipFile zipFile = new ZipFile(zip)) { 50 | for (File mFile : Objects.requireNonNull(path.listFiles())) { 51 | if (mFile.isDirectory()) { 52 | if (mFile.getName().equals("assets") || mFile.getName().equals("lib") 53 | || mFile.getName().equals("res") || mFile.getName().equals("r") 54 | || mFile.getName().equals("R")) { 55 | zipFile.addFolder(mFile, getZipParametersAsStore(mFile)); 56 | } else { 57 | zipFile.addFolder(mFile); 58 | } 59 | } else { 60 | if (mFile.getName().equalsIgnoreCase("resources.arsc") 61 | || mFile.getName().startsWith("classes") && mFile.getName().endsWith(".dex")) { 62 | zipFile.addFile(mFile, getZipParametersAsStore(mFile)); 63 | } else { 64 | zipFile.addFile(mFile); 65 | } 66 | } 67 | } 68 | } catch (IOException ignored) { 69 | } 70 | } 71 | 72 | private static ZipParameters getZipParametersAsStore(File file) { 73 | ZipParameters zipParameters = new ZipParameters(); 74 | zipParameters.setCompressionMethod(CompressionMethod.STORE); 75 | zipParameters.setEntrySize(file.length()); 76 | return zipParameters; 77 | } 78 | 79 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_xmleditor.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | 12 | 21 | 22 | 28 | 29 | 43 | 44 | 45 | 46 | 47 | 50 | 51 | 52 | 53 | 54 | 55 | 72 | -------------------------------------------------------------------------------- /app/src/main/java/com/apk/editor/utils/tasks/ExportApp.java: -------------------------------------------------------------------------------- 1 | package com.apk.editor.utils.tasks; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.content.Context; 5 | 6 | import com.apk.editor.R; 7 | import com.apk.editor.utils.APKData; 8 | import com.apk.editor.utils.dialogs.ProgressDialog; 9 | import com.google.android.material.dialog.MaterialAlertDialogBuilder; 10 | 11 | import java.io.File; 12 | import java.util.List; 13 | 14 | import in.sunilpaulmathew.sCommon.CommonUtils.sExecutor; 15 | import in.sunilpaulmathew.sCommon.FileUtils.sFileUtils; 16 | import in.sunilpaulmathew.sCommon.PackageUtils.sPackageUtils; 17 | 18 | /* 19 | * Created by APK Explorer & Editor on January 28, 2023 20 | */ 21 | public class ExportApp extends sExecutor { 22 | 23 | private final Context mContext; 24 | private ProgressDialog mProgressDialog; 25 | private final List mPackageNames; 26 | 27 | public ExportApp(List packageNames, Context context) { 28 | mPackageNames = packageNames; 29 | mContext = context; 30 | } 31 | 32 | @SuppressLint("StringFormatInvalid") 33 | @Override 34 | public void onPreExecute() { 35 | mProgressDialog = new ProgressDialog(mContext); 36 | mProgressDialog.setTitle(mContext.getString(R.string.exporting_batch)); 37 | mProgressDialog.setIcon(R.mipmap.ic_launcher); 38 | mProgressDialog.setIndeterminate(true); 39 | mProgressDialog.show(); 40 | if (!APKData.getExportPath(mContext).exists()) { 41 | sFileUtils.mkdir(APKData.getExportPath(mContext)); 42 | } 43 | } 44 | 45 | @Override 46 | public void doInBackground() { 47 | for (String packageName : mPackageNames) { 48 | if (APKData.isAppBundle(sPackageUtils.getSourceDir(packageName, mContext))) { 49 | File mParent = new File(APKData.getExportPath(mContext) , packageName); 50 | if (mParent.exists()) { 51 | sFileUtils.delete(mParent); 52 | } 53 | sFileUtils.mkdir(mParent); 54 | for (String mSplits : APKData.splitApks(sPackageUtils.getSourceDir(packageName, mContext))) { 55 | if (mSplits.endsWith(".apk")) { 56 | sFileUtils.copy(new File(mSplits), new File(mParent, new File(mSplits).getName())); 57 | } 58 | } 59 | } else { 60 | sFileUtils.copy(new File(sPackageUtils.getSourceDir(packageName, mContext)), new File(APKData.getExportPath(mContext), packageName + ".apk")); 61 | } 62 | } 63 | } 64 | 65 | @Override 66 | public void onPostExecute() { 67 | try { 68 | mProgressDialog.dismiss(); 69 | } catch (IllegalArgumentException ignored) { 70 | } 71 | new MaterialAlertDialogBuilder(mContext) 72 | .setIcon(R.mipmap.ic_launcher) 73 | .setTitle(R.string.app_name) 74 | .setMessage(mContext.getString(R.string.exported_apks_path, 75 | "Download > AEE")) 76 | .setCancelable(false) 77 | .setPositiveButton(R.string.cancel, (dialog, id) -> {} 78 | ).show(); 79 | } 80 | 81 | } --------------------------------------------------------------------------------