Можно ли создать APK-файл из ответного вызова API base64String? - PullRequest
0 голосов
/ 27 января 2020

В настоящее время я работаю над решением, как обновлять и устанавливать APK-файл программно - очень похоже на эту проблему. Мое приложение не использует Сервисы Google.

В целях обновления APK-файлы с восходящими версиями хранятся на внутреннем сервере, а веб-служба C# возвращает последнюю версию APK-файла.

Я делаю это с Retrofit2:

    @Streaming
    @GET("/ws/webservice.svc/getUpdate")
    fun getUpdate(
        @Query("Programm") program: String,
        @Query("version") version: String,
        @Query("test") test: Boolean
    ): Single<String>

и LiveData:

override fun getUpdate() {
        disposables += api.getUpdate(
            program = context.getString(R.string.app_name),
            version = context.getString(R.string.app_version),
            test = isTest
        )
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeBy(
                onSuccess = {
                    liveData.value = GetUpdate(it)
                },
                onError = {
                    liveData.value = Error("Error getUpdate: " + it.message)
                }
            )
    }

Проблема, с которой я сталкиваюсь, заключается в том, что ответ на этот вызов API ( Это означает, что - самый последний файл APK) имеет представление base64String , как показано на рисунке ниже - это, например, только часть ответа сервера, когда вызов API выполняется в браузере.

APK file as String

Возможно ли как-то сгенерировать "настоящий" APK-файл из этого представления String после его загрузки, поэтому после этого я, вероятно, смогу установить его на устройство? Я знаю, что это странно, но клиент хочет, чтобы я повторно использовал тот же веб-сервис для этих целей.

Я нашел похожую проблему здесь . Как это можно сделать в Kotlin? Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 27 января 2020

Да, вам нужно декодировать base64 в ByteArray, а затем записать байты в местоположение с постфиксом .apk. У вас есть String, где bytes равны encoded с использованием схемы кодирования base64.

Поскольку вы используете kotlin, вы можете что посмотреть здесь, чтобы получить ByteArray! [ 1] из String. Затем убедитесь, что файл, который вы пишете, имеет расширение .apk.

[1] https://developer.android.com/reference/kotlin/java/util/Base64.Decoder#decode (kotlin .String)

0 голосов
/ 29 января 2020

AndroidManifest. xml

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

MVVM с LiveData:

    override fun getUpdate() {
        disposables += api.getUpdate(
            program = context.getString(R.string.app_name) + ".apk",
            version = context.getString(R.string.app_version),
            test = isTest
        )
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .map(::decodeToAPK)
            .subscribe({
                liveData.value = GetUpdate 
            }, {
                liveData.value = Error("Error getUpdate: " + it.message)
            })
    }


    private fun decodeToAPK(base64String: String) {

        val byteArrayAPK = Base64.decode(base64String, Base64.DEFAULT)

        val file =
            File(context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "yourApp.apk")
        try {
            val fileOutputStream = FileOutputStream(file)
            fileOutputStream.write(byteArrayAPK)
            fileOutputStream.flush()
            fileOutputStream.close()
        } catch (e: UnsupportedEncodingException) {
            Log.d(null, "error writing APK")
            e.printStackTrace()
        }
   }

   sealed class SomeAction : Action {
     data class Error(val message: String) : SomeAction()
     object GetUpdate : SomeAction()
   }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...