Я бы хотел обновить свой apk без использования PlayStore. Я прочитал это:
Android установить apk с Intent.VIEW_ACTION не работает с провайдером файлов
android .os.FileUriExposedException: файл: / //storage/emulated/0/test.txt раскрывается за пределами приложения через Intent.getData ()
FileProvider: Установка APK. Произошла ошибка при разборе пакета.
и многое другое, но я не смог найти проблему. Приложение загружает новый apk правильно (значение CR C является правильным). После загрузки запускается новое намерение установить этот новый apk. Но после нажатия «Установить» появляется сообщение «Произошла ошибка при разборе пакета». Если я удаляю свое приложение и загружаю этот файл apk вручную и устанавливаю его, он работает нормально.
Мой код:
MainActivity
override fun onStart() {
super.onStart()
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), REQUEST_PERMISSION)
} else {
updateApp()
}
}
private fun updateApp() {
updateLayout.visibility = View.VISIBLE
doAsync {
var onlineVersion = getUrlAsText("mydomain.com/version.properties")
if(compareVersionsForUpdate(onlineVersion)) {
downloadAndInstallUpdate("mydomain.com/manager.apk")
}
uiThread {
updateLayout.visibility = View.INVISIBLE
}
}
}
private fun downloadAndInstallUpdate(url: String) {
var destination = "${getExternalFilesDir("download")}/manager.apk"
val uri = Uri.parse("file://$destination")
var file = File(destination)
if(file.exists()) {
file.delete()
}
val request = DownloadManager.Request(Uri.parse(url))
request.setDestinationUri(uri)
val manager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val downloadId = manager.enqueue(request)
var fileProviderUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".fileprovider",
val onComplete: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(ctxt: Context?, intent: Intent?) {
val install = Intent(Intent.ACTION_INSTALL_PACKAGE)
install.data = fileProviderUri
install.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
startActivity(install)
unregisterReceiver(this)
finish()
}
}
registerReceiver(onComplete, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
}
private fun compareVersionsForUpdate(onlineVersion: String): Boolean {
val manager = this.packageManager
val info = manager.getPackageInfo(this.packageName, PackageManager.GET_ACTIVITIES)
if(onlineVersion.split("=")[1].trim().toInt() > info.versionCode) {
return true
}
return false
}
private fun getUrlAsText(url: String): String {
return URL(url).readText()
}
Манифест
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
<application
android:allowBackup="true"
android:icon="@drawable/icon"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
</application>
provider_paths. xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="." />
</paths>