feat: 改用系统安装器弹窗(FileProvider+ACTION_VIEW), 无需手动找权限

This commit is contained in:
LukeMackin
2026-07-19 21:06:04 +08:00
parent 14367a229b
commit b70c5015a0
14 changed files with 21 additions and 37 deletions

View File

@@ -19,5 +19,15 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<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/file_paths" />
</provider>
</application>
</manifest>

View File

@@ -19,6 +19,7 @@ import java.net.HttpURLConnection
import java.net.URL
import java.security.MessageDigest
import android.util.Log
import androidx.core.content.FileProvider
import org.json.JSONObject
class MainActivity : AppCompatActivity() {
@@ -210,44 +211,12 @@ class MainActivity : AppCompatActivity() {
}
private fun installApk(apkFile: File) {
if (!packageManager.canRequestPackageInstalls()) {
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
data = Uri.parse("package:$packageName")
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
startActivity(intent)
throw SecurityException("请开启安装未知应用权限后重试")
}
val packageInstaller = packageManager.packageInstaller
val params = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL)
val sessionId = packageInstaller.createSession(params)
val session: PackageInstaller.Session
try {
session = packageInstaller.openSession(sessionId)
} catch (e: Exception) {
packageInstaller.abandonSession(sessionId)
throw e
}
try {
apkFile.inputStream().use { input ->
session.openWrite("package", 0, apkFile.length()).use { output ->
input.copyTo(output)
session.fsync(output)
}
}
val launchIntent = packageManager.getLaunchIntentForPackage(packageName)
?: throw Exception("无法获取启动Intent")
val pendingIntent = PendingIntent.getActivity(
this, 0, launchIntent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
session.commit(pendingIntent.intentSender)
} catch (e: Exception) {
session.abandon()
throw e
} finally {
session.close()
val uri = FileProvider.getUriForFile(this, "${packageName}.fileprovider", apkFile)
val intent = Intent(Intent.ACTION_VIEW).apply {
setDataAndType(uri, "application/vnd.android.package-archive")
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_ACTIVITY_NEW_TASK)
}
startActivity(intent)
}
private fun computeSha256(file: File): String {

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<paths>
<cache-path name="apk" path="/" />
</paths>