mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-08-03 10:46:53 -04:00
Fixed, Unable to upload APK on play store for new apps.
* We have implemented Play Asset Delivery to include the ZIM file within the Android App Bundle (AAB). * To achieve this, we've created Gradle tasks to automatically download the ZIM file and place it inside the assets folder. * In order to utilize this asset file, we've refactored our custom application code. * We haven't removed the functionality of uploading the APK, as this approach remains static for now. Thus, we are retaining both codebases.
This commit is contained in:
parent
3a47ae601a
commit
4c951de69e
@ -100,6 +100,14 @@ class Transaction(
|
||||
).execute().prettyPrint()
|
||||
}
|
||||
|
||||
fun uploadBundle(file: File) {
|
||||
publisher.edits().apks().upload(
|
||||
packageName,
|
||||
editId,
|
||||
FileContent("application/octet-stream", file)
|
||||
).execute().prettyPrint()
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
fun addToTrackInDraft(apkVariants: List<ApkVariantOutput>): Track =
|
||||
publisher.edits().tracks().update(packageName, editId, "internal", Track().apply {
|
||||
@ -110,6 +118,17 @@ class Transaction(
|
||||
})
|
||||
track = "internal"
|
||||
}).execute().prettyPrint()
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
fun addBundleToTrackInDraft(versionCode: Int, versionName: String?): Track =
|
||||
publisher.edits().tracks().update(packageName, editId, "internal", Track().apply {
|
||||
releases = listOf(TrackRelease().apply {
|
||||
status = "draft"
|
||||
name = versionName
|
||||
versionCodes = listOf(versionCode.toLong())
|
||||
})
|
||||
track = "internal"
|
||||
}).execute().prettyPrint()
|
||||
}
|
||||
|
||||
fun AndroidPublisher.transactionWithCommit(packageName: String, func: Transaction.() -> Unit) {
|
||||
|
@ -13,6 +13,7 @@ import java.io.FileOutputStream
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.ResponseBody
|
||||
import java.io.FileNotFoundException
|
||||
|
||||
plugins {
|
||||
android
|
||||
@ -33,8 +34,13 @@ android {
|
||||
createDownloadTask(it)
|
||||
createPublishApkWithExpansionTask(it, applicationVariants)
|
||||
}
|
||||
File("$projectDir/../install_time_asset_for_dwds/src/main/assets", "$name.zim").let {
|
||||
createDownloadTaskForPlayAssetDelivery(it)
|
||||
createPublishBundleWithAssetPlayDelivery(applicationVariants)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bundle {
|
||||
language {
|
||||
// This is for testing the bundle file for the play store
|
||||
@ -42,6 +48,12 @@ android {
|
||||
enableSplit = false
|
||||
}
|
||||
}
|
||||
splits {
|
||||
abi {
|
||||
isUniversalApk = true
|
||||
}
|
||||
}
|
||||
assetPacks += ":install_time_asset_for_dwds"
|
||||
}
|
||||
|
||||
fun ProductFlavor.createDownloadTask(file: File): Task {
|
||||
@ -105,6 +117,38 @@ fun writeZimFileData(responseBody: ResponseBody, file: File) {
|
||||
}
|
||||
}
|
||||
|
||||
fun ProductFlavor.createDownloadTaskForPlayAssetDelivery(
|
||||
file: File
|
||||
): Task {
|
||||
return tasks.create(
|
||||
"download${
|
||||
name.replaceFirstChar {
|
||||
if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else "$it"
|
||||
}
|
||||
}ZimAndPutInAssetFolder"
|
||||
) {
|
||||
group = "Downloading"
|
||||
doLast {
|
||||
if (!file.exists()) {
|
||||
file.createNewFile()
|
||||
|
||||
OkHttpClient().newCall(fetchRequest()).execute().use { response ->
|
||||
if (response.isSuccessful) {
|
||||
response.body?.let { responseBody ->
|
||||
writeZimFileData(responseBody, file)
|
||||
}
|
||||
} else {
|
||||
throw RuntimeException(
|
||||
"Download Failed. Error: ${response.message}\n" +
|
||||
" Status Code: ${response.code}"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val String.decodeUrl: String
|
||||
get() = URLDecoder.decode(this, "UTF-8")
|
||||
val String.isAuthenticationUrl: Boolean
|
||||
@ -149,6 +193,37 @@ fun DomainObjectSet<ApplicationVariant>.releaseVariantsFor(productFlavor: Produc
|
||||
find { it.name.equals("${productFlavor.name}Release", true) }!!
|
||||
.outputs.filterIsInstance<ApkVariantOutput>().sortedBy { it.versionCodeOverride }
|
||||
|
||||
fun ProductFlavor.createPublishBundleWithAssetPlayDelivery(
|
||||
applicationVariants: DomainObjectSet<ApplicationVariant>
|
||||
): Task {
|
||||
val capitalizedName =
|
||||
name.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else "$it" }
|
||||
return tasks.create("publish${capitalizedName}ReleaseBundleWithPlayAssetDelivery") {
|
||||
group = "publishing"
|
||||
description = "Uploads $capitalizedName to the Play Console with an Expansion file"
|
||||
doLast {
|
||||
val packageName = "org.kiwix$applicationIdSuffix"
|
||||
println("packageName $packageName")
|
||||
createPublisher(File(rootDir, "playstore.json"))
|
||||
.transactionWithCommit(packageName) {
|
||||
val variants =
|
||||
applicationVariants.releaseVariantsFor(this@createPublishBundleWithAssetPlayDelivery)
|
||||
val generatedBundleFile =
|
||||
File(
|
||||
"$buildDir/outputs/bundle/${capitalizedName.lowercase(Locale.getDefault())}" +
|
||||
"Release/custom-${capitalizedName.lowercase(Locale.getDefault())}-release.aab"
|
||||
)
|
||||
if (generatedBundleFile.exists()) {
|
||||
uploadBundle(generatedBundleFile)
|
||||
addBundleToTrackInDraft(variants[0].versionCode, versionName)
|
||||
} else {
|
||||
throw FileNotFoundException("Unable to find generated aab file")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
tasks.filter { it.name.contains("ReleaseApkWithExpansionFile") }.forEach {
|
||||
val flavorName =
|
||||
@ -156,4 +231,10 @@ afterEvaluate {
|
||||
it.dependsOn.add(tasks.getByName("download${flavorName}Zim"))
|
||||
it.dependsOn.add(tasks.getByName("assemble${flavorName}Release"))
|
||||
}
|
||||
tasks.filter { it.name.contains("ReleaseBundleWithPlayAssetDelivery") }.forEach {
|
||||
val flavorName =
|
||||
it.name.substringAfter("publish").substringBefore("ReleaseBundleWithPlayAssetDelivery")
|
||||
it.dependsOn.add(tasks.getByName("download${flavorName}ZimAndPutInAssetFolder"))
|
||||
it.dependsOn.add(tasks.getByName("bundle${flavorName}Release"))
|
||||
}
|
||||
}
|
||||
|
@ -19,11 +19,15 @@
|
||||
package org.kiwix.kiwixmobile.custom.main
|
||||
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.util.Log
|
||||
import androidx.core.content.ContextCompat
|
||||
import org.kiwix.kiwixmobile.custom.main.ValidationState.HasBothFiles
|
||||
import org.kiwix.kiwixmobile.custom.main.ValidationState.HasFile
|
||||
import org.kiwix.kiwixmobile.custom.main.ValidationState.HasNothing
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import javax.inject.Inject
|
||||
|
||||
class CustomFileValidator @Inject constructor(private val context: Context) {
|
||||
@ -37,16 +41,48 @@ class CustomFileValidator @Inject constructor(private val context: Context) {
|
||||
|
||||
private fun detectInstallationState(
|
||||
obbFiles: List<File> = obbFiles(),
|
||||
zimFiles: List<File> = zimFiles()
|
||||
zimFiles: List<File> = zimFiles(),
|
||||
assetFile: File? = getFileFromPlayAssetDelivery()
|
||||
): ValidationState {
|
||||
return when {
|
||||
obbFiles.isNotEmpty() && zimFiles().isNotEmpty() -> HasBothFiles(obbFiles[0], zimFiles[0])
|
||||
obbFiles.isNotEmpty() -> HasFile(obbFiles[0])
|
||||
zimFiles.isNotEmpty() -> HasFile(zimFiles[0])
|
||||
assetFile != null -> HasFile(assetFile)
|
||||
else -> HasNothing
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("NestedBlockDepth", "MagicNumber")
|
||||
private fun getFileFromPlayAssetDelivery(): File? {
|
||||
var zimFile: File? = null
|
||||
try {
|
||||
val context = context.createPackageContext(context.packageName, 0)
|
||||
val assetManager = context.assets
|
||||
val inputStream = assetManager.open("dwds_de_dictionary_nopic_2023-09-12.zim")
|
||||
val filePath = ContextCompat.getExternalFilesDirs(context, null)[0]
|
||||
zimFile = File(filePath, "dwds_de_dictionary_nopic_2023-09-12.zim")
|
||||
FileOutputStream(zimFile).use { outputSteam ->
|
||||
inputStream.use { inputStream ->
|
||||
val buffer = ByteArray(1024)
|
||||
var length: Int
|
||||
while (inputStream.read(buffer).also { length = it } > 0) {
|
||||
outputSteam.write(buffer, 0, length)
|
||||
}
|
||||
outputSteam.flush()
|
||||
}
|
||||
}
|
||||
} catch (packageNameNotFoundException: PackageManager.NameNotFoundException) {
|
||||
Log.w(
|
||||
"ASSET_PACKAGE_DELIVERY",
|
||||
"Asset package is not found ${packageNameNotFoundException.message}"
|
||||
)
|
||||
} catch (ioException: IOException) {
|
||||
Log.w("ASSET_PACKAGE_DELIVERY", "Unable to copy the content of asset ${ioException.message}")
|
||||
}
|
||||
return zimFile
|
||||
}
|
||||
|
||||
private fun obbFiles() = scanDirs(ContextCompat.getObbDirs(context), "obb")
|
||||
|
||||
private fun zimFiles(): List<File> {
|
||||
|
8
install_time_asset_for_dwds/build.gradle
Normal file
8
install_time_asset_for_dwds/build.gradle
Normal file
@ -0,0 +1,8 @@
|
||||
apply plugin: 'com.android.asset-pack'
|
||||
|
||||
assetPack {
|
||||
packName = "install_time_asset_for_dwds" // Directory name for the asset pack
|
||||
dynamicDelivery {
|
||||
deliveryType = "install-time" // delivery mode
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
include(
|
||||
":core",
|
||||
":app",
|
||||
":custom"
|
||||
":custom",
|
||||
":install_time_asset_for_dwds"
|
||||
)
|
||||
rootProject.name = "kiwix-android"
|
||||
|
Loading…
x
Reference in New Issue
Block a user