У меня есть приложение для Android, которое я пытаюсь подписать apk с пользовательской задачей после запуска процесса сборки. Я дошел до того, что у меня задача выполняется постфактум, но в консоли я получаю следующую ошибку:
Error: Invalid command syntax
java -jar apksigtool.jar <apk-file> <private-key-file-der-format> <certificate-x509-file>
Теперь я могу запустить этот исполняемый файл из командной строки без проблем, но я не смог запустить задачу после того, как файлы apk были сгенерированы файлом сборки.
Что я пытаюсь сделать с помощью файла build.gradle:
создайте неподписанный apk, подпишите apk с файлом jar, используя мой сертификат, затем подпишите процесс сборки и zipalign apk
Это то, что у меня есть до сих пор
import java.text.SimpleDateFormat
import java.util.regex.Pattern
apply plugin: 'com.android.application'
def buildTime() {
def df = new SimpleDateFormat("yyyyMMdd'-'HHmm")
df.setTimeZone(TimeZone.getDefault())
return df.format(new Date())
}
def apkName = "MyApp"
def apkLocation
task (runApkSigTool , dependsOn: android, type: JavaExec) {
classpath files('apksigtool.jar')
main 'com.widevine.tools.android.apksigtool.ApkSigTool'
args[0] = apkLocation
args[1] = 'private_key.der'
args[2] = 'my.crt'
System.out.println(apkLocation);
}
android {
compileSdkVersion 19
buildToolsVersion "19.1.0"
signingConfigs{
debug{
storeFile file("debug.keystore")
storePassword "android"
keyAlias "androiddebugkey"
keyPassword "android"
}
release{
storeFile file("debug.keystore")
storePassword "android"
keyAlias "androiddebugkey"
keyPassword "android"
}
}
buildTypes {
debug{
}
release {
signingConfig signingConfigs.release
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
assembleDebug.doLast{
runApkSigTool.execute()
}
zipAlign true
}
debug{
signingConfig signingConfigs.debug
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
assembleDebug.doLast{
runApkSigTool.execute()
}
zipAlign false
}
android.applicationVariants.all { variant ->
def manifestFile = file("C:\\path\\app\\src\\main\\AndroidManifest.xml")
def pattern = Pattern.compile("versionName=\"(.+)\"")
def manifestText = manifestFile.getText()
def matcher = pattern.matcher(manifestText)
matcher.find()
def versionName = matcher.group(1)
pattern = Pattern.compile("versionCode=\"(.+)\"")
matcher = pattern.matcher(manifestText)
matcher.find()
def versionCode = matcher.group(1)
if (variant.zipAlign) {
variant.outputFile = new File("apk/"+apkName+"-V"+versionName+"-"+versionCode+"-"+variant.name+"-"+buildTime()+"-unaligned.apk");
variant.zipAlign.inputFile = variant.outputFile
variant.zipAlign.outputFile = new File("apk/"+apkName+"-V"+versionName+"-"+versionCode+"-"+variant.name+"-"+buildTime()+".apk");
} else {
apkLocation = "apk/"+apkName+"-V"+versionName+"-"+versionCode+"-"+variant.name+"-"+buildTime()+".apk";
variant.outputFile = new File("apk/"+apkName+"-V"+versionName+"-"+versionCode+"-"+variant.name+"-"+buildTime()+".apk");
System.out.println("CREATED UNSIGNED APK---------------")
}
}
}
lintOptions {
abortOnError false
ignoreWarnings true
checkAllWarnings false
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:20.0.0'
compile 'com.android.support:mediarouter-v7:20.0.0'
compile 'com.google.android.gms:play-services:5.0.89'
}
Я также вижу, что задача запускается в первый раз, прежде чем что-либо будет установлено для моего определения apkLocation. Другое дело, что я понятия не имею, действительно ли я правильно использую аргументы в своей задаче для запуска файла jar в первую очередь. На самом деле нет какой-либо доступной документации, которая просто подходит к тому, что мне нужно сделать, поэтому, надеюсь, кто-то может помочь.
ОБНОВЛЕНИЕ Я нашел корень в своем проекте, где заканчиваются файлы apk. Но когда я использую кнопку запуска, чтобы просто выполнять отладочные сборки, я вижу, что он пытается установить apk с неправильного пути.
Второе обновление
Я заменил часть файла сборки на этот
if (variant.zipAlign) {
def buildTime = buildTime();
new File("apk/"+apkName+"-V"+versionName+"-"+versionCode+"-"+variant.name+"-"+buildTime+"-unaligned.apk");
variant.outputFile = file("apk/"+apkName+"-V"+versionName+"-"+versionCode+"-"+variant.name+"-"+buildTime+"-unaligned.apk");
variant.zipAlign.inputFile = variant.outputFile
new File("apk/"+apkName+"-V"+versionName+"-"+versionCode+"-"+variant.name+"-"+buildTime+".apk");
variant.zipAlign.outputFile = file("apk/"+apkName+"-V"+versionName+"-"+versionCode+"-"+variant.name+"-"+buildTime+".apk");
} else {
def buildTime = buildTime();
new File("apk/"+apkName+"-V"+versionName+"-"+versionCode+"-"+variant.name+"-"+buildTime+".apk");
apkLocation = projectRoot+"apk/"+apkName+"-V"+versionName+"-"+versionCode+"-"+variant.name+"-"+buildTime+".apk";
variant.outputFile = file("apk/"+apkName+"-V"+versionName+"-"+versionCode+"-"+variant.name+"-"+buildTime+".apk");
System.out.println("CREATED UNSIGNED APK---------------")
}
Это дает мне точный результат, который позволяет мне создать apk и поместить его в файл в корневом каталоге моих проектов. Таким образом, когда я использую кнопку воспроизведения, чтобы запустить его на устройстве, студия имеет контекст для пути к файлу и не использует какой-то дурацкий, которого не существует.