This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
"精简打包应用模板 APK 文件大小",
|
"精简打包应用模板 APK 文件大小",
|
||||||
"打包页面支持 Pinyin 库选项",
|
"打包页面支持 Pinyin 库选项",
|
||||||
"打包应用主活动页面优化状态栏背景及文字颜色",
|
"打包应用主活动页面优化状态栏背景及文字颜色",
|
||||||
|
"脚本项目配置文件 project.json 支持更多打包选项 _[`issue #305`](http://issues.autojs6.com/305)_ _[`issue #306`](http://issues.autojs6.com/306)_",
|
||||||
"APK 文件类型信息对话框增加文件大小与签名方案信息",
|
"APK 文件类型信息对话框增加文件大小与签名方案信息",
|
||||||
"APK 文件类型信息对话框增加点击监听器支持文本复制与应用详情跳转",
|
"APK 文件类型信息对话框增加点击监听器支持文本复制与应用详情跳转",
|
||||||
"尝试恢复 com.stardust 前缀包以便提升代码兼容性 _[`issue #290`](http://issues.autojs6.com/290)_",
|
"尝试恢复 com.stardust 前缀包以便提升代码兼容性 _[`issue #290`](http://issues.autojs6.com/290)_",
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package org.autojs.autojs.annotation
|
||||||
|
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD, AnnotationTarget.FUNCTION)
|
||||||
|
annotation class SerializedNameCompatible(vararg val with: With) {
|
||||||
|
annotation class With(val value: String, val target: Array<String> = ["AutoJs6"], val isReversed: Boolean = false)
|
||||||
|
}
|
||||||
@@ -5,7 +5,6 @@ import android.content.pm.PackageManager.ApplicationInfoFlags
|
|||||||
import android.content.pm.PackageManager.GET_SHARED_LIBRARY_FILES
|
import android.content.pm.PackageManager.GET_SHARED_LIBRARY_FILES
|
||||||
import android.content.res.AssetManager
|
import android.content.res.AssetManager
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.mcal.apksigner.ApkSigner
|
import com.mcal.apksigner.ApkSigner
|
||||||
@@ -13,7 +12,6 @@ import com.reandroid.arsc.chunk.TableBlock
|
|||||||
import org.apache.commons.io.FileUtils.copyFile
|
import org.apache.commons.io.FileUtils.copyFile
|
||||||
import org.apache.commons.io.FileUtils.copyInputStreamToFile
|
import org.apache.commons.io.FileUtils.copyInputStreamToFile
|
||||||
import org.autojs.autojs.apkbuilder.keystore.AESUtils
|
import org.autojs.autojs.apkbuilder.keystore.AESUtils
|
||||||
import org.autojs.autojs.apkbuilder.keystore.KeyStore
|
|
||||||
import org.autojs.autojs.app.GlobalAppContext
|
import org.autojs.autojs.app.GlobalAppContext
|
||||||
import org.autojs.autojs.engine.encryption.AdvancedEncryptionStandard
|
import org.autojs.autojs.engine.encryption.AdvancedEncryptionStandard
|
||||||
import org.autojs.autojs.pio.PFiles
|
import org.autojs.autojs.pio.PFiles
|
||||||
@@ -35,7 +33,6 @@ import java.io.FileNotFoundException
|
|||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.util.concurrent.Callable
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Stardust on Oct 24, 2017.
|
* Created by Stardust on Oct 24, 2017.
|
||||||
@@ -49,7 +46,7 @@ open class ApkBuilder(apkInputStream: InputStream?, private val outApkFile: File
|
|||||||
private var mInitVector: String? = null
|
private var mInitVector: String? = null
|
||||||
private var mKey: String? = null
|
private var mKey: String? = null
|
||||||
|
|
||||||
private lateinit var mAppConfig: AppConfig
|
private lateinit var mProjectConfig: ProjectConfig
|
||||||
|
|
||||||
private val mApkPackager = ApkPackager(apkInputStream, workspacePath)
|
private val mApkPackager = ApkPackager(apkInputStream, workspacePath)
|
||||||
|
|
||||||
@@ -59,6 +56,9 @@ open class ApkBuilder(apkInputStream: InputStream?, private val outApkFile: File
|
|||||||
private var mAssetsFileIncludes = Libs.defaultAssetFilesToInclude.toMutableList()
|
private var mAssetsFileIncludes = Libs.defaultAssetFilesToInclude.toMutableList()
|
||||||
private var mAssetsDirExcludes = Libs.defaultAssetDirsToExclude.toMutableList()
|
private var mAssetsDirExcludes = Libs.defaultAssetDirsToExclude.toMutableList()
|
||||||
|
|
||||||
|
private var mSplashThemeId = 0
|
||||||
|
private var mNoSplashThemeId = 0
|
||||||
|
|
||||||
private val mManifestFile
|
private val mManifestFile
|
||||||
get() = File(workspacePath, "AndroidManifest.xml")
|
get() = File(workspacePath, "AndroidManifest.xml")
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ open class ApkBuilder(apkInputStream: InputStream?, private val outApkFile: File
|
|||||||
srcChildFile.copyTo(File(destDirFile, srcChildFile.name), true)
|
srcChildFile.copyTo(File(destDirFile, srcChildFile.name), true)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!mAppConfig.ignoredDirs.contains(srcChildFile)) {
|
if (!mProjectConfig.ignoredDirs.contains(srcChildFile)) {
|
||||||
copyDir(srcChildFile, PFiles.join(relativeDestPath, srcChildFile.name + File.separator))
|
copyDir(srcChildFile, PFiles.join(relativeDestPath, srcChildFile.name + File.separator))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,10 +141,27 @@ open class ApkBuilder(apkInputStream: InputStream?, private val outApkFile: File
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun withConfig(config: AppConfig) = also {
|
fun withConfig(config: ProjectConfig) = also {
|
||||||
config.also { mAppConfig = it }.run {
|
config.also { mProjectConfig = it }.run {
|
||||||
|
if (!launchConfig.isSplashVisible) {
|
||||||
|
try {
|
||||||
|
val tableBlock = TableBlock.load(mResourcesArscFile)
|
||||||
|
val packageName = "${GlobalAppContext.get().packageName}.inrt"
|
||||||
|
val packageBlock = tableBlock.getOrCreatePackage(0x7f, packageName).also {
|
||||||
|
tableBlock.currentPackage = it
|
||||||
|
}
|
||||||
|
packageBlock.getEntry("", "style", "AppTheme.Splash")?.let {
|
||||||
|
mSplashThemeId = it.resourceId
|
||||||
|
}
|
||||||
|
packageBlock.getEntry("", "style", "AppTheme.SevereTransparent")?.let {
|
||||||
|
mNoSplashThemeId = it.resourceId
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
mManifestEditor = editManifest()
|
mManifestEditor = editManifest()
|
||||||
.setAppName(appName)
|
.setAppName(name)
|
||||||
.setVersionName(versionName)
|
.setVersionName(versionName)
|
||||||
.setVersionCode(versionCode)
|
.setVersionCode(versionCode)
|
||||||
.setPackageName(packageName)
|
.setPackageName(packageName)
|
||||||
@@ -160,32 +177,32 @@ open class ApkBuilder(apkInputStream: InputStream?, private val outApkFile: File
|
|||||||
@Throws(FileNotFoundException::class)
|
@Throws(FileNotFoundException::class)
|
||||||
fun editManifest(): ManifestEditor = ManifestEditorWithAuthorities(FileInputStream(mManifestFile)).also { mManifestEditor = it }
|
fun editManifest(): ManifestEditor = ManifestEditorWithAuthorities(FileInputStream(mManifestFile)).also { mManifestEditor = it }
|
||||||
|
|
||||||
private fun updateProjectConfig(appConfig: AppConfig) {
|
private fun updateProjectConfig(config: ProjectConfig) {
|
||||||
val projectConfig = when {
|
val projectConfig = when {
|
||||||
!PFiles.isDir(appConfig.sourcePath) -> null
|
!PFiles.isDir(config.sourcePath) -> null
|
||||||
else -> ProjectConfig.fromProjectDir(appConfig.sourcePath)?.also {
|
else -> ProjectConfig.fromProjectDir(config.sourcePath)?.also {
|
||||||
val buildNumber = it.buildInfo.buildNumber
|
val buildNumber = it.buildInfo.buildNumber
|
||||||
it.buildInfo = BuildInfo.generate(buildNumber + 1)
|
it.buildInfo = BuildInfo.generate(buildNumber + 1)
|
||||||
PFiles.write(ProjectConfig.configFileOfDir(appConfig.sourcePath), it.toJson())
|
PFiles.write(ProjectConfig.configFileOfDir(config.sourcePath), it.toJson())
|
||||||
}
|
}
|
||||||
} ?: ProjectConfig()
|
} ?: ProjectConfig()
|
||||||
.setMainScriptFile("main.js")
|
.setMainScriptFile("main.js")
|
||||||
.setName(appConfig.appName)
|
.setName(config.name)
|
||||||
.setPackageName(appConfig.packageName)
|
.setPackageName(config.packageName)
|
||||||
.setVersionName(appConfig.versionName)
|
.setVersionName(config.versionName)
|
||||||
.setVersionCode(appConfig.versionCode)
|
.setVersionCode(config.versionCode)
|
||||||
.also { config ->
|
.also { newProjectConfig ->
|
||||||
config.buildInfo = BuildInfo.generate(appConfig.versionCode.toLong())
|
newProjectConfig.buildInfo = BuildInfo.generate(newProjectConfig.versionCode.toLong())
|
||||||
File(workspacePath, "assets/project/${ProjectConfig.CONFIG_FILE_NAME}").also { file ->
|
File(workspacePath, "assets/project/${ProjectConfig.CONFIG_FILE_NAME}").also { file ->
|
||||||
file.parentFile?.let { parent -> if (!parent.exists()) parent.mkdirs() }
|
file.parentFile?.let { parent -> if (!parent.exists()) parent.mkdirs() }
|
||||||
}.writeText(config.toJson())
|
}.writeText(newProjectConfig.toJson())
|
||||||
}
|
}
|
||||||
|
|
||||||
projectConfig.run {
|
projectConfig.run {
|
||||||
mKey = MD5Utils.md5(packageName + versionName + mainScriptFile)
|
mKey = MD5Utils.md5(packageName + versionName + mainScriptFile)
|
||||||
mInitVector = MD5Utils.md5(buildInfo.buildId + name).substring(0, 16)
|
mInitVector = MD5Utils.md5(buildInfo.buildId + name).substring(0, 16)
|
||||||
Libs.entries.forEach { entry ->
|
Libs.entries.forEach { entry ->
|
||||||
if (appConfig.libs.contains(entry.label)) {
|
if (config.libs.contains(entry.label)) {
|
||||||
mLibsIncludes += entry.libsToInclude.toSet()
|
mLibsIncludes += entry.libsToInclude.toSet()
|
||||||
mAssetsFileIncludes += entry.assetFilesToInclude.toSet()
|
mAssetsFileIncludes += entry.assetFilesToInclude.toSet()
|
||||||
mAssetsDirExcludes -= entry.assetDirsToExclude.toSet()
|
mAssetsDirExcludes -= entry.assetDirsToExclude.toSet()
|
||||||
@@ -197,7 +214,7 @@ open class ApkBuilder(apkInputStream: InputStream?, private val outApkFile: File
|
|||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
fun build() = also {
|
fun build() = also {
|
||||||
mProgressCallback?.let { callback -> GlobalAppContext.post { callback.onBuild(this) } }
|
mProgressCallback?.let { callback -> GlobalAppContext.post { callback.onBuild(this) } }
|
||||||
mAppConfig.icon?.let { callable ->
|
mProjectConfig.iconBitmapGetter?.let { callable ->
|
||||||
runCatching {
|
runCatching {
|
||||||
val tableBlock = TableBlock.load(mResourcesArscFile)
|
val tableBlock = TableBlock.load(mResourcesArscFile)
|
||||||
val packageName = "${GlobalAppContext.get().packageName}.inrt"
|
val packageName = "${GlobalAppContext.get().packageName}.inrt"
|
||||||
@@ -264,17 +281,17 @@ open class ApkBuilder(apkInputStream: InputStream?, private val outApkFile: File
|
|||||||
|
|
||||||
val signer = ApkSigner(outApkFile, tmpOutputApk)
|
val signer = ApkSigner(outApkFile, tmpOutputApk)
|
||||||
signer.useDefaultSignatureVersion = false
|
signer.useDefaultSignatureVersion = false
|
||||||
signer.v1SigningEnabled = mAppConfig.signatureSchemes.contains("V1")
|
signer.v1SigningEnabled = mProjectConfig.signatureSchemes.contains("V1")
|
||||||
signer.v2SigningEnabled = mAppConfig.signatureSchemes.contains("V2")
|
signer.v2SigningEnabled = mProjectConfig.signatureSchemes.contains("V2")
|
||||||
signer.v3SigningEnabled = mAppConfig.signatureSchemes.contains("V3")
|
signer.v3SigningEnabled = mProjectConfig.signatureSchemes.contains("V3")
|
||||||
signer.v4SigningEnabled = mAppConfig.signatureSchemes.contains("V4")
|
signer.v4SigningEnabled = mProjectConfig.signatureSchemes.contains("V4")
|
||||||
|
|
||||||
var keyStoreFile = defaultKeyStoreFile
|
var keyStoreFile = defaultKeyStoreFile
|
||||||
var password = "AutoJs6"
|
var password = "AutoJs6"
|
||||||
var alias = "AutoJs6"
|
var alias = "AutoJs6"
|
||||||
var aliasPassword = "AutoJs6"
|
var aliasPassword = "AutoJs6"
|
||||||
|
|
||||||
mAppConfig.keyStore?.let {
|
mProjectConfig.keyStore?.let {
|
||||||
keyStoreFile = File(it.absolutePath)
|
keyStoreFile = File(it.absolutePath)
|
||||||
password = AESUtils.decrypt(it.password)
|
password = AESUtils.decrypt(it.password)
|
||||||
alias = it.alias
|
alias = it.alias
|
||||||
@@ -324,76 +341,14 @@ open class ApkBuilder(apkInputStream: InputStream?, private val outApkFile: File
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class AppConfig {
|
|
||||||
|
|
||||||
var appName: String? = null
|
|
||||||
private set
|
|
||||||
var versionName: String? = null
|
|
||||||
private set
|
|
||||||
var versionCode = 0
|
|
||||||
private set
|
|
||||||
var sourcePath: String? = null
|
|
||||||
private set
|
|
||||||
var packageName: String? = null
|
|
||||||
private set
|
|
||||||
var ignoredDirs = ArrayList<File>()
|
|
||||||
var icon: Callable<Bitmap>? = null
|
|
||||||
private set
|
|
||||||
var abis: List<String> = emptyList()
|
|
||||||
private set
|
|
||||||
var libs: List<String> = emptyList()
|
|
||||||
private set
|
|
||||||
var keyStore: KeyStore? = null
|
|
||||||
private set
|
|
||||||
var signatureSchemes: String = "V1 + V2"
|
|
||||||
private set
|
|
||||||
var permissions: List<String> = emptyList()
|
|
||||||
private set
|
|
||||||
|
|
||||||
fun ignoreDir(dir: File) = also { ignoredDirs.add(dir) }
|
|
||||||
|
|
||||||
fun setAppName(appName: String?) = also { appName?.let { this.appName = it } }
|
|
||||||
|
|
||||||
fun setVersionName(versionName: String?) = also { versionName?.let { this.versionName = it } }
|
|
||||||
|
|
||||||
fun setVersionCode(versionCode: Int?) = also { versionCode?.let { this.versionCode = it } }
|
|
||||||
|
|
||||||
fun setSourcePath(sourcePath: String?) = also { sourcePath?.let { this.sourcePath = it } }
|
|
||||||
|
|
||||||
fun setPackageName(packageName: String?) = also { packageName?.let { this.packageName = it } }
|
|
||||||
|
|
||||||
fun setIcon(icon: Callable<Bitmap>?) = also { icon?.let { this.icon = it } }
|
|
||||||
|
|
||||||
fun setIcon(iconPath: String?) = also { iconPath?.let { this.icon = Callable { BitmapFactory.decodeFile(it) } } }
|
|
||||||
|
|
||||||
fun setAbis(abis: List<String>) = also { this.abis = abis }
|
|
||||||
|
|
||||||
fun setLibs(libs: List<String>) = also { this.libs = libs }
|
|
||||||
|
|
||||||
fun setKeyStore(keyStore: KeyStore?) = also { this.keyStore = keyStore }
|
|
||||||
|
|
||||||
fun setSignatureSchemes(signatureSchemes: String) = also { this.signatureSchemes = signatureSchemes }
|
|
||||||
|
|
||||||
fun setPermissions(permissions: List<String>) = also { this.permissions = permissions }
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
@JvmStatic
|
|
||||||
fun fromProjectConfig(projectDir: String?, projectConfig: ProjectConfig) = AppConfig()
|
|
||||||
.setAppName(projectConfig.name)
|
|
||||||
.setPackageName(projectConfig.packageName)
|
|
||||||
.ignoreDir(File(projectDir, projectConfig.buildDir))
|
|
||||||
.setVersionCode(projectConfig.versionCode)
|
|
||||||
.setVersionName(projectConfig.versionName)
|
|
||||||
.setSourcePath(projectDir)
|
|
||||||
.setIcon(projectConfig.icon?.let { File(projectDir, it).path })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private inner class ManifestEditorWithAuthorities(manifestInputStream: InputStream?) : ManifestEditor(manifestInputStream) {
|
private inner class ManifestEditorWithAuthorities(manifestInputStream: InputStream?) : ManifestEditor(manifestInputStream) {
|
||||||
override fun onAttr(attr: AxmlWriter.Attr) {
|
override fun onAttr(attr: AxmlWriter.Attr) {
|
||||||
attr.apply {
|
attr.apply {
|
||||||
|
if (!mProjectConfig.launchConfig.isSplashVisible && mSplashThemeId != 0 && value == mSplashThemeId) {
|
||||||
|
value = mNoSplashThemeId
|
||||||
|
}
|
||||||
if (name.data == "authorities" && value is StringItem) {
|
if (name.data == "authorities" && value is StringItem) {
|
||||||
(value as StringItem).data = "${mAppConfig.packageName}.fileprovider"
|
(value as StringItem).data = "${mProjectConfig.packageName}.fileprovider"
|
||||||
} else {
|
} else {
|
||||||
super.onAttr(this)
|
super.onAttr(this)
|
||||||
}
|
}
|
||||||
@@ -401,11 +356,11 @@ open class ApkBuilder(apkInputStream: InputStream?, private val outApkFile: File
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun isPermissionRequired(permissionName: String): Boolean {
|
override fun isPermissionRequired(permissionName: String): Boolean {
|
||||||
return mAppConfig.permissions.contains(permissionName)
|
return mProjectConfig.permissions.contains(permissionName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun copyLibrariesByConfig(config: AppConfig) {
|
private fun copyLibrariesByConfig(config: ProjectConfig) {
|
||||||
|
|
||||||
// @Hint by SuperMonster003 on Dec 11, 2023.
|
// @Hint by SuperMonster003 on Dec 11, 2023.
|
||||||
// ! The list contains only abi names not matching the canonical name itself.
|
// ! The list contains only abi names not matching the canonical name itself.
|
||||||
@@ -461,6 +416,7 @@ open class ApkBuilder(apkInputStream: InputStream?, private val outApkFile: File
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("SpellCheckingInspection")
|
||||||
enum class Libs(
|
enum class Libs(
|
||||||
@JvmField val label: String,
|
@JvmField val label: String,
|
||||||
@JvmField val aliases: List<String> = emptyList(),
|
@JvmField val aliases: List<String> = emptyList(),
|
||||||
|
|||||||
@@ -10,10 +10,11 @@ import android.os.Handler
|
|||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import org.autojs.autojs.inrt.autojs.AutoJs
|
import org.autojs.autojs.inrt.autojs.AutoJs
|
||||||
import org.autojs.autojs.inrt.launch.GlobalProjectLauncher
|
import org.autojs.autojs.inrt.launch.GlobalProjectLauncher
|
||||||
|
import org.autojs.autojs.project.ProjectConfig
|
||||||
import org.autojs.autojs.ui.splash.SplashActivity.Companion.INIT_TIMEOUT
|
import org.autojs.autojs.ui.splash.SplashActivity.Companion.INIT_TIMEOUT
|
||||||
import org.autojs.autojs6.R
|
|
||||||
import org.autojs.autojs6.databinding.ActivitySplashInrtBinding
|
import org.autojs.autojs6.databinding.ActivitySplashInrtBinding
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
@@ -24,14 +25,29 @@ import kotlin.concurrent.thread
|
|||||||
class SplashActivity : AppCompatActivity() {
|
class SplashActivity : AppCompatActivity() {
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
setContentView(R.layout.activity_splash_inrt)
|
val binding = ActivitySplashInrtBinding.inflate(layoutInflater).apply {
|
||||||
val binding = ActivitySplashInrtBinding.inflate(layoutInflater)
|
setContentView(root)
|
||||||
binding.slug.typeface = Typeface.createFromAsset(assets, "roboto_medium.ttf")
|
}
|
||||||
|
val handler = Handler(Looper.myLooper()!!)
|
||||||
|
val projectConfig = ProjectConfig.fromAssets(this, ProjectConfig.configFileOfDir("project"))
|
||||||
|
var timeout = INIT_TIMEOUT
|
||||||
|
|
||||||
|
if (!projectConfig.launchConfig.isSplashVisible) {
|
||||||
|
timeout = 0L
|
||||||
|
} else {
|
||||||
|
handler.post {
|
||||||
|
binding.slug.typeface = Typeface.createFromAsset(assets, "roboto_medium.ttf")
|
||||||
|
binding.slug.isVisible = true
|
||||||
|
binding.icon.isVisible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!Pref.isFirstUsing) {
|
if (!Pref.isFirstUsing) {
|
||||||
main()
|
main()
|
||||||
} else {
|
} else {
|
||||||
Handler(Looper.myLooper()!!).postDelayed({ this@SplashActivity.main() }, INIT_TIMEOUT)
|
handler.postDelayed({ this@SplashActivity.main() }, timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ open class AssetsProjectLauncher(private val mAssetsProjectDir: String, private
|
|||||||
|
|
||||||
fun launch(activity: Activity) {
|
fun launch(activity: Activity) {
|
||||||
// 如果需要隐藏日志界面, 则直接运行脚本
|
// 如果需要隐藏日志界面, 则直接运行脚本
|
||||||
if (mProjectConfig.launchConfig.shouldHideLogs() || Pref.shouldHideLogs()) {
|
if (!mProjectConfig.launchConfig.isLogsVisible || Pref.shouldHideLogs()) {
|
||||||
runScript(activity)
|
runScript(activity)
|
||||||
} else {
|
} else {
|
||||||
// 如果不隐藏日志界面
|
// 如果不隐藏日志界面
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import java.util.zip.CRC32;
|
|||||||
|
|
||||||
public class BuildInfo {
|
public class BuildInfo {
|
||||||
|
|
||||||
@SerializedName("build_time")
|
@SerializedName(value = "buildTime", alternate = {"build_time"})
|
||||||
private long mBuildTime;
|
private long mBuildTime;
|
||||||
|
|
||||||
@SerializedName("build_id")
|
@SerializedName(value = "buildId", alternate = {"build_id"})
|
||||||
private String mBuildId;
|
private String mBuildId;
|
||||||
|
|
||||||
@SerializedName("build_number")
|
@SerializedName(value = "buildNumber", alternate = {"build_number"})
|
||||||
private long mBuildNumber;
|
private long mBuildNumber;
|
||||||
|
|
||||||
public long getBuildNumber() {
|
public long getBuildNumber() {
|
||||||
|
|||||||
@@ -1,21 +1,57 @@
|
|||||||
package org.autojs.autojs.project;
|
package org.autojs.autojs.project
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName
|
||||||
|
import org.autojs.autojs.annotation.SerializedNameCompatible
|
||||||
|
import org.autojs.autojs.annotation.SerializedNameCompatible.With
|
||||||
|
import org.autojs.autojs.app.GlobalAppContext
|
||||||
|
import org.autojs.autojs6.R
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Stardust on Jan 25, 2018.
|
* Created by Stardust on Jan 25, 2018.
|
||||||
|
* Modified by SuperMonster003 as of Jan 15, 2025.
|
||||||
|
* Created by SuperMonster003 on Jan 15, 2025.
|
||||||
*/
|
*/
|
||||||
public class LaunchConfig {
|
class LaunchConfig {
|
||||||
|
|
||||||
@SerializedName("hideLogs")
|
@Transient
|
||||||
private boolean mHideLogs = false;
|
private val mContext = GlobalAppContext.get()
|
||||||
|
|
||||||
public boolean shouldHideLogs() {
|
@SerializedName("logsVisible")
|
||||||
return mHideLogs;
|
@field:SerializedNameCompatible(
|
||||||
}
|
With(value = "showLogs"),
|
||||||
|
With(value = "hideLogs", target = ["AutoJs4", "AutoX"], isReversed = true),
|
||||||
|
With(value = "displayLogs"),
|
||||||
|
)
|
||||||
|
var isLogsVisible = true
|
||||||
|
|
||||||
public void setHideLogs(boolean hideLogs) {
|
@SerializedName("splashVisible")
|
||||||
mHideLogs = hideLogs;
|
@field:SerializedNameCompatible(
|
||||||
}
|
With(value = "showSplash"),
|
||||||
|
With(value = "hideSplash", isReversed = true),
|
||||||
|
With(value = "displaySplash", target = ["AutoX"]),
|
||||||
|
)
|
||||||
|
var isSplashVisible = true
|
||||||
|
|
||||||
|
@SerializedName("launcherVisible")
|
||||||
|
@field:SerializedNameCompatible(
|
||||||
|
With(value = "showLauncher"),
|
||||||
|
With(value = "hideLauncher", target = ["AutoX"], isReversed = true),
|
||||||
|
With(value = "displayLauncher"),
|
||||||
|
)
|
||||||
|
var isLauncherVisible = true
|
||||||
|
|
||||||
|
@SerializedName("slug")
|
||||||
|
@field:SerializedNameCompatible(
|
||||||
|
With(value = "slugText"),
|
||||||
|
With(value = "splashText", target = ["AutoX"]),
|
||||||
|
)
|
||||||
|
var slug = mContext.getString(R.string.text_powered_by_autojs)
|
||||||
|
|
||||||
|
@SerializedName("permissions")
|
||||||
|
@field:SerializedNameCompatible(
|
||||||
|
With(value = "permission"),
|
||||||
|
With(value = "permissionList"),
|
||||||
|
)
|
||||||
|
var permissions = emptyList<String>()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
package org.autojs.autojs.project;
|
package org.autojs.autojs.project;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
import org.autojs.autojs.apkbuilder.keystore.KeyStore;
|
||||||
import org.autojs.autojs.model.explorer.ExplorerPage;
|
import org.autojs.autojs.model.explorer.ExplorerPage;
|
||||||
import org.autojs.autojs.pio.PFiles;
|
import org.autojs.autojs.pio.PFiles;
|
||||||
import org.autojs.autojs.util.JsonUtils;
|
import org.autojs.autojs.util.JsonUtils;
|
||||||
@@ -20,6 +23,7 @@ import java.util.Collections;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@@ -30,7 +34,9 @@ public class ProjectConfig {
|
|||||||
|
|
||||||
public static final String CONFIG_FILE_NAME = "project.json";
|
public static final String CONFIG_FILE_NAME = "project.json";
|
||||||
|
|
||||||
private static final Gson sGson = new GsonBuilder().setPrettyPrinting().create();
|
private static final Gson sGson = new GsonBuilder()
|
||||||
|
.setPrettyPrinting()
|
||||||
|
.create();
|
||||||
|
|
||||||
@SerializedName("name")
|
@SerializedName("name")
|
||||||
private String mName;
|
private String mName;
|
||||||
@@ -52,13 +58,15 @@ public class ProjectConfig {
|
|||||||
private List<String> mAssets = new ArrayList<>();
|
private List<String> mAssets = new ArrayList<>();
|
||||||
|
|
||||||
@SerializedName("launchConfig")
|
@SerializedName("launchConfig")
|
||||||
private LaunchConfig mLaunchConfig;
|
private LaunchConfig mLaunchConfig = new LaunchConfig();
|
||||||
|
|
||||||
@SerializedName("build")
|
@SerializedName("build")
|
||||||
private BuildInfo mBuildInfo = new BuildInfo();
|
private BuildInfo mBuildInfo = new BuildInfo();
|
||||||
|
|
||||||
@SerializedName("icon")
|
@SerializedName("icon")
|
||||||
private String mIcon;
|
private String mIconPath;
|
||||||
|
|
||||||
|
private transient Callable<Bitmap> mIconBitmapGetter;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@SerializedName(value = "abis", alternate = {"abi", "abiList"})
|
@SerializedName(value = "abis", alternate = {"abi", "abiList"})
|
||||||
@@ -68,12 +76,27 @@ public class ProjectConfig {
|
|||||||
@SerializedName(value = "libs", alternate = {"lib", "libList"})
|
@SerializedName(value = "libs", alternate = {"lib", "libList"})
|
||||||
private List<String> mLibs = new ArrayList<>();
|
private List<String> mLibs = new ArrayList<>();
|
||||||
|
|
||||||
|
@SerializedName("permissions")
|
||||||
|
private List<String> mPermissions = new ArrayList<>();
|
||||||
|
|
||||||
|
@SerializedName("signatureSchemes")
|
||||||
|
private String mSignatureSchemes = "V1 + V2";
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private transient KeyStore mKeyStore = null;
|
||||||
|
|
||||||
@SerializedName("scripts")
|
@SerializedName("scripts")
|
||||||
private final Map<String, ScriptConfig> mScriptConfigs = new HashMap<>();
|
private final Map<String, ScriptConfig> mScriptConfigs = new HashMap<>();
|
||||||
|
|
||||||
@SerializedName(value = "useFeatures", alternate = {"useFeature", "useFeatureList"})
|
@SerializedName(value = "useFeatures", alternate = {"useFeature", "useFeatureList"})
|
||||||
private List<String> mFeatures = new ArrayList<>();
|
private List<String> mFeatures = new ArrayList<>();
|
||||||
|
|
||||||
|
@SerializedName("ignoredDirs")
|
||||||
|
private final List<File> mIgnoredDirs = new ArrayList<>();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private transient String mSourcePath = null;
|
||||||
|
|
||||||
public static ProjectConfig fromJson(String json) {
|
public static ProjectConfig fromJson(String json) {
|
||||||
if (json == null) {
|
if (json == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -117,7 +140,7 @@ public class ProjectConfig {
|
|||||||
return fromJson(fileContents);
|
return fromJson(fileContents);
|
||||||
} catch (Exception e1) {
|
} catch (Exception e1) {
|
||||||
if (fileContents == null) return null;
|
if (fileContents == null) return null;
|
||||||
try {
|
try {
|
||||||
return fromJson(JsonUtils.repairJson(fileContents));
|
return fromJson(JsonUtils.repairJson(fileContents));
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
return tryReadCrucialData(fileContents, path);
|
return tryReadCrucialData(fileContents, path);
|
||||||
@@ -126,10 +149,9 @@ public class ProjectConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static ProjectConfig tryReadCrucialData(String s, String jsonFilePath) {
|
private static ProjectConfig tryReadCrucialData(String s, String jsonFilePath) {
|
||||||
ProjectConfig config = new ProjectConfig();
|
ProjectConfig projectConfig = new ProjectConfig();
|
||||||
BuildInfo buildInfo = new BuildInfo();
|
|
||||||
ScriptConfig scriptConfig = new ScriptConfig();
|
|
||||||
LaunchConfig launchConfig = new LaunchConfig();
|
LaunchConfig launchConfig = new LaunchConfig();
|
||||||
|
BuildInfo buildInfo = new BuildInfo();
|
||||||
|
|
||||||
Pattern namePattern = Pattern.compile(stringPattern("name"));
|
Pattern namePattern = Pattern.compile(stringPattern("name"));
|
||||||
Pattern versionNamePattern = Pattern.compile(stringPattern("versionName"));
|
Pattern versionNamePattern = Pattern.compile(stringPattern("versionName"));
|
||||||
@@ -147,40 +169,47 @@ public class ProjectConfig {
|
|||||||
Pattern buildNumberPattern = Pattern.compile(numberPattern("buildNumber"));
|
Pattern buildNumberPattern = Pattern.compile(numberPattern("buildNumber"));
|
||||||
Pattern buildIdPattern = Pattern.compile(stringPattern("buildId"));
|
Pattern buildIdPattern = Pattern.compile(stringPattern("buildId"));
|
||||||
|
|
||||||
Pattern launchConfigPattern = Pattern.compile(booleanPattern("hideLogs"));
|
Pattern launchConfigHideLogsPattern = Pattern.compile(booleanPattern("hideLogs"));
|
||||||
|
Pattern launchConfigLogsVisiblePattern = Pattern.compile(booleanPattern("logsVisible"));
|
||||||
|
|
||||||
Pattern scriptsUiModePattern = Pattern.compile(booleanPattern("uiMode"));
|
Pattern launchConfigDisplaySplashPattern = Pattern.compile(booleanPattern("displaySplash"));
|
||||||
|
Pattern launchConfigSplashVisiblePattern = Pattern.compile(booleanPattern("splashVisible"));
|
||||||
|
|
||||||
setFieldIfMatches(namePattern, s, config::setName);
|
setFieldIfMatches(namePattern, s, projectConfig::setName);
|
||||||
setFieldIfMatches(versionNamePattern, s, config::setVersionName);
|
setFieldIfMatches(versionNamePattern, s, projectConfig::setVersionName);
|
||||||
setFieldForIntIfMatches(versionCodePattern, s, config::setVersionCode);
|
setFieldForIntIfMatches(versionCodePattern, s, projectConfig::setVersionCode);
|
||||||
setFieldIfMatches(packageNamePattern, s, config::setPackageName);
|
setFieldIfMatches(packageNamePattern, s, projectConfig::setPackageName);
|
||||||
setFieldIfMatches(mainPattern, s, config::setMainScriptFile);
|
setFieldIfMatches(mainPattern, s, projectConfig::setMainScriptFile);
|
||||||
setFieldIfMatches(iconPattern, s, config::setIcon);
|
setFieldIfMatches(iconPattern, s, projectConfig::setIconPath);
|
||||||
|
|
||||||
setListIfMatches(assetsPattern, s, config::setAssets);
|
setListIfMatches(assetsPattern, s, projectConfig::setAssets);
|
||||||
setListIfMatches(abisPattern, s, config::setAbis);
|
setListIfMatches(abisPattern, s, projectConfig::setAbis);
|
||||||
setListIfMatches(libsPattern, s, config::setLibs);
|
setListIfMatches(libsPattern, s, projectConfig::setLibs);
|
||||||
setListIfMatches(useFeaturesPattern, s, config::setFeatures);
|
setListIfMatches(useFeaturesPattern, s, projectConfig::setFeatures);
|
||||||
|
|
||||||
setFieldForIntIfMatches(buildTimePattern, s, buildInfo::setBuildTime);
|
setFieldForIntIfMatches(buildTimePattern, s, buildInfo::setBuildTime);
|
||||||
setFieldForIntIfMatches(buildNumberPattern, s, buildInfo::setBuildNumber);
|
setFieldForIntIfMatches(buildNumberPattern, s, buildInfo::setBuildNumber);
|
||||||
setFieldIfMatches(buildIdPattern, s, buildInfo::setBuildId);
|
setFieldIfMatches(buildIdPattern, s, buildInfo::setBuildId);
|
||||||
|
|
||||||
setFieldForBooleanIfMatches(launchConfigPattern, s, launchConfig::setHideLogs);
|
setFieldForBooleanIfMatches(launchConfigHideLogsPattern, s, value -> launchConfig.setLogsVisible(!value));
|
||||||
|
setFieldForBooleanIfMatches(launchConfigLogsVisiblePattern, s, launchConfig::setLogsVisible); /* 优先. */
|
||||||
|
|
||||||
setFieldForBooleanIfMatches(scriptsUiModePattern, s, scriptConfig::setUiMode);
|
setFieldForBooleanIfMatches(launchConfigDisplaySplashPattern, s, launchConfig::setSplashVisible);
|
||||||
|
setFieldForBooleanIfMatches(launchConfigSplashVisiblePattern, s, launchConfig::setSplashVisible); /* 优先. */
|
||||||
|
|
||||||
if (config.getName() == null || config.getName().isBlank()) {
|
if (projectConfig.getName() == null || projectConfig.getName().isBlank()) {
|
||||||
if (jsonFilePath.endsWith(CONFIG_FILE_NAME)) {
|
if (jsonFilePath.endsWith(CONFIG_FILE_NAME)) {
|
||||||
File parentFile = new File(jsonFilePath).getParentFile();
|
File parentFile = new File(jsonFilePath).getParentFile();
|
||||||
if (parentFile != null) {
|
if (parentFile != null) {
|
||||||
config.setName(parentFile.getName());
|
projectConfig.setName(parentFile.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return config;
|
projectConfig.setBuildInfo(buildInfo);
|
||||||
|
projectConfig.setLaunchConfig(launchConfig);
|
||||||
|
|
||||||
|
return projectConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -350,13 +379,10 @@ public class ProjectConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public LaunchConfig getLaunchConfig() {
|
public LaunchConfig getLaunchConfig() {
|
||||||
if (mLaunchConfig == null) {
|
|
||||||
mLaunchConfig = new LaunchConfig();
|
|
||||||
}
|
|
||||||
return mLaunchConfig;
|
return mLaunchConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLaunchConfig(LaunchConfig launchConfig) {
|
public void setLaunchConfig(@NonNull LaunchConfig launchConfig) {
|
||||||
mLaunchConfig = launchConfig;
|
mLaunchConfig = launchConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,12 +390,23 @@ public class ProjectConfig {
|
|||||||
return sGson.toJson(this);
|
return sGson.toJson(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getIcon() {
|
public String getIconPath() {
|
||||||
return mIcon;
|
return mIconPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIcon(String icon) {
|
public ProjectConfig setIconPath(String iconPath) {
|
||||||
mIcon = icon;
|
mIconPath = iconPath;
|
||||||
|
mIconBitmapGetter = () -> BitmapFactory.decodeFile(iconPath);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Callable<Bitmap> getIconBitmapGetter() {
|
||||||
|
return mIconBitmapGetter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProjectConfig setIconGetter(@Nullable Callable<Bitmap> getter) {
|
||||||
|
mIconBitmapGetter = getter;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getAbis() {
|
public List<String> getAbis() {
|
||||||
@@ -379,8 +416,9 @@ public class ProjectConfig {
|
|||||||
return mAbis;
|
return mAbis;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAbis(@Nullable List<String> abis) {
|
public ProjectConfig setAbis(@Nullable List<String> abis) {
|
||||||
mAbis = abis;
|
mAbis = abis;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getLibs() {
|
public List<String> getLibs() {
|
||||||
@@ -390,8 +428,9 @@ public class ProjectConfig {
|
|||||||
return mLibs;
|
return mLibs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLibs(@Nullable List<String> libs) {
|
public ProjectConfig setLibs(@Nullable List<String> libs) {
|
||||||
mLibs = libs;
|
mLibs = libs;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBuildDir() {
|
public String getBuildDir() {
|
||||||
@@ -427,4 +466,51 @@ public class ProjectConfig {
|
|||||||
config.setFeatures(features);
|
config.setFeatures(features);
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<File> getIgnoredDirs() {
|
||||||
|
return mIgnoredDirs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProjectConfig ignoredDir(File ignoredDir) {
|
||||||
|
mIgnoredDirs.add(ignoredDir);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getSourcePath() {
|
||||||
|
return mSourcePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProjectConfig setSourcePath(@Nullable String sourcePath) {
|
||||||
|
mSourcePath = sourcePath;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getPermissions() {
|
||||||
|
return mPermissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProjectConfig setPermissions(List<String> permissions) {
|
||||||
|
mPermissions = permissions;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSignatureSchemes() {
|
||||||
|
return mSignatureSchemes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProjectConfig setSignatureSchemes(String signatureSchemes) {
|
||||||
|
mSignatureSchemes = signatureSchemes;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public KeyStore getKeyStore() {
|
||||||
|
return mKeyStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProjectConfig setKeyStore(@Nullable KeyStore keyStore) {
|
||||||
|
mKeyStore = keyStore;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,17 +2,14 @@ package org.autojs.autojs.project
|
|||||||
|
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
data class ScriptConfig(
|
data class ScriptConfig @JvmOverloads constructor(
|
||||||
@SerializedName("useFeatures") var features: List<String>,
|
@SerializedName("useFeatures") var features: List<String> = emptyList(),
|
||||||
@SerializedName("uiMode") var uiMode: Boolean
|
|
||||||
) {
|
) {
|
||||||
constructor() : this(emptyList(), false)
|
|
||||||
|
|
||||||
fun hasFeature(feature: String): Boolean {
|
fun hasFeature(feature: String) = features.contains(feature)
|
||||||
return features.contains(feature)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val FEATURE_CONTINUATION = "continuation"
|
const val FEATURE_CONTINUATION = "continuation"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -160,18 +160,18 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
|||||||
put("moe.shizuku.manager.permission.API_V23", R.string.text_permission_shizuku);
|
put("moe.shizuku.manager.permission.API_V23", R.string.text_permission_shizuku);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
EditText mSourcePath;
|
EditText mSourcePathView;
|
||||||
View mSourcePathContainer;
|
View mSourcePathContainerView;
|
||||||
EditText mOutputPath;
|
EditText mOutputPathView;
|
||||||
EditText mAppName;
|
EditText mAppNameView;
|
||||||
EditText mPackageName;
|
EditText mPackageNameView;
|
||||||
TextInputLayout mPackageNameParent;
|
TextInputLayout mPackageNameParentView;
|
||||||
EditText mVersionName;
|
EditText mVersionNameView;
|
||||||
TextInputLayout mVersionNameParent;
|
TextInputLayout mVersionNameParentView;
|
||||||
EditText mVersionCode;
|
EditText mVersionCodeView;
|
||||||
TextInputLayout mVersionCodeParent;
|
TextInputLayout mVersionCodeParentView;
|
||||||
ImageView mIcon;
|
ImageView mIconView;
|
||||||
LinearLayout mAppConfig;
|
LinearLayout mAppConfigView;
|
||||||
|
|
||||||
private ProjectConfig mProjectConfig;
|
private ProjectConfig mProjectConfig;
|
||||||
private MaterialDialog mProgressDialog;
|
private MaterialDialog mProgressDialog;
|
||||||
@@ -209,24 +209,24 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
|||||||
ActivityBuildBinding binding = ActivityBuildBinding.inflate(getLayoutInflater());
|
ActivityBuildBinding binding = ActivityBuildBinding.inflate(getLayoutInflater());
|
||||||
setContentView(binding.getRoot());
|
setContentView(binding.getRoot());
|
||||||
|
|
||||||
mSourcePath = binding.sourcePath;
|
mSourcePathView = binding.sourcePath;
|
||||||
mSourcePath.setOnKeyListener((v, keyCode, event) -> {
|
mSourcePathView.setOnKeyListener((v, keyCode, event) -> {
|
||||||
if (keyCode == KeyEvent.KEYCODE_ENTER) {
|
if (keyCode == KeyEvent.KEYCODE_ENTER) {
|
||||||
if (event.getAction() == KeyEvent.ACTION_UP) {
|
if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||||
mOutputPath.requestFocus();
|
mOutputPathView.requestFocus();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
mSourcePathContainer = binding.sourcePathContainer;
|
mSourcePathContainerView = binding.sourcePathContainer;
|
||||||
|
|
||||||
mOutputPath = binding.outputPath;
|
mOutputPathView = binding.outputPath;
|
||||||
mOutputPath.setOnKeyListener((v, keyCode, event) -> {
|
mOutputPathView.setOnKeyListener((v, keyCode, event) -> {
|
||||||
if (keyCode == KeyEvent.KEYCODE_ENTER) {
|
if (keyCode == KeyEvent.KEYCODE_ENTER) {
|
||||||
if (event.getAction() == KeyEvent.ACTION_UP) {
|
if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||||
TextView nextField = (TextView) mOutputPath.focusSearch(View.FOCUS_DOWN);
|
TextView nextField = (TextView) mOutputPathView.focusSearch(View.FOCUS_DOWN);
|
||||||
if (nextField != null) {
|
if (nextField != null) {
|
||||||
nextField.requestFocus();
|
nextField.requestFocus();
|
||||||
}
|
}
|
||||||
@@ -236,30 +236,30 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
mAppName = binding.appName;
|
mAppNameView = binding.appName;
|
||||||
|
|
||||||
mPackageName = binding.packageName;
|
mPackageNameView = binding.packageName;
|
||||||
mPackageName.setOnKeyListener((v, keyCode, event) -> {
|
mPackageNameView.setOnKeyListener((v, keyCode, event) -> {
|
||||||
if (keyCode == KeyEvent.KEYCODE_ENTER) {
|
if (keyCode == KeyEvent.KEYCODE_ENTER) {
|
||||||
if (event.getAction() == KeyEvent.ACTION_UP) {
|
if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||||
mVersionName.requestFocus();
|
mVersionNameView.requestFocus();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
mPackageNameParent = binding.packageNameParent;
|
mPackageNameParentView = binding.packageNameParent;
|
||||||
|
|
||||||
mVersionName = binding.versionName;
|
mVersionNameView = binding.versionName;
|
||||||
mVersionNameParent = binding.versionNameParent;
|
mVersionNameParentView = binding.versionNameParent;
|
||||||
mVersionCode = binding.versionCode;
|
mVersionCodeView = binding.versionCode;
|
||||||
mVersionCodeParent = binding.versionCodeParent;
|
mVersionCodeParentView = binding.versionCodeParent;
|
||||||
|
|
||||||
mIcon = binding.appIcon;
|
mIconView = binding.appIcon;
|
||||||
mIcon.setVisibility(View.INVISIBLE);
|
mIconView.setVisibility(View.INVISIBLE);
|
||||||
mIcon.setOnClickListener(v -> selectIcon());
|
mIconView.setOnClickListener(v -> selectIcon());
|
||||||
|
|
||||||
mAppConfig = binding.appConfig;
|
mAppConfigView = binding.appConfig;
|
||||||
|
|
||||||
mFlexboxAbis = binding.flexboxAbis;
|
mFlexboxAbis = binding.flexboxAbis;
|
||||||
initAbisChildren();
|
initAbisChildren();
|
||||||
@@ -515,8 +515,8 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
|||||||
if (dir != null && dir.startsWith(getFilesDir().getPath())) {
|
if (dir != null && dir.startsWith(getFilesDir().getPath())) {
|
||||||
dir = WorkingDirectoryUtils.getPath();
|
dir = WorkingDirectoryUtils.getPath();
|
||||||
}
|
}
|
||||||
mOutputPath.setText(dir);
|
mOutputPathView.setText(dir);
|
||||||
mAppName.setText(file.getSimplifiedName());
|
mAppNameView.setText(file.getSimplifiedName());
|
||||||
|
|
||||||
Observable.fromCallable(() -> {
|
Observable.fromCallable(() -> {
|
||||||
String packageNameSuffix = generatePackageNameSuffix(file);
|
String packageNameSuffix = generatePackageNameSuffix(file);
|
||||||
@@ -525,34 +525,34 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
|||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(packageName -> {
|
.subscribe(packageName -> {
|
||||||
mPackageName.setText(packageName);
|
mPackageNameView.setText(packageName);
|
||||||
mPackageNameParent.setHint(R.string.text_package_name);
|
mPackageNameParentView.setHint(R.string.text_package_name);
|
||||||
|
|
||||||
SimpleVersionInfo nextVersionInfo = AppUtils.generateNextVersionInfo(packageName);
|
SimpleVersionInfo nextVersionInfo = AppUtils.generateNextVersionInfo(packageName);
|
||||||
if (nextVersionInfo != null) {
|
if (nextVersionInfo != null) {
|
||||||
mVersionName.setText(nextVersionInfo.versionName);
|
mVersionNameView.setText(nextVersionInfo.versionName);
|
||||||
mVersionCode.setText(nextVersionInfo.versionCodeString);
|
mVersionCodeView.setText(nextVersionInfo.versionCodeString);
|
||||||
} else {
|
} else {
|
||||||
mVersionName.setText(R.string.default_build_apk_version_name);
|
mVersionNameView.setText(R.string.default_build_apk_version_name);
|
||||||
mVersionCode.setText(R.string.default_build_apk_version_code);
|
mVersionCodeView.setText(R.string.default_build_apk_version_code);
|
||||||
}
|
}
|
||||||
mVersionNameParent.setHint(R.string.text_version_name);
|
mVersionNameParentView.setHint(R.string.text_version_name);
|
||||||
mVersionCodeParent.setHint(R.string.text_version_code);
|
mVersionCodeParentView.setHint(R.string.text_version_code);
|
||||||
|
|
||||||
Drawable iconDrawable = AppUtils.getInstalledAppIcon(packageName);
|
Drawable iconDrawable = AppUtils.getInstalledAppIcon(packageName);
|
||||||
if (iconDrawable != null) {
|
if (iconDrawable != null) {
|
||||||
mIcon.setImageDrawable(iconDrawable);
|
mIconView.setImageDrawable(iconDrawable);
|
||||||
mIsDefaultIcon = false;
|
mIsDefaultIcon = false;
|
||||||
}
|
}
|
||||||
mIcon.setVisibility(View.VISIBLE);
|
mIconView.setVisibility(View.VISIBLE);
|
||||||
}, throwable -> {
|
}, throwable -> {
|
||||||
mPackageName.setText(getString(R.string.format_default_package_name, file.getSimplifiedName().toLowerCase(Language.getPrefLanguage().getLocale())));
|
mPackageNameView.setText(getString(R.string.format_default_package_name, file.getSimplifiedName().toLowerCase(Language.getPrefLanguage().getLocale())));
|
||||||
mVersionName.setText(R.string.default_build_apk_version_name);
|
mVersionNameView.setText(R.string.default_build_apk_version_name);
|
||||||
mVersionCode.setText(R.string.default_build_apk_version_code);
|
mVersionCodeView.setText(R.string.default_build_apk_version_code);
|
||||||
mPackageNameParent.setHint(R.string.text_package_name);
|
mPackageNameParentView.setHint(R.string.text_package_name);
|
||||||
mVersionNameParent.setHint(R.string.text_version_name);
|
mVersionNameParentView.setHint(R.string.text_version_name);
|
||||||
mVersionCodeParent.setHint(R.string.text_version_code);
|
mVersionCodeParentView.setHint(R.string.text_version_code);
|
||||||
mIcon.setVisibility(View.VISIBLE);
|
mIconView.setVisibility(View.VISIBLE);
|
||||||
});
|
});
|
||||||
|
|
||||||
setSource(file);
|
setSource(file);
|
||||||
@@ -579,7 +579,7 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
void selectSourceFilePath() {
|
void selectSourceFilePath() {
|
||||||
String initialDir = new File(mSourcePath.getText().toString()).getParent();
|
String initialDir = new File(mSourcePathView.getText().toString()).getParent();
|
||||||
new FileChooserDialogBuilder(this)
|
new FileChooserDialogBuilder(this)
|
||||||
.title(R.string.text_source_file_path)
|
.title(R.string.text_source_file_path)
|
||||||
.dir(EnvironmentUtils.getExternalStoragePath(),
|
.dir(EnvironmentUtils.getExternalStoragePath(),
|
||||||
@@ -590,7 +590,7 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
|||||||
|
|
||||||
private void setSource(File file) {
|
private void setSource(File file) {
|
||||||
if (!file.isDirectory()) {
|
if (!file.isDirectory()) {
|
||||||
mSourcePath.setText(file.getPath());
|
mSourcePathView.setText(file.getPath());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mProjectConfig = ProjectConfig.fromProjectDir(file.getPath());
|
mProjectConfig = ProjectConfig.fromProjectDir(file.getPath());
|
||||||
@@ -598,20 +598,20 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mIsProjectLevelBuilding = true;
|
mIsProjectLevelBuilding = true;
|
||||||
mOutputPath.setText(new File(mSource, mProjectConfig.getBuildDir()).getPath());
|
mOutputPathView.setText(new File(mSource, mProjectConfig.getBuildDir()).getPath());
|
||||||
mAppConfig.setVisibility(View.GONE);
|
mAppConfigView.setVisibility(View.GONE);
|
||||||
mSourcePathContainer.setVisibility(View.GONE);
|
mSourcePathContainerView.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void selectOutputDirPath() {
|
void selectOutputDirPath() {
|
||||||
String initialDir = new File(mOutputPath.getText().toString()).exists()
|
String initialDir = new File(mOutputPathView.getText().toString()).exists()
|
||||||
? mOutputPath.getText().toString()
|
? mOutputPathView.getText().toString()
|
||||||
: WorkingDirectoryUtils.getPath();
|
: WorkingDirectoryUtils.getPath();
|
||||||
new FileChooserDialogBuilder(this)
|
new FileChooserDialogBuilder(this)
|
||||||
.title(R.string.text_output_apk_path)
|
.title(R.string.text_output_apk_path)
|
||||||
.dir(initialDir)
|
.dir(initialDir)
|
||||||
.chooseDir()
|
.chooseDir()
|
||||||
.singleChoice(dir -> mOutputPath.setText(dir.getPath()))
|
.singleChoice(dir -> mOutputPathView.setText(dir.getPath()))
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -633,14 +633,14 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
|||||||
|
|
||||||
private boolean checkInputs() {
|
private boolean checkInputs() {
|
||||||
if (mIsProjectLevelBuilding) {
|
if (mIsProjectLevelBuilding) {
|
||||||
return checkNotEmpty(mOutputPath);
|
return checkNotEmpty(mOutputPathView);
|
||||||
}
|
}
|
||||||
return checkNotEmpty(mSourcePath)
|
return checkNotEmpty(mSourcePathView)
|
||||||
& checkNotEmpty(mOutputPath)
|
& checkNotEmpty(mOutputPathView)
|
||||||
& checkNotEmpty(mAppName)
|
& checkNotEmpty(mAppNameView)
|
||||||
& checkNotEmpty(mVersionCode)
|
& checkNotEmpty(mVersionCodeView)
|
||||||
& checkNotEmpty(mVersionName)
|
& checkNotEmpty(mVersionNameView)
|
||||||
& checkPackageNameValid(mPackageName);
|
& checkPackageNameValid(mPackageNameView);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkAbis() {
|
private boolean checkAbis() {
|
||||||
@@ -773,12 +773,12 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
|||||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||||
@SuppressLint("CheckResult")
|
@SuppressLint("CheckResult")
|
||||||
private void doBuildingApk() {
|
private void doBuildingApk() {
|
||||||
ApkBuilder.AppConfig appConfig = createAppConfig();
|
ProjectConfig projectConfig = determineProjectConfig();
|
||||||
File tmpDir = new File(getCacheDir(), "build/");
|
File tmpDir = new File(getCacheDir(), "build/");
|
||||||
File outApk = new File(mOutputPath.getText().toString(),
|
File outApk = new File(mOutputPathView.getText().toString(),
|
||||||
String.format("%s_v%s.apk", appConfig.getAppName(), appConfig.getVersionName()));
|
String.format("%s_v%s.apk", projectConfig.getName(), projectConfig.getVersionName()));
|
||||||
showProgressDialog();
|
showProgressDialog();
|
||||||
Observable.fromCallable(() -> callApkBuilder(tmpDir, outApk, appConfig))
|
Observable.fromCallable(() -> callApkBuilder(tmpDir, outApk, projectConfig))
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(apkBuilder -> {
|
.subscribe(apkBuilder -> {
|
||||||
@@ -790,32 +790,33 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
|||||||
}, this::onBuildFailed);
|
}, this::onBuildFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ApkBuilder.AppConfig createAppConfig() {
|
private ProjectConfig determineProjectConfig() {
|
||||||
ArrayList<String> abis = collectCheckedItems(mFlexboxAbis);
|
ArrayList<String> abis = collectCheckedItems(mFlexboxAbis);
|
||||||
ArrayList<String> libs = collectCheckedItems(mFlexboxLibs);
|
ArrayList<String> libs = collectCheckedItems(mFlexboxLibs);
|
||||||
ArrayList<String> permissions = collectCheckedItems(mFlexboxPermissions);
|
ArrayList<String> permissions = collectCheckedItems(mFlexboxPermissions);
|
||||||
|
|
||||||
ApkBuilder.AppConfig appConfig = mProjectConfig != null
|
ProjectConfig projectConfig;
|
||||||
? ApkBuilder.AppConfig.fromProjectConfig(mSource, mProjectConfig)
|
if (mProjectConfig != null) {
|
||||||
: new ApkBuilder.AppConfig()
|
projectConfig = mProjectConfig
|
||||||
.setAppName(mAppName.getText().toString())
|
.ignoredDir(new File(mSource, mProjectConfig.getBuildDir()))
|
||||||
.setSourcePath(mSourcePath.getText().toString())
|
.setSourcePath(mSource)
|
||||||
.setPackageName(mPackageName.getText().toString())
|
.setIconPath(mProjectConfig.getIconPath() == null ? null : new File(mSource, mProjectConfig.getIconPath()).getPath());
|
||||||
.setVersionName(mVersionName.getText().toString())
|
|
||||||
.setVersionCode(Integer.parseInt(mVersionCode.getText().toString()))
|
|
||||||
.setIcon(mIsDefaultIcon ? null : () -> BitmapUtils.drawableToBitmap(mIcon.getDrawable()));
|
|
||||||
|
|
||||||
appConfig.setAbis(abis);
|
|
||||||
appConfig.setLibs(libs);
|
|
||||||
appConfig.setSignatureSchemes(mSignatureSchemes.getSelectedItem().toString());
|
|
||||||
if (mVerifiedKeyStores.getSelectedItemPosition() > 0) {
|
|
||||||
appConfig.setKeyStore((KeyStore) mVerifiedKeyStores.getSelectedItem());
|
|
||||||
} else {
|
} else {
|
||||||
appConfig.setKeyStore(null);
|
projectConfig = new ProjectConfig()
|
||||||
|
.setName(mAppNameView.getText().toString())
|
||||||
|
.setSourcePath(mSourcePathView.getText().toString())
|
||||||
|
.setPackageName(mPackageNameView.getText().toString())
|
||||||
|
.setVersionName(mVersionNameView.getText().toString())
|
||||||
|
.setVersionCode(Integer.parseInt(mVersionCodeView.getText().toString()))
|
||||||
|
.setIconGetter(mIsDefaultIcon ? null : () -> BitmapUtils.drawableToBitmap(mIconView.getDrawable()));
|
||||||
}
|
}
|
||||||
appConfig.setPermissions(permissions);
|
|
||||||
|
|
||||||
return appConfig;
|
return projectConfig
|
||||||
|
.setAbis(abis)
|
||||||
|
.setLibs(libs)
|
||||||
|
.setKeyStore(mVerifiedKeyStores.getSelectedItemPosition() > 0 ? (KeyStore) mVerifiedKeyStores.getSelectedItem() : null)
|
||||||
|
.setSignatureSchemes(mSignatureSchemes.getSelectedItem().toString())
|
||||||
|
.setPermissions(permissions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -843,12 +844,12 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
|||||||
return libs;
|
return libs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ApkBuilder callApkBuilder(File tmpDir, File outApk, ApkBuilder.AppConfig appConfig) throws Exception {
|
private ApkBuilder callApkBuilder(File tmpDir, File outApk, ProjectConfig projectConfig) throws Exception {
|
||||||
InputStream templateApk = getAssets().open(TEMPLATE_APK_NAME);
|
InputStream templateApk = getAssets().open(TEMPLATE_APK_NAME);
|
||||||
return new ApkBuilder(templateApk, outApk, tmpDir.getPath())
|
return new ApkBuilder(templateApk, outApk, tmpDir.getPath())
|
||||||
.setProgressCallback(BuildActivity.this)
|
.setProgressCallback(BuildActivity.this)
|
||||||
.prepare()
|
.prepare()
|
||||||
.withConfig(appConfig)
|
.withConfig(projectConfig)
|
||||||
.build()
|
.build()
|
||||||
.sign()
|
.sign()
|
||||||
.cleanWorkspace();
|
.cleanWorkspace();
|
||||||
@@ -920,7 +921,7 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa
|
|||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(drawable -> {
|
.subscribe(drawable -> {
|
||||||
mIcon.setImageDrawable(drawable);
|
mIconView.setImageDrawable(drawable);
|
||||||
mIsDefaultIcon = false;
|
mIsDefaultIcon = false;
|
||||||
}, Throwable::printStackTrace);
|
}, Throwable::printStackTrace);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,12 +122,12 @@ class ProjectConfigActivity : BaseActivity() {
|
|||||||
} else {
|
} else {
|
||||||
mAppName.setText(config.name)
|
mAppName.setText(config.name)
|
||||||
setToolbarAsBack(config.name)
|
setToolbarAsBack(config.name)
|
||||||
mVersionCode.setText(config.versionCode.toString())
|
mVersionCode.setText(config.versionCode.coerceAtLeast(0).toString())
|
||||||
mPackageName.setText(config.packageName)
|
mPackageName.setText(config.packageName)
|
||||||
mVersionName.setText(config.versionName)
|
mVersionName.setText(config.versionName)
|
||||||
mMainFileName.setText(config.mainScriptFile)
|
mMainFileName.setText(config.mainScriptFile)
|
||||||
mProjectLocationWrapper.visibility = View.GONE
|
mProjectLocationWrapper.visibility = View.GONE
|
||||||
config.icon?.let { icon ->
|
config.iconPath?.let { icon ->
|
||||||
File(mDirectory, icon).takeIf { it.exists() }?.let { iconFile ->
|
File(mDirectory, icon).takeIf { it.exists() }?.let { iconFile ->
|
||||||
Glide.with(this)
|
Glide.with(this)
|
||||||
.load(iconFile)
|
.load(iconFile)
|
||||||
@@ -259,7 +259,7 @@ class ProjectConfigActivity : BaseActivity() {
|
|||||||
private fun saveIcon(b: Bitmap): Observable<String> {
|
private fun saveIcon(b: Bitmap): Observable<String> {
|
||||||
return Observable.just(b)
|
return Observable.just(b)
|
||||||
.map { bitmap: Bitmap ->
|
.map { bitmap: Bitmap ->
|
||||||
var iconPath = mProjectConfig!!.icon
|
var iconPath = mProjectConfig!!.iconPath
|
||||||
if (iconPath == null) {
|
if (iconPath == null) {
|
||||||
iconPath = "res/logo.png"
|
iconPath = "res/logo.png"
|
||||||
}
|
}
|
||||||
@@ -272,7 +272,7 @@ class ProjectConfigActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.doOnNext { iconPath: String? -> mProjectConfig!!.icon = iconPath }
|
.doOnNext { iconPath: String? -> mProjectConfig!!.iconPath = iconPath }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
|||||||
@@ -1,27 +1,32 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="128dp"
|
android:layout_height="128dp"
|
||||||
android:layout_gravity="center|bottom"
|
android:layout_gravity="center|bottom"
|
||||||
android:layout_marginBottom="16dp"
|
android:layout_marginBottom="16dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="72dp"
|
android:id="@+id/icon"
|
||||||
android:layout_height="72dp"
|
android:visibility="gone"
|
||||||
android:layout_gravity="center"
|
tools:visibility="visible"
|
||||||
android:src="@mipmap/ic_launcher" />
|
android:layout_width="72dp"
|
||||||
|
android:layout_height="72dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@mipmap/ic_launcher" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/slug"
|
android:id="@+id/slug"
|
||||||
android:layout_width="wrap_content"
|
android:visibility="gone"
|
||||||
android:layout_height="wrap_content"
|
tools:visibility="visible"
|
||||||
android:layout_gravity="center"
|
android:layout_width="wrap_content"
|
||||||
android:layout_marginTop="20dp"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/text_powered_by_autojs"
|
android:layout_gravity="center"
|
||||||
android:textColor="@color/day_night_full"
|
android:layout_marginTop="20dp"
|
||||||
android:textSize="16sp" />
|
android:text="@string/text_powered_by_autojs"
|
||||||
|
android:textColor="@color/day_night_full"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#Sat Jan 18 23:47:18 CST 2025
|
#Mon Jan 20 14:32:52 CST 2025
|
||||||
BUILD_TIME=1737215238545
|
BUILD_TIME=1737354772708
|
||||||
COMPILE_SDK_VERSION=34
|
COMPILE_SDK_VERSION=34
|
||||||
JAVA_VERSION=23
|
JAVA_VERSION=23
|
||||||
JAVA_VERSION_MIN_RADICAL=0
|
JAVA_VERSION_MIN_RADICAL=0
|
||||||
@@ -17,6 +17,6 @@ RAPID_OCR_OPENCV_MOBILE_LABEL_VERSION=13
|
|||||||
RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3
|
RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3
|
||||||
TARGET_SDK_VERSION=34
|
TARGET_SDK_VERSION=34
|
||||||
TARGET_SDK_VERSION_INRT=29
|
TARGET_SDK_VERSION_INRT=29
|
||||||
VERSION_BUILD=2977
|
VERSION_BUILD=2979
|
||||||
VERSION_NAME=6.6.2 Alpha2
|
VERSION_NAME=6.6.2 Alpha2
|
||||||
VSCODE_EXT_REQUIRED_VERSION=1.0.8
|
VSCODE_EXT_REQUIRED_VERSION=1.0.8
|
||||||
|
|||||||
Reference in New Issue
Block a user