Cod*_*Lee 6 android apk android-package-managers android-fileprovider
我正在制作一个 APK 安装应用程序,并且经历了很多。特别是版本控制。为此,我查阅了一些帖子和 StackOverFlow。但现在所有的帖子让我更加困惑。那么,什么是正确的方法呢?
首先,请检查我下面关于每个版本安装的代码。让我们谈谈什么是正确的方法。
KitKat(API 19)、棒棒糖(API 21)、MashMellow(API 23)
fun installApkBelowNougat(apkFile: File) {
val apkUri = Uri.fromFile(apkFile)
val intent = Intent(Intent.ACTION_VIEW).apply {
setDataAndType(apkUri, "application/vnd.android.package-archive")
flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,所有解决方案都是相同的,我们必须使用Uri.fromFile(file)
来获得Uri
.
牛轧糖(API 24)
fun installApkInNougat(apkFile: File) {
val apkUri = FileProvider.getUriForFile(applicationContext, applicationContext.packageName + ".fileProvider", apkFile)
val intent = Intent(Intent.ACTION_VIEW).apply {
setDataAndType(apkUri, "application/vnd.android.package-archive")
flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我们就不能再使用了Uri.fromFile(file)
。因此,我们必须使用FileProvider
“Nougat”来代替它。并且我们还必须<proivder/>
在AndroidManifest.xml中这样写。
...
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepath" />
</provider>
...
Run Code Online (Sandbox Code Playgroud)
有人说我们不需要使用setDataAndType()
. 相反,他们只是setData()
在 Android7(Nougat) 中使用它。哪一种是正确的方法?两者都好吗?我们需要设置一个 Flag Intent.FLAG_GRANT_READ_URI_PERMISSION
。
编辑:您可以在此处找到何时使用setDataAndType()
或仅使用两者之一。
奥利奥(API 26)、派(API 28)、Q(API 29)、R(API 30)
fun installApkMoreThanO(apkFile: File) {
f (!this.packageManager.canRequestPackageInstalls()) {
val unknownIntent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES).setData(
Uri.parse(String.format("package:%s", this.packageName))
)
resultLauncher.launch(unknownIntent)
} else {
val apkUri = FileProvider.getUriForFile(applicationContext, applicationContext.packageName + ".fileProvider", apkFile)
val intent = Intent(Intent.ACTION_VIEW, apkUri).apply {
putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true)
setDataAndType(apkUri, "application/vnd.android.package-archive")
flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
startActivity(intent)
finish()
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,从 Oreo,我们必须添加此权限<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
才能安装 APK 文件。如果不这样做,应用程序就会毫无征兆地崩溃。而我们必须使用Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES
,因为自Android8(Oreo)以来,授予权限的方式已经发生了变化。在 Oreo 之前,我们可以一次性授予所有应用程序权限。但自 Oreo 以来,我们必须单独为每个应用程序授予权限。
我们可以使用registerActivitResult
许可的结果。这意味着如果您到目前为止从未允许过该应用程序的权限,则必须允许该权限,并且允许后系统返回Activity.RESULT_OK或Activity.RESULT_CANCELED。然后你就可以做你想做的事了。
S(API 31)
fun installApkMoreThanR(apkFile: File) {
val apkUri = FileProvider.getUriForFile(applicationContext, applicationContext.packageName + ".fileProvider", apkFile)
val intent = Intent(Intent.ACTION_VIEW, apkUri).apply {
putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, false)
setDataAndType(apkUri, "application/vnd.android.package-archive")
flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,看起来我回到了有点旧的方式,但它确实有效并且很好。与Android 8~10的方式结果相同。我不使用的原因是,即使我们授予应用程序权限,Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES)
我们也只能接收。它总是在 Android12 中RESULT_CANCELED
返回。Activity.RESULT_CANCELED
我不知道为什么。有些人说我们必须使用PackageInstaller
API,因为ACTION_VIEW
和ACTION_INSTALL_PACKAGE
在 Android 10 中已弃用。但我测试了它,并ACTION_VIEW
没有弃用。但哪种方式更好?从Android 10开始我们必须使用PackageInstaller
API吗?
归档时间: |
|
查看次数: |
1277 次 |
最近记录: |