mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-08-03 18:56:44 -04:00
1360 add custom publishing code for a custom app
This commit is contained in:
parent
ac4717a79e
commit
8057ef6b6e
@ -2,6 +2,7 @@ import plugin.KiwixConfigurationPlugin
|
||||
|
||||
plugins {
|
||||
id("com.android.application")
|
||||
id("com.github.triplet.play") version("2.5.0")
|
||||
}
|
||||
apply plugin: KiwixConfigurationPlugin
|
||||
|
||||
@ -67,6 +68,10 @@ android {
|
||||
}
|
||||
|
||||
play {
|
||||
enabled = true
|
||||
serviceAccountCredentials = file("../google.json")
|
||||
track = "alpha"
|
||||
releaseStatus = "draft"
|
||||
resolutionStrategy = "fail"
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,8 @@ dependencies {
|
||||
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.50")
|
||||
implementation("com.dicedmelon.gradle:jacoco-android:0.1.4")
|
||||
implementation("org.jlleitschuh.gradle:ktlint-gradle:8.2.0")
|
||||
implementation("com.github.triplet.gradle:play-publisher:2.5.0")
|
||||
implementation("com.google.apis:google-api-services-androidpublisher:v3-rev129-1.25.0")
|
||||
|
||||
implementation(gradleApi())
|
||||
implementation(localGroovy())
|
||||
}
|
||||
|
122
buildSrc/src/main/kotlin/custom/Auth.kt
Normal file
122
buildSrc/src/main/kotlin/custom/Auth.kt
Normal file
@ -0,0 +1,122 @@
|
||||
/* Kiwix Android
|
||||
* Copyright (c) 2019 Kiwix <android.kiwix.org>
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package custom
|
||||
|
||||
import com.android.build.gradle.api.ApkVariantOutput
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential
|
||||
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport
|
||||
import com.google.api.client.http.FileContent
|
||||
import com.google.api.client.http.javanet.NetHttpTransport
|
||||
import com.google.api.client.json.GenericJson
|
||||
import com.google.api.client.json.jackson2.JacksonFactory
|
||||
import com.google.api.services.androidpublisher.AndroidPublisher
|
||||
import com.google.api.services.androidpublisher.AndroidPublisherScopes
|
||||
import com.google.api.services.androidpublisher.model.ExpansionFile
|
||||
import com.google.api.services.androidpublisher.model.ExpansionFilesUploadResponse
|
||||
import com.google.api.services.androidpublisher.model.Track
|
||||
import com.google.api.services.androidpublisher.model.TrackRelease
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.security.KeyStore
|
||||
|
||||
fun createPublisher(auth: File): AndroidPublisher {
|
||||
val transport = buildTransport()
|
||||
val factory = JacksonFactory.getDefaultInstance()
|
||||
|
||||
val credential =
|
||||
GoogleCredential.fromStream(auth.inputStream(), transport, factory)
|
||||
.createScoped(listOf(AndroidPublisherScopes.ANDROIDPUBLISHER))
|
||||
|
||||
|
||||
return AndroidPublisher.Builder(transport, JacksonFactory.getDefaultInstance()) {
|
||||
credential.initialize(it.setReadTimeout(0))
|
||||
}.setApplicationName("kiwixcustom").build()
|
||||
}
|
||||
|
||||
private fun buildTransport(): NetHttpTransport {
|
||||
val trustStore: String? = System.getProperty("javax.net.ssl.trustStore", null)
|
||||
val trustStorePassword: String? =
|
||||
System.getProperty("javax.net.ssl.trustStorePassword", null)
|
||||
|
||||
return if (trustStore == null) {
|
||||
GoogleNetHttpTransport.newTrustedTransport()
|
||||
} else {
|
||||
val ks = KeyStore.getInstance(KeyStore.getDefaultType())
|
||||
FileInputStream(trustStore).use { fis ->
|
||||
ks.load(fis, trustStorePassword?.toCharArray())
|
||||
}
|
||||
NetHttpTransport.Builder().trustCertificates(ks).build()
|
||||
}
|
||||
}
|
||||
|
||||
class Transaction(
|
||||
private val publisher: AndroidPublisher,
|
||||
private val packageName: String,
|
||||
val editId: String
|
||||
) {
|
||||
fun uploadExpansionTo(
|
||||
file: File,
|
||||
apkVariantOutput: ApkVariantOutput
|
||||
): ExpansionFilesUploadResponse = publisher.edits().expansionfiles()
|
||||
.upload(
|
||||
packageName,
|
||||
editId,
|
||||
apkVariantOutput.versionCodeOverride,
|
||||
"main",
|
||||
FileContent("application/octet-stream", file)
|
||||
).execute().prettyPrint()
|
||||
|
||||
fun attachExpansionTo(expansionCode: Int, apkVariantOutput: ApkVariantOutput): ExpansionFile =
|
||||
publisher.edits().expansionfiles().update(
|
||||
packageName,
|
||||
editId,
|
||||
apkVariantOutput.versionCodeOverride,
|
||||
"main",
|
||||
ExpansionFile().apply { referencesVersion = expansionCode }
|
||||
).execute().prettyPrint()
|
||||
|
||||
fun uploadApk(apkVariantOutput: ApkVariantOutput) {
|
||||
publisher.edits().apks().upload(
|
||||
packageName,
|
||||
editId,
|
||||
FileContent("application/octet-stream", apkVariantOutput.outputFile)
|
||||
).execute().prettyPrint()
|
||||
}
|
||||
|
||||
fun addToTrackInDraft(apkVariants: List<ApkVariantOutput>): Track =
|
||||
publisher.edits().tracks().update(packageName, editId, "alpha", Track().apply {
|
||||
releases = listOf(TrackRelease().apply {
|
||||
status = "draft"
|
||||
name = apkVariants[0].versionNameOverride
|
||||
versionCodes = apkVariants.map { it.versionCodeOverride.toLong() }
|
||||
})
|
||||
track = "alpha"
|
||||
}).execute().prettyPrint()
|
||||
}
|
||||
|
||||
fun AndroidPublisher.transactionWithCommit(packageName: String, func: Transaction.() -> Unit) {
|
||||
Transaction(
|
||||
this,
|
||||
packageName,
|
||||
edits().insert(packageName, null).execute().prettyPrint().id
|
||||
).apply {
|
||||
func()
|
||||
edits().validate(packageName, editId).execute().prettyPrint()
|
||||
}.also { edits().commit(packageName, it.editId).execute().prettyPrint() }
|
||||
}
|
||||
|
||||
private fun <T : GenericJson> T.prettyPrint() = also { println(it.toPrettyString()) }
|
@ -22,7 +22,6 @@ import Libs
|
||||
import com.android.build.VariantOutput
|
||||
import com.android.build.gradle.AppExtension
|
||||
import com.android.build.gradle.api.ApkVariantOutput
|
||||
import com.github.triplet.gradle.play.PlayPublisherExtension
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.dependencies
|
||||
import org.gradle.kotlin.dsl.exclude
|
||||
@ -37,7 +36,7 @@ class AppConfigurer {
|
||||
}
|
||||
signingConfigs {
|
||||
create("releaseSigningConfig") {
|
||||
this.storeFile = File(target.rootDir, "kiwix-android.keystore")
|
||||
storeFile = File(target.rootDir, "kiwix-android.keystore")
|
||||
storePassword = System.getenv("KEY_STORE_PASSWORD") ?: "000000"
|
||||
keyAlias = System.getenv("KEY_ALIAS") ?: "keystore"
|
||||
keyPassword = System.getenv("KEY_PASSWORD") ?: "000000"
|
||||
@ -76,13 +75,6 @@ class AppConfigurer {
|
||||
cruncherEnabled = true
|
||||
}
|
||||
}
|
||||
target.plugins.apply("com.github.triplet.play")
|
||||
target.configureExtension<PlayPublisherExtension> {
|
||||
isEnabled = true
|
||||
serviceAccountCredentials = File(target.rootDir, "google.json")
|
||||
track = "alpha"
|
||||
releaseStatus = "draft"
|
||||
}
|
||||
configureDependencies(target)
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,6 @@ import org.kiwix.kiwixmobile.core.downloader.DownloadRequester
|
||||
import org.kiwix.kiwixmobile.core.downloader.model.DownloadModel
|
||||
import org.kiwix.kiwixmobile.core.downloader.model.DownloadRequest
|
||||
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity.Book
|
||||
import org.kiwix.kiwixmobile.core.entity.MetaLinkNetworkEntity
|
||||
import org.kiwix.kiwixmobile.core.dao.entities.FetchDownloadEntity
|
||||
import org.kiwix.kiwixmobile.core.dao.entities.FetchDownloadEntity_
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk
|
||||
@ -79,7 +78,7 @@ class FetchDownloadDao @Inject constructor(
|
||||
}
|
||||
|
||||
fun addIfDoesNotExist(
|
||||
metaLinkNetworkEntity: MetaLinkNetworkEntity,
|
||||
url: String,
|
||||
book: Book,
|
||||
downloadRequester: DownloadRequester
|
||||
) {
|
||||
@ -88,7 +87,7 @@ class FetchDownloadDao @Inject constructor(
|
||||
insert(
|
||||
downloadRequester.enqueue(
|
||||
DownloadRequest(
|
||||
metaLinkNetworkEntity,
|
||||
url,
|
||||
book
|
||||
)
|
||||
),
|
||||
|
@ -18,10 +18,12 @@
|
||||
|
||||
package org.kiwix.kiwixmobile.core.downloader
|
||||
|
||||
import io.reactivex.Observable
|
||||
import org.kiwix.kiwixmobile.core.dao.FetchDownloadDao
|
||||
import org.kiwix.kiwixmobile.core.data.remote.KiwixService
|
||||
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity
|
||||
import org.kiwix.kiwixmobile.core.downloader.model.DownloadItem
|
||||
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity
|
||||
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity.Book
|
||||
import javax.inject.Inject
|
||||
|
||||
class DownloaderImpl @Inject constructor(
|
||||
@ -31,7 +33,7 @@ class DownloaderImpl @Inject constructor(
|
||||
) : Downloader {
|
||||
|
||||
override fun download(book: LibraryNetworkEntity.Book) {
|
||||
kiwixService.getMetaLinks(book.url)
|
||||
urlProvider(book)
|
||||
.take(1)
|
||||
.subscribe(
|
||||
{
|
||||
@ -41,6 +43,10 @@ class DownloaderImpl @Inject constructor(
|
||||
)
|
||||
}
|
||||
|
||||
private fun urlProvider(book: Book): Observable<String> =
|
||||
if (book.url.endsWith("meta4")) kiwixService.getMetaLinks(book.url).map { it.relevantUrl.value }
|
||||
else Observable.just(book.url)
|
||||
|
||||
override fun cancelDownload(downloadItem: DownloadItem) {
|
||||
downloadRequester.cancel(downloadItem)
|
||||
}
|
||||
|
@ -18,8 +18,7 @@
|
||||
package org.kiwix.kiwixmobile.core.downloader.model
|
||||
|
||||
import android.net.Uri
|
||||
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity
|
||||
import org.kiwix.kiwixmobile.core.entity.MetaLinkNetworkEntity
|
||||
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity.Book
|
||||
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
||||
import org.kiwix.kiwixmobile.core.utils.StorageUtils
|
||||
|
||||
@ -31,14 +30,7 @@ data class DownloadRequest(
|
||||
|
||||
val uri: Uri get() = Uri.parse(urlString)
|
||||
|
||||
constructor(
|
||||
metaLinkNetworkEntity: MetaLinkNetworkEntity,
|
||||
book: LibraryNetworkEntity.Book
|
||||
) : this(
|
||||
metaLinkNetworkEntity.relevantUrl.value,
|
||||
book.title,
|
||||
book.description
|
||||
)
|
||||
constructor(url: String, book: Book) : this(url, book.title, book.description)
|
||||
|
||||
fun getDestination(sharedPreferenceUtil: SharedPreferenceUtil): String =
|
||||
"${sharedPreferenceUtil.prefStorage}/Kiwix/${
|
||||
|
@ -1089,10 +1089,7 @@ public abstract class CoreMainActivity extends BaseActivity implements WebViewCa
|
||||
switch (requestCode) {
|
||||
case REQUEST_STORAGE_PERMISSION: {
|
||||
if (hasPermission(Manifest.permission.READ_EXTERNAL_STORAGE)) {
|
||||
finish();
|
||||
Intent newZimFile = Intents.internal(CoreMainActivity.class);
|
||||
newZimFile.setData(Uri.fromFile(file));
|
||||
startActivity(newZimFile);
|
||||
openZimFile(file);
|
||||
} else {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this, dialogStyle());
|
||||
builder.setMessage(getResources().getString(R.string.reboot_message));
|
||||
|
@ -1,5 +1,13 @@
|
||||
import com.android.build.gradle.api.ApkVariantOutput
|
||||
import com.android.build.gradle.api.ApplicationVariant
|
||||
import com.android.build.gradle.internal.dsl.ProductFlavor
|
||||
import custom.createPublisher
|
||||
import custom.transactionWithCommit
|
||||
import plugin.KiwixConfigurationPlugin
|
||||
import java.net.URI
|
||||
import java.net.URL
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
|
||||
plugins {
|
||||
android
|
||||
@ -12,20 +20,128 @@ android {
|
||||
}
|
||||
|
||||
flavorDimensions("default")
|
||||
productFlavors {
|
||||
|
||||
// productFlavors {
|
||||
// create("customexample") {
|
||||
// versionName = "2017-07"
|
||||
// versionCode = 1
|
||||
// applicationIdSuffix = ".kiwixcustomexample"
|
||||
// configureStrings("Test Custom App")
|
||||
// }
|
||||
// }
|
||||
create(
|
||||
CustomFlavor(
|
||||
flavorName = "customexample",
|
||||
versionName = "2017-07",
|
||||
url = "http://download.kiwix.org/zim/wikipedia_fr_test.zim",
|
||||
enforcedLanguage = "en",
|
||||
appName = "Test Custom App"
|
||||
),
|
||||
CustomFlavor(
|
||||
flavorName = "wikimed",
|
||||
versionName = "2018-08",
|
||||
url = "http://download.kiwix.org/zim/wikipedia_en_medicine_novid.zim",
|
||||
enforcedLanguage = "en",
|
||||
appName = "Medical Wikipedia"
|
||||
)
|
||||
)
|
||||
all {
|
||||
val zimFile = File("$projectDir/src", "$name/$name.zim")
|
||||
createDownloadTask(zimFile)
|
||||
createPublishApkWithExpansionTask(name, zimFile, applicationVariants)
|
||||
}
|
||||
}
|
||||
splits {
|
||||
abi {
|
||||
isUniversalApk = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply(from = File("dynamic_flavors.gradle"))
|
||||
// apply(from = File("dynamic_flavors.gradle"))
|
||||
|
||||
fun ProductFlavor.configureStrings(appName: String) {
|
||||
resValue("string", "app_name", appName)
|
||||
resValue("string", "app_search_string", "Search $appName")
|
||||
}
|
||||
|
||||
fun ProductFlavor.fetchUrl(): String {
|
||||
val urlConnection =
|
||||
URI.create(buildConfigFields["ZIM_URL"]!!.value.replace("\"", "")).toURL()
|
||||
.openConnection()
|
||||
urlConnection.connect()
|
||||
urlConnection.getInputStream()
|
||||
return urlConnection
|
||||
.getHeaderField("Location")
|
||||
?.replace("https", "http")
|
||||
?: urlConnection.url.toString()
|
||||
}
|
||||
|
||||
fun NamedDomainObjectContainer<ProductFlavor>.create(vararg customFlavors: CustomFlavor) {
|
||||
customFlavors.forEach { customFlavor ->
|
||||
create(customFlavor.flavorName) {
|
||||
versionName = customFlavor.versionName
|
||||
versionCode = customFlavor.versionCode
|
||||
applicationIdSuffix = ".kiwixcustom${customFlavor.flavorName}"
|
||||
buildConfigField("String", "ZIM_URL", "\"${customFlavor.url}\"")
|
||||
buildConfigField("String", "ENFORCED_LANG", "\"${customFlavor.enforcedLanguage}\"")
|
||||
configureStrings(customFlavor.appName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class CustomFlavor(
|
||||
val flavorName: String,
|
||||
val versionName: String,
|
||||
val versionCode: Int = Date().let {
|
||||
SimpleDateFormat("YYDDD0").format(it).toInt()
|
||||
},
|
||||
val url: String,
|
||||
val enforcedLanguage: String,
|
||||
val appName: String
|
||||
)
|
||||
|
||||
fun ProductFlavor.createDownloadTask(file: File): Task {
|
||||
return tasks.create("download${name.capitalize()}Zim") {
|
||||
group = "Downloading"
|
||||
doLast {
|
||||
if (!file.exists()) {
|
||||
file.createNewFile()
|
||||
URL(fetchUrl()).openStream().use {
|
||||
it.copyTo(file.outputStream())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun ProductFlavor.createPublishApkWithExpansionTask(
|
||||
flavorName: String,
|
||||
file: File,
|
||||
applicationVariants: DomainObjectSet<ApplicationVariant>
|
||||
): Task {
|
||||
return tasks.create("publish${flavorName.capitalize()}ReleaseApkWithExpansionFile") {
|
||||
group = "publishing"
|
||||
description = "Uploads ${flavorName.capitalize()} to the Play Console with an Expansion file"
|
||||
doLast {
|
||||
val packageName = "org.kiwix$applicationIdSuffix"
|
||||
println("packageName $packageName")
|
||||
val apkVariants = getApkVariants(applicationVariants, flavorName)
|
||||
createPublisher(File(rootDir, "google.json"))
|
||||
.transactionWithCommit(packageName) {
|
||||
apkVariants.forEach(::uploadApk)
|
||||
uploadExpansionTo(file, apkVariants[0])
|
||||
apkVariants.drop(1).forEach {
|
||||
attachExpansionTo(apkVariants[0].versionCodeOverride, it)
|
||||
}
|
||||
addToTrackInDraft(apkVariants)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
afterEvaluate {
|
||||
tasks.filter { it.name.contains("ReleaseApkWithExpansionFile") }.forEach {
|
||||
val flavorName =
|
||||
it.name.substringAfter("publish").substringBefore("ReleaseApkWithExpansionFile")
|
||||
it.dependsOn.add(tasks.getByName("download${flavorName}Zim"))
|
||||
it.dependsOn.add(tasks.getByName("assemble${flavorName}Release"))
|
||||
}
|
||||
}
|
||||
|
||||
fun getApkVariants(applicationVariants: DomainObjectSet<ApplicationVariant>, flavorName: String) =
|
||||
applicationVariants.find {
|
||||
it.name.contains("release", true) && it.name.contains(flavorName, true)
|
||||
}!!.outputs.filterIsInstance<ApkVariantOutput>().sortedBy { it.versionCodeOverride }
|
||||
|
@ -1,15 +0,0 @@
|
||||
android {
|
||||
def f = file(buildscript.sourceFile.parent + "/wikipedia_fr_test_2017-07.zim");
|
||||
if (!f.exists()) {
|
||||
URLConnection urlConnection = new URL('http://download.kiwix.org/zim/wikipedia_fr_test.zim').
|
||||
openConnection()
|
||||
urlConnection.connect()
|
||||
urlConnection.getInputStream()
|
||||
String url = urlConnection.getURL().toString()
|
||||
if (urlConnection.getHeaderField("Location") != null) {
|
||||
url = urlConnection.getHeaderField("Location")
|
||||
url = url.replace("https", "http")
|
||||
}
|
||||
new URL(url).withInputStream { i -> f.withOutputStream { it << i } }
|
||||
}
|
||||
}
|
@ -18,11 +18,9 @@
|
||||
|
||||
package org.kiwix.kiwixmobile.custom.main
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.Menu
|
||||
import org.kiwix.kiwixmobile.core.CoreApp
|
||||
import org.kiwix.kiwixmobile.core.R
|
||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.start
|
||||
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
|
||||
@ -34,7 +32,6 @@ import org.kiwix.kiwixmobile.custom.customActivityComponent
|
||||
import org.kiwix.kiwixmobile.custom.download.CustomDownloadActivity
|
||||
import org.kiwix.kiwixmobile.custom.main.ValidationState.HasBothFiles
|
||||
import org.kiwix.kiwixmobile.custom.main.ValidationState.HasFile
|
||||
import java.io.File
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -57,7 +54,7 @@ class CustomMainActivity : CoreMainActivity() {
|
||||
super.onCreate(savedInstanceState)
|
||||
requireEnforcedLanguage()
|
||||
customFileValidator.validate(
|
||||
{
|
||||
onFilesFound = {
|
||||
when (it) {
|
||||
is HasFile -> openZimFile(it.file)
|
||||
is HasBothFiles -> {
|
||||
@ -66,7 +63,7 @@ class CustomMainActivity : CoreMainActivity() {
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
onNoFilesFound = {
|
||||
finish()
|
||||
start<CustomDownloadActivity>()
|
||||
}
|
||||
@ -90,7 +87,7 @@ class CustomMainActivity : CoreMainActivity() {
|
||||
if (BuildConfig.ENFORCED_LANG.isNotEmpty() && BuildConfig.ENFORCED_LANG != currentLocaleCode) {
|
||||
LanguageUtils.handleLocaleChange(this, BuildConfig.ENFORCED_LANG)
|
||||
sharedPreferenceUtil.putPrefLanguage(BuildConfig.ENFORCED_LANG)
|
||||
startActivity(Intent(this, this.javaClass))
|
||||
recreate()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@ -99,12 +96,4 @@ class CustomMainActivity : CoreMainActivity() {
|
||||
override fun manageZimFiles(tab: Int) {
|
||||
TODO("not implemented")
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun getExpansionAPKFileName() =
|
||||
"main.${BuildConfig.CONTENT_VERSION_CODE}.${CoreApp.getInstance().packageName}.obb"
|
||||
|
||||
fun generateExpansionFilePath(fileName: String = getExpansionAPKFileName()) =
|
||||
"${CoreApp.getInstance().obbDir}${File.separator}$fileName"
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user