mirror of
https://github.com/izzy2lost/aab2apk.git
synced 2026-06-19 01:20:08 -07:00
New Project Structure and Rewritten Architecture
This commit is contained in:
Generated
+1
@@ -0,0 +1 @@
|
||||
AabToApk
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AndroidProjectSystem">
|
||||
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
|
||||
</component>
|
||||
</project>
|
||||
+1
-3
@@ -1,8 +1,6 @@
|
||||
<component name="ArtifactManager">
|
||||
<artifact type="jar" name="AabToApk-jvm-1.0-SNAPSHOT">
|
||||
<output-path>$PROJECT_DIR$/build/libs</output-path>
|
||||
<root id="archive" name="AabToApk-jvm-1.0-SNAPSHOT.jar">
|
||||
<element id="module-output" name="AabToApk.jvmMain" />
|
||||
</root>
|
||||
<root id="archive" name="AabToApk-jvm-1.0-SNAPSHOT.jar" />
|
||||
</artifact>
|
||||
</component>
|
||||
Generated
+8
@@ -0,0 +1,8 @@
|
||||
<component name="ArtifactManager">
|
||||
<artifact type="jar" name="composeApp-jvm">
|
||||
<output-path>$PROJECT_DIR$/composeApp/build/libs</output-path>
|
||||
<root id="archive" name="composeApp-jvm.jar">
|
||||
<element id="module-output" name="AabToApk.composeApp.jvmMain" />
|
||||
</root>
|
||||
</artifact>
|
||||
</component>
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AgentMigrationStateService">
|
||||
<option name="migrationStatus" value="COMPLETED" />
|
||||
</component>
|
||||
</project>
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AskMigrationStateService">
|
||||
<option name="migrationStatus" value="COMPLETED" />
|
||||
</component>
|
||||
</project>
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Ask2AgentMigrationStateService">
|
||||
<option name="migrationStatus" value="COMPLETED" />
|
||||
</component>
|
||||
</project>
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="EditMigrationStateService">
|
||||
<option name="migrationStatus" value="COMPLETED" />
|
||||
</component>
|
||||
</project>
|
||||
Generated
+1
@@ -9,6 +9,7 @@
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/composeApp" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
|
||||
Generated
-1
@@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="azul-18" project-jdk-type="JavaSDK">
|
||||
|
||||
+7
-57
@@ -1,58 +1,8 @@
|
||||
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
|
||||
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
id("org.jetbrains.compose")
|
||||
}
|
||||
|
||||
group = "com.AabToApk"
|
||||
version = "1.0-SNAPSHOT"
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvm {
|
||||
jvmToolchain(11)
|
||||
withJava()
|
||||
}
|
||||
sourceSets {
|
||||
val jvmMain by getting {
|
||||
dependencies {
|
||||
implementation(compose.desktop.currentOs)
|
||||
api("com.esotericsoftware:kryo:4.0.1")
|
||||
}
|
||||
}
|
||||
val jvmTest by getting {
|
||||
dependencies {
|
||||
implementation(compose.desktop.uiTestJUnit4)
|
||||
implementation(compose.desktop.currentOs)
|
||||
}
|
||||
}
|
||||
val resourcesDir = "src/common/resources"
|
||||
}
|
||||
}
|
||||
|
||||
compose.desktop {
|
||||
application {
|
||||
mainClass = "MainKt"
|
||||
nativeDistributions {
|
||||
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
|
||||
packageName = "AabToApk"
|
||||
packageVersion = "1.0.4"
|
||||
val iconsRoot = project.file("desktop-icons")
|
||||
macOS{
|
||||
iconFile.set(iconsRoot.resolve("launcher.icns"))
|
||||
}
|
||||
windows{
|
||||
iconFile.set(iconsRoot.resolve("launcher.ico"))
|
||||
}
|
||||
linux{
|
||||
iconFile.set(iconsRoot.resolve("launcher.png"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// this is necessary to avoid the plugins to be loaded multiple times
|
||||
// in each subproject's classloader
|
||||
alias(libs.plugins.composeHotReload) apply false
|
||||
alias(libs.plugins.composeMultiplatform) apply false
|
||||
alias(libs.plugins.composeCompiler) apply false
|
||||
alias(libs.plugins.kotlinMultiplatform) apply false
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.kotlinMultiplatform)
|
||||
alias(libs.plugins.composeMultiplatform)
|
||||
alias(libs.plugins.composeCompiler)
|
||||
alias(libs.plugins.composeHotReload)
|
||||
alias(libs.plugins.kotlin.serialization)
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvm()
|
||||
sourceSets {
|
||||
commonMain.dependencies {
|
||||
implementation(compose.runtime)
|
||||
implementation(compose.foundation)
|
||||
implementation(compose.material3)
|
||||
implementation(compose.materialIconsExtended)
|
||||
implementation(compose.ui)
|
||||
implementation(compose.components.resources)
|
||||
implementation(compose.components.uiToolingPreview)
|
||||
implementation(libs.androidx.lifecycle.viewmodelCompose)
|
||||
implementation(libs.androidx.lifecycle.runtimeCompose)
|
||||
// Ktor Client
|
||||
implementation(libs.ktor.client.core)
|
||||
implementation(libs.ktor.client.content.negotiation)
|
||||
implementation(libs.ktor.serialization.kotlinx.json)
|
||||
implementation(libs.ktor.client.logging)
|
||||
// Koin
|
||||
implementation(libs.koin.core)
|
||||
implementation(libs.koin.compose)
|
||||
implementation(libs.koin.viewmodel)
|
||||
implementation(libs.koin.navigation)
|
||||
// Navigation
|
||||
implementation(libs.androidx.compose.navigation)
|
||||
// Datastore
|
||||
implementation(libs.datastore)
|
||||
implementation(libs.datastore.prefs)
|
||||
}
|
||||
commonTest.dependencies {
|
||||
implementation(libs.kotlin.test)
|
||||
}
|
||||
jvmMain.dependencies {
|
||||
implementation(compose.desktop.currentOs)
|
||||
implementation(libs.kotlinx.coroutinesSwing)
|
||||
implementation(libs.ktor.client.cio)
|
||||
implementation(libs.kotlinx.coroutines.core)
|
||||
implementation(libs.logback.logging)
|
||||
}
|
||||
val jvmMain by getting {
|
||||
resources.srcDir("src/jvmMain/composeResources")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compose.desktop {
|
||||
application {
|
||||
mainClass = "MainKt"
|
||||
nativeDistributions {
|
||||
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
|
||||
packageName = "AabToApk"
|
||||
packageVersion = "1.0.4"
|
||||
val iconsRoot = project.file("desktop-icons")
|
||||
macOS{
|
||||
iconFile.set(iconsRoot.resolve("launcher.icns"))
|
||||
}
|
||||
windows{
|
||||
iconFile.set(iconsRoot.resolve("launcher.ico"))
|
||||
}
|
||||
linux{
|
||||
iconFile.set(iconsRoot.resolve("launcher.png"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<resources>
|
||||
<string name="app_name">BundleTool Desktop</string>
|
||||
<string name="title">AAB to APK Converter</string>
|
||||
<string name="subtitle">Convert Android App Bundles to various APK formats with ease.</string>
|
||||
<string name="step_one_title">1. Select Android App Bundle (.aab)</string>
|
||||
<string name="no_aab_selected">No AAB file selected</string>
|
||||
<string name="step_two_title">2. Choose BundleTool Executable</string>
|
||||
<string name="bundletool_not_selected">Bundle Tool not selected</string>
|
||||
<string name="download_bundletool">Download BundleTool</string>
|
||||
<string name="step_three_title">3. Choose Output Mode</string>
|
||||
<string name="universal_apk">Universal APK</string>
|
||||
<string name="apk_set">APK Set (.apks)</string>
|
||||
<string name="device_specific">Device-specific</string>
|
||||
<string name="step_four_title">4. Output Directory (optional)</string>
|
||||
<string name="step_four_subtitle">Leave empty for same directory as .aab</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,25 @@
|
||||
import aabtoapk.composeapp.generated.resources.Res
|
||||
import aabtoapk.composeapp.generated.resources.app_name
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.WindowPosition
|
||||
import androidx.compose.ui.window.application
|
||||
import androidx.compose.ui.window.rememberWindowState
|
||||
import di.initKoin
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import ui.App
|
||||
|
||||
fun main() = application {
|
||||
initKoin()
|
||||
Window(
|
||||
onCloseRequest = ::exitApplication,
|
||||
state = rememberWindowState(
|
||||
width = 800.dp, height = 1000.dp,
|
||||
position = WindowPosition(Alignment.Center)
|
||||
),
|
||||
title = stringResource(Res.string.app_name)
|
||||
) {
|
||||
App {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package command
|
||||
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
class CommandBuilder(
|
||||
private val config: Config
|
||||
) : ICommandBuilder {
|
||||
|
||||
val logger = LoggerFactory.getLogger("CommandBuilder") as Logger
|
||||
data class Config(
|
||||
val bundleToolPath: String,
|
||||
val aabPath: String,
|
||||
val outputDir: String? = null,
|
||||
val isUniversal: Boolean = true,
|
||||
val keystore: KeystoreConfig? = null,
|
||||
val deviceId: String? = null,
|
||||
val overwrite: Boolean = false
|
||||
)
|
||||
|
||||
data class KeystoreConfig(
|
||||
val path: String,
|
||||
val password: String,
|
||||
val alias: String,
|
||||
val keyPassword: String
|
||||
)
|
||||
|
||||
override fun build(): Result<String> {
|
||||
if (config.bundleToolPath.isBlank()) return Result.failure(IllegalArgumentException("BundleTool path missing"))
|
||||
if (config.aabPath.isBlank()) return Result.failure(IllegalArgumentException("AAB file path missing"))
|
||||
|
||||
val cmd = buildString {
|
||||
append("java -jar \"${config.bundleToolPath}\" build-apks ")
|
||||
append("--bundle=\"${config.aabPath}\" ")
|
||||
append("--output=\"${if(config.outputDir.isNullOrEmpty()) getDefaultOutput() else config.outputDir}\" ")
|
||||
if (config.isUniversal) append("--mode=universal ")
|
||||
if (config.overwrite) append("--overwrite ")
|
||||
config.keystore?.let {
|
||||
append("--ks=${it.path} ")
|
||||
append("--ks-pass=pass:${it.password} ")
|
||||
append("--ks-key-alias=${it.alias} ")
|
||||
append("--key-pass=pass:${it.keyPassword} ")
|
||||
}
|
||||
config.deviceId?.let { append("--device-id=$it ") }
|
||||
append("--overwrite ")
|
||||
}
|
||||
logger.debug(cmd.trim())
|
||||
return Result.success(cmd.trim())
|
||||
}
|
||||
|
||||
private fun getDefaultOutput(): String {
|
||||
val base = config.aabPath.substringBeforeLast(".")
|
||||
return "$base.apks"
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun create(block: Builder.() -> Unit): CommandBuilder {
|
||||
val builder = Builder()
|
||||
builder.block()
|
||||
return CommandBuilder(builder.build())
|
||||
}
|
||||
}
|
||||
|
||||
class Builder {
|
||||
private var bundleToolPath: String = ""
|
||||
private var aabPath: String = ""
|
||||
private var outputDir: String? = null
|
||||
private var isUniversal: Boolean = true
|
||||
private var keystore: KeystoreConfig? = null
|
||||
private var deviceId: String? = null
|
||||
private var overwrite: Boolean = false
|
||||
|
||||
fun bundleTool(path: String) = apply { bundleToolPath = path }
|
||||
fun aab(path: String) = apply { aabPath = path }
|
||||
fun outputDir(dir: String?) = apply { outputDir = dir }
|
||||
fun universal(enable: Boolean) = apply { isUniversal = enable }
|
||||
fun overwrite(enable: Boolean) = apply { overwrite = enable }
|
||||
fun keystore(block: KeystoreConfig.() -> Unit) = apply {
|
||||
keystore = KeystoreConfig("", "", "", "").apply(block)
|
||||
}
|
||||
|
||||
fun device(id: String?) = apply { deviceId = id }
|
||||
|
||||
fun build() = Config(bundleToolPath, aabPath, outputDir, isUniversal, keystore, deviceId, overwrite)
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user