feat: 构建flutter 基座
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
package io.openim.flutter.im_webview_app
|
||||
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
|
||||
class MainActivity : FlutterActivity()
|
||||
@@ -0,0 +1,146 @@
|
||||
package io.openim.flutter.openim
|
||||
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import androidx.core.content.FileProvider
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
import org.conscrypt.Conscrypt
|
||||
import java.security.Security
|
||||
import io.flutter.embedding.engine.FlutterEngine
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import java.io.File
|
||||
|
||||
class MainActivity : FlutterActivity() {
|
||||
private val CHANNEL = "io.openim.flutter.openim/apk_info"
|
||||
private val TAG = "MainActivity"
|
||||
|
||||
override fun onCreate(savedInstanceState: android.os.Bundle?) {
|
||||
// 华为/荣耀/OPPO 等国产设备:在任意网络请求之前同步安装 Conscrypt,修复 SSL 握手失败(无 GMS 时系统 SSL 实现不完整)
|
||||
try {
|
||||
Security.insertProviderAt(Conscrypt.newProvider(), 1)
|
||||
Log.d(TAG, "Conscrypt security provider installed (SSL fix for domestic devices)")
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "Conscrypt provider install failed: ${e.message}")
|
||||
}
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
||||
super.configureFlutterEngine(flutterEngine)
|
||||
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
|
||||
when (call.method) {
|
||||
"getApkPackageName" -> {
|
||||
val apkPath = call.argument<String>("apkPath")
|
||||
if (apkPath != null) {
|
||||
try {
|
||||
val packageName = getApkPackageName(apkPath)
|
||||
result.success(packageName)
|
||||
} catch (e: Exception) {
|
||||
result.error("ERROR", "无法解析APK包名: ${e.message}", null)
|
||||
}
|
||||
} else {
|
||||
result.error("ERROR", "APK路径为空", null)
|
||||
}
|
||||
}
|
||||
"getCurrentPackageName" -> {
|
||||
try {
|
||||
val packageName = packageName
|
||||
result.success(packageName)
|
||||
} catch (e: Exception) {
|
||||
result.error("ERROR", "无法获取当前包名: ${e.message}", null)
|
||||
}
|
||||
}
|
||||
"canRequestPackageInstalls" -> {
|
||||
try {
|
||||
val canInstall = canRequestPackageInstalls()
|
||||
result.success(canInstall)
|
||||
} catch (e: Exception) {
|
||||
result.error("ERROR", "无法检查安装权限: ${e.message}", null)
|
||||
}
|
||||
}
|
||||
"installApk" -> {
|
||||
val apkPath = call.argument<String>("apkPath")
|
||||
if (apkPath != null) {
|
||||
try {
|
||||
val success = installApk(apkPath)
|
||||
result.success(success)
|
||||
} catch (e: Exception) {
|
||||
result.error("ERROR", "安装APK失败: ${e.message}", null)
|
||||
}
|
||||
} else {
|
||||
result.error("ERROR", "APK路径为空", null)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
result.notImplemented()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getApkPackageName(apkPath: String): String? {
|
||||
return try {
|
||||
val packageManager = packageManager
|
||||
val packageInfo: PackageInfo = packageManager.getPackageArchiveInfo(
|
||||
apkPath,
|
||||
PackageManager.GET_ACTIVITIES
|
||||
) ?: return null
|
||||
packageInfo.packageName
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
/// 检查是否可以请求安装包权限(Android 8.0+)
|
||||
private fun canRequestPackageInstalls(): Boolean {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
// Android 8.0+ 需要检查安装权限
|
||||
packageManager.canRequestPackageInstalls()
|
||||
} else {
|
||||
// Android 8.0 以下版本默认允许安装
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// 使用 Intent 直接打开安装界面
|
||||
private fun installApk(apkPath: String): Boolean {
|
||||
return try {
|
||||
val file = File(apkPath)
|
||||
if (!file.exists()) {
|
||||
return false
|
||||
}
|
||||
|
||||
val intent = Intent(Intent.ACTION_VIEW).apply {
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
|
||||
val apkUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
// Android 7.0+ 使用 FileProvider
|
||||
FileProvider.getUriForFile(
|
||||
this@MainActivity,
|
||||
"${packageName}.fileprovider",
|
||||
file
|
||||
)
|
||||
} else {
|
||||
// Android 7.0 以下直接使用 file://
|
||||
Uri.fromFile(file)
|
||||
}
|
||||
|
||||
setDataAndType(apkUri, "application/vnd.android.package-archive")
|
||||
|
||||
// Android 7.0+ 需要添加临时读取权限
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
}
|
||||
}
|
||||
|
||||
startActivity(intent)
|
||||
true
|
||||
} catch (e: Exception) {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user