feat: 添加照片发送确认对话框,优化相机捕获功能
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
package io.openim.flutter.openim
|
package io.openim.flutter.openim
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
import android.app.AlertDialog
|
||||||
|
import android.content.Intent
|
||||||
import android.content.pm.PackageInfo
|
import android.content.pm.PackageInfo
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
@@ -15,6 +16,8 @@ import android.util.Base64
|
|||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.ImageView
|
||||||
import androidx.core.content.FileProvider
|
import androidx.core.content.FileProvider
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
import org.conscrypt.Conscrypt
|
import org.conscrypt.Conscrypt
|
||||||
@@ -33,6 +36,7 @@ class MainActivity : FlutterActivity() {
|
|||||||
private val FILE_PICKER_REQUEST_CODE = 4201
|
private val FILE_PICKER_REQUEST_CODE = 4201
|
||||||
private var pendingFilePickerResult: MethodChannel.Result? = null
|
private var pendingFilePickerResult: MethodChannel.Result? = null
|
||||||
private var pendingCameraCaptureUri: Uri? = null
|
private var pendingCameraCaptureUri: Uri? = null
|
||||||
|
private var pendingCaptureConfirmationDialog: AlertDialog? = null
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: android.os.Bundle?) {
|
override fun onCreate(savedInstanceState: android.os.Bundle?) {
|
||||||
// 华为/荣耀/OPPO 等国产设备:在任意网络请求之前同步安装 Conscrypt,修复 SSL 握手失败(无 GMS 时系统 SSL 实现不完整)
|
// 华为/荣耀/OPPO 等国产设备:在任意网络请求之前同步安装 Conscrypt,修复 SSL 握手失败(无 GMS 时系统 SSL 实现不完整)
|
||||||
@@ -51,6 +55,12 @@ class MainActivity : FlutterActivity() {
|
|||||||
disableAutofillForCurrentWindow()
|
disableAutofillForCurrentWindow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
pendingCaptureConfirmationDialog?.dismiss()
|
||||||
|
pendingCaptureConfirmationDialog = null
|
||||||
|
super.onDestroy()
|
||||||
|
}
|
||||||
|
|
||||||
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
||||||
super.configureFlutterEngine(flutterEngine)
|
super.configureFlutterEngine(flutterEngine)
|
||||||
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
|
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
|
||||||
@@ -153,8 +163,7 @@ class MainActivity : FlutterActivity() {
|
|||||||
|
|
||||||
pendingCameraCaptureUri?.let { uri ->
|
pendingCameraCaptureUri?.let { uri ->
|
||||||
pendingCameraCaptureUri = null
|
pendingCameraCaptureUri = null
|
||||||
grantPickedFileReadPermission(uri)
|
showCaptureConfirmation(uri, result)
|
||||||
result.success(listOf(uri.toString()))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +200,7 @@ class MainActivity : FlutterActivity() {
|
|||||||
capture: Boolean,
|
capture: Boolean,
|
||||||
result: MethodChannel.Result
|
result: MethodChannel.Result
|
||||||
) {
|
) {
|
||||||
if (pendingFilePickerResult != null) {
|
if (pendingFilePickerResult != null || pendingCaptureConfirmationDialog != null) {
|
||||||
result.error("FILE_PICKER_BUSY", "A file picker request is already active", null)
|
result.error("FILE_PICKER_BUSY", "A file picker request is already active", null)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -258,6 +267,95 @@ class MainActivity : FlutterActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun showCaptureConfirmation(uri: Uri, result: MethodChannel.Result) {
|
||||||
|
if (isFinishing ||
|
||||||
|
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && isDestroyed)
|
||||||
|
) {
|
||||||
|
deleteCaptureUri(uri)
|
||||||
|
result.success(emptyList<String>())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val preview = ImageView(this).apply {
|
||||||
|
setImageURI(uri)
|
||||||
|
adjustViewBounds = true
|
||||||
|
scaleType = ImageView.ScaleType.FIT_CENTER
|
||||||
|
setBackgroundColor(0xFFF2F5F8.toInt())
|
||||||
|
layoutParams = FrameLayout.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
dp(360)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val previewContainer = FrameLayout(this).apply {
|
||||||
|
setPadding(dp(20), dp(12), dp(20), 0)
|
||||||
|
addView(preview)
|
||||||
|
}
|
||||||
|
|
||||||
|
var completed = false
|
||||||
|
fun complete(uris: List<String>) {
|
||||||
|
if (completed) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
completed = true
|
||||||
|
if (uris.isEmpty()) {
|
||||||
|
deleteCaptureUri(uri)
|
||||||
|
}
|
||||||
|
result.success(uris)
|
||||||
|
}
|
||||||
|
|
||||||
|
val dialog = AlertDialog.Builder(this)
|
||||||
|
.setTitle("确认发送照片")
|
||||||
|
.setMessage("确认后才会发送给好友。")
|
||||||
|
.setView(previewContainer)
|
||||||
|
.setNegativeButton("取消") { _, _ -> }
|
||||||
|
.setPositiveButton("发送") { _, _ -> }
|
||||||
|
.create()
|
||||||
|
|
||||||
|
dialog.setOnCancelListener {
|
||||||
|
complete(emptyList())
|
||||||
|
}
|
||||||
|
dialog.setOnDismissListener {
|
||||||
|
if (pendingCaptureConfirmationDialog == dialog) {
|
||||||
|
pendingCaptureConfirmationDialog = null
|
||||||
|
}
|
||||||
|
complete(emptyList())
|
||||||
|
}
|
||||||
|
dialog.setOnShowListener {
|
||||||
|
val sendButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE)
|
||||||
|
val cancelButton = dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
|
||||||
|
sendButton.setOnClickListener {
|
||||||
|
sendButton.isEnabled = false
|
||||||
|
cancelButton.isEnabled = false
|
||||||
|
grantPickedFileReadPermission(uri)
|
||||||
|
complete(listOf(uri.toString()))
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
cancelButton.setOnClickListener {
|
||||||
|
complete(emptyList())
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pendingCaptureConfirmationDialog = dialog
|
||||||
|
try {
|
||||||
|
dialog.show()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
pendingCaptureConfirmationDialog = null
|
||||||
|
complete(emptyList())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun dp(value: Int): Int {
|
||||||
|
return (value * resources.displayMetrics.density).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun deleteCaptureUri(uri: Uri) {
|
||||||
|
try {
|
||||||
|
contentResolver.delete(uri, null, null)
|
||||||
|
} catch (_: Exception) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun createCameraCaptureUri(extension: String): Uri {
|
private fun createCameraCaptureUri(extension: String): Uri {
|
||||||
val directory = externalCacheDir ?: cacheDir
|
val directory = externalCacheDir ?: cacheDir
|
||||||
val file = File.createTempFile(
|
val file = File.createTempFile(
|
||||||
|
|||||||
Reference in New Issue
Block a user