优化ai对话页面,以及权限申请

This commit is contained in:
fengjignqi
2026-08-03 10:16:31 +08:00
parent 12fecfbe41
commit bc0c7adb41
19 changed files with 345 additions and 34 deletions

Binary file not shown.

View File

@@ -156,4 +156,7 @@ dependencies {
implementation 'com.github.yyued:SVGAPlayer-Android:2.6.1'
//圆形视图库
implementation 'com.makeramen:roundedimageview:2.3.0'
}

View File

@@ -1,7 +1,9 @@
package com.ck.ckcollar.app.ui.act.customer
import android.Manifest
import android.content.Context
import android.content.Intent
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Build
import android.os.Bundle
@@ -25,6 +27,10 @@ import androidx.core.content.FileProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import com.ck.ckcollar.app.CKApp
import com.ck.ckcollar.app.R
import com.ck.ckcollar.app.action.ActionCode
@@ -71,7 +77,6 @@ class CustomerActivity : CKBaseActivity() {
binding = ActivityCustomerBinding.inflate(layoutInflater)
setContentView(binding.root)
super.onCreate(savedInstanceState)
checkAppPermissions()
setTitleText(getString(R.string.customer_service4))
@@ -185,25 +190,32 @@ class CustomerActivity : CKBaseActivity() {
binding.editMessage.requestFocus()
KeyboardUtils.showKeyboard(binding.editMessage)
}
//拍照
binding.conetnt1.setOnClickListener {
if (TextUtils.isEmpty(path)) {
takePhoto()
getPermissionRequst(
Manifest.permission.CAMERA,
REQUEST_CAMERA_PERMISSION
)
} else {
toast(getString(R.string.only_one_photo))
}
}
//相册
binding.conetnt2.setOnClickListener {
if (TextUtils.isEmpty(path)) {
//相册
val i = Intent(
Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
val permission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
Manifest.permission.READ_MEDIA_IMAGES
} else {
Manifest.permission.READ_EXTERNAL_STORAGE
}
getPermissionRequst(
permission,
REQUEST_PHOTO_PERMISSION
)
i.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
startActivityForResult(i, 56)
} else {
toast(getString(R.string.only_one_photo))
}
@@ -226,6 +238,21 @@ class CustomerActivity : CKBaseActivity() {
}
override fun onPermissionsGranted(requestCode: Int, permissions: Array<String>) {
when (requestCode) {
REQUEST_CAMERA_PERMISSION -> takePhoto()
REQUEST_PHOTO_PERMISSION -> {
val intent = Intent(
Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
).apply {
setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*")
}
startActivityForResult(intent, 56)
}
}
}
override fun initData() {
//getList()
@@ -658,14 +685,42 @@ class CustomerActivity : CKBaseActivity() {
if (!TextUtils.isEmpty(model.url)) {
holder.binding.textTo.visibility = View.GONE
holder.binding.imageContentTo.visibility = View.VISIBLE
val imageView = holder.binding.imageContentTo
val imageUrl = model.url!!
imageView.setTag(imageUrl)
resetImageContentSize(imageView)
Glide.with(context)
.load( model.url)
.load(imageUrl)
.placeholder(R.mipmap.image_default)
.into(holder.binding.imageContentTo)
.listener(object : RequestListener<Drawable> {
override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<Drawable>?,
isFirstResource: Boolean
): Boolean = false
holder.binding.imageContentTo.setTag(model.url)
holder.binding.imageContentTo.setOnClickListener(imageClick)
override fun onResourceReady(
resource: Drawable,
model: Any,
target: Target<Drawable>?,
dataSource: DataSource,
isFirstResource: Boolean
): Boolean {
if (imageView.tag == imageUrl) {
setImageContentSize(
imageView,
resource.intrinsicWidth,
resource.intrinsicHeight
)
}
return false
}
})
.into(imageView)
imageView.setOnClickListener(imageClick)
} else {
holder.binding.textTo.visibility = View.VISIBLE
holder.binding.imageContentTo.visibility = View.GONE
@@ -680,6 +735,39 @@ class CustomerActivity : CKBaseActivity() {
}
}
private fun resetImageContentSize(imageView: View) {
val density = imageView.resources.displayMetrics.density
imageView.layoutParams = imageView.layoutParams.apply {
width = getMaxImageWidth(density)
height = (200 * density).toInt()
}
}
private fun setImageContentSize(imageView: View, sourceWidth: Int, sourceHeight: Int) {
if (sourceWidth <= 0 || sourceHeight <= 0) return
val density = imageView.resources.displayMetrics.density
val maxWidth = getMaxImageWidth(density).toFloat()
val maxHeight = (200 * density).toFloat()
val scale = minOf(
1f,
maxWidth / sourceWidth.toFloat(),
maxHeight / sourceHeight.toFloat()
)
imageView.layoutParams = imageView.layoutParams.apply {
width = (sourceWidth * scale).toInt().coerceAtLeast(1)
height = (sourceHeight * scale).toInt().coerceAtLeast(1)
}
}
private fun getMaxImageWidth(density: Float): Int {
val requestedWidth = (200 * density).toInt()
// Reserve the avatar, paddings, and the bubble's left inset.
val availableWidth = context.resources.displayMetrics.widthPixels - (155 * density).toInt()
return minOf(requestedWidth, availableWidth.coerceAtLeast(1))
}
override fun getItemCount(): Int {
return data.size
}
@@ -715,4 +803,9 @@ class CustomerActivity : CKBaseActivity() {
}
}
companion object {
private const val REQUEST_CAMERA_PERMISSION = 1001
private const val REQUEST_PHOTO_PERMISSION = 1002
}
}

View File

@@ -1,8 +1,10 @@
package com.ck.ckcollar.app.ui.act.home.fragment
import android.Manifest
import android.app.Activity.RESULT_OK
import android.content.Context
import android.content.Intent
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.GradientDrawable.Orientation
import android.net.Uri
import android.os.Build
@@ -10,11 +12,16 @@ import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.text.TextUtils
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.ImageView
import android.widget.PopupWindow
import android.widget.TextView
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.core.content.FileProvider
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.RecyclerView
@@ -67,6 +74,25 @@ import kotlin.random.Random
class HomeFragment : CKBaseFragment() {
private enum class CameraAction { SCAN, TAKE_PHOTO }
private var pendingCameraAction: CameraAction? = null
private var permissionTopDialog: AlertDialog? = null
private val cameraPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { granted ->
hideCameraPermissionTopDialog()
val action = pendingCameraAction
pendingCameraAction = null
if (granted) {
when (action) {
CameraAction.SCAN -> startScan()
CameraAction.TAKE_PHOTO -> takePhoto()
null -> Unit
}
}
}
lateinit var homeBinding: FragmentHomeBinding
var collarDatas = listOf<CollarTypeModel.TypeDataModel>()
@@ -111,6 +137,11 @@ class HomeFragment : CKBaseFragment() {
if (!checkCameraPermissions()){
CKAlertDialog(activity!!,getString(R.string.alert),getString(R.string.camera_alert),object : CKAlertDialog.AlertClickListener{
override fun onBack(isConfirm: Boolean) {
if(isConfirm){
requestCameraPermission(CameraAction.SCAN)
}else{
}
}
}).show()
@@ -126,7 +157,7 @@ class HomeFragment : CKBaseFragment() {
CKAlertDialog(activity!!,getString(R.string.alert),getString(R.string.camera_alert),object : CKAlertDialog.AlertClickListener{
override fun onBack(isConfirm: Boolean) {
if (isConfirm) requestCameraPermission(CameraAction.TAKE_PHOTO)
}
}).show()
return@setOnClickListener
@@ -201,6 +232,50 @@ class HomeFragment : CKBaseFragment() {
}
}
private fun requestCameraPermission(action: CameraAction) {
pendingCameraAction = action
showCameraPermissionTopDialog()
permissionTopDialog?.window?.decorView?.post {
if (isAdded && pendingCameraAction == action) {
cameraPermissionLauncher.launch(Manifest.permission.CAMERA)
}
}
}
private fun showCameraPermissionTopDialog() {
permissionTopDialog?.dismiss()
val view = layoutInflater.inflate(R.layout.permission_top_dialog, null)
view.findViewById<TextView>(R.id.permissionTopTitle).text = getString(R.string.camera)
view.findViewById<TextView>(R.id.permissionTopContent).text = getString(R.string.camera_alert)
permissionTopDialog = AlertDialog.Builder(requireContext())
.setView(view)
.create()
.also { dialog ->
dialog.setCanceledOnTouchOutside(false)
dialog.setCancelable(false)
dialog.show()
dialog.window?.apply {
setBackgroundDrawable(ColorDrawable(android.graphics.Color.TRANSPARENT))
setGravity(Gravity.TOP)
setLayout(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT
)
}
}
}
private fun hideCameraPermissionTopDialog() {
permissionTopDialog?.dismiss()
permissionTopDialog = null
}
override fun onDestroyView() {
hideCameraPermissionTopDialog()
pendingCameraAction = null
super.onDestroyView()
}
override fun initData() {
var data = PreferencesUtils.getString(activity!!, Const.PET_DATA, "")

View File

@@ -51,7 +51,7 @@ class LoginActivity : CKBaseActivity() {
// api = WXAPIFactory.createWXAPI(this, Const.WX_APP_ID, false);
setStatusBarColor(R.attr.mainBackground)
//检测权限
checkAppPermissions()
// checkAppPermissions()
}

View File

@@ -59,11 +59,12 @@ class WelcomeActivity : CKBaseActivity() {
view.btnCome.setOnClickListener {
val toPermisstionActivity = PreferencesUtils.getBolean(this@WelcomeActivity,
Const.PERMISSIONS_FIRST,false) as Boolean
if (!toPermisstionActivity){
toActivity(PermisstionActivity::class.java, DataCollection())
}else{
// if (!toPermisstionActivity){
// toActivity(PermisstionActivity::class.java, DataCollection())
// }else{
// toActivity(LoginActivity::class.java, DataCollection())
// }
toActivity(LoginActivity::class.java, DataCollection())
}
finish()
}

View File

@@ -1,15 +1,20 @@
package com.ck.ckcollar.app.ui.base
import android.Manifest
import android.content.pm.PackageManager
import android.graphics.drawable.ColorDrawable
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.util.TypedValue
import android.view.View
import android.view.Gravity
import android.view.WindowManager
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.TextView
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
@@ -18,6 +23,7 @@ import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import com.ck.ckcollar.app.CKApp
import com.ck.ckcollar.app.R
import com.ck.ckcollar.app.ui.dialog.CKAlertDialog
import com.tt.kit.base.TTBaseActivity
import com.tt.kit.utils.TTLog
import com.tt.kit.utils.TTUtils
@@ -26,6 +32,27 @@ import pub.devrel.easypermissions.EasyPermissions
open class CKBaseActivity : TTBaseActivity(){
private var permissionDialog: AlertDialog? = null
private var pendingPermissionRequestCode: Int? = null
private var pendingPermissions: Array<String> = emptyArray()
private val permissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { result ->
hidePermissionDialog()
val requestCode = pendingPermissionRequestCode ?: return@registerForActivityResult
val requestedPermissions = pendingPermissions
pendingPermissionRequestCode = null
pendingPermissions = emptyArray()
val denied = result.filterValues { !it }.keys.toTypedArray()
if (denied.isEmpty()) {
onPermissionsGranted(requestCode, requestedPermissions)
} else {
val permanentlyDenied = denied.all { !ActivityCompat.shouldShowRequestPermissionRationale(this, it) }
onPermissionsDenied(requestCode, denied, permanentlyDenied)
}
}
var perms_= listOf<String>(Manifest.permission.CAMERA, Manifest.permission.READ_MEDIA_IMAGES,Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
var perms_tiramisu = listOf<String>(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE)
@@ -208,10 +235,118 @@ open class CKBaseActivity : TTBaseActivity(){
}
fun checkCameraPermissions() : Boolean{
var a = 0;
return EasyPermissions.hasPermissions(this, *perms_carmra.toTypedArray())
}
fun hasRecordPermission(permission: String): Boolean {
return hasRecordPermission(arrayOf(permission))
}
fun hasRecordPermission(permissions: Array<String>): Boolean {
return permissions.all {
ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
}
}
fun getPermissionRequst(
permission: String,
requestCode: Int
) {
val isCameraPermission = permission == Manifest.permission.CAMERA
getPermissionRequst(
permission,
getString(if (isCameraPermission) R.string.camera else R.string.photo),
getString(if (isCameraPermission) R.string.camera_alert else R.string.photo_permission_alert),
requestCode
)
}
fun getPermissionRequst(
permission: String,
title: String,
content: String,
requestCode: Int
) {
getMorePermissionRequst(arrayOf(permission), title, content, requestCode)
}
fun getMorePermissionRequst(
permissions: Array<String>,
title: String,
content: String,
requestCode: Int
) {
if (hasRecordPermission(permissions)) {
onPermissionsGranted(requestCode, permissions)
return
}
CKAlertDialog(this, getString(R.string.alert), content, object : CKAlertDialog.AlertClickListener {
override fun onBack(isConfirm: Boolean) {
if (isConfirm) {
requestSystemPermissions(permissions, title, content, requestCode)
} else {
onPermissionsDenied(requestCode, permissions, false)
}
}
}).show()
}
private fun requestSystemPermissions(
permissions: Array<String>,
title: String,
content: String,
requestCode: Int
) {
pendingPermissionRequestCode = requestCode
pendingPermissions = permissions
showPermissionDialog(title, content)
permissionDialog?.window?.decorView?.post {
if (!isFinishing && pendingPermissionRequestCode == requestCode) {
permissionLauncher.launch(permissions)
}
}
}
private fun showPermissionDialog(title: String, content: String) {
hidePermissionDialog()
val view = layoutInflater.inflate(R.layout.permission_top_dialog, null)
view.findViewById<TextView>(R.id.permissionTopTitle).text = title
view.findViewById<TextView>(R.id.permissionTopContent).text = content
permissionDialog = AlertDialog.Builder(this)
.setView(view)
.create()
.also { dialog ->
dialog.setCanceledOnTouchOutside(false)
dialog.setCancelable(false)
dialog.show()
dialog.window?.apply {
setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
setGravity(Gravity.TOP)
setLayout(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT
)
}
}
}
private fun hidePermissionDialog() {
permissionDialog?.dismiss()
permissionDialog = null
}
protected open fun onPermissionsGranted(requestCode: Int, permissions: Array<String>) {
}
protected open fun onPermissionsDenied(
requestCode: Int,
permissions: Array<String>,
permanentlyDenied: Boolean
) {
}
fun requstPermissions(){
var perms = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
perms_
@@ -228,6 +363,9 @@ open class CKBaseActivity : TTBaseActivity(){
ActivityCompat.requestPermissions(this, perms.toTypedArray(), 1001)
}
override fun onDestroy() {
hidePermissionDialog()
pendingPermissionRequestCode = null
pendingPermissions = emptyArray()
super.onDestroy()
CKApp.app.activitys.remove(this)
}

View File

@@ -74,9 +74,9 @@ open class CKLHBaseActivity : TTBaseActivity(){
// getWindow().setStatusBarColor(Color.TRANSPARENT);
if (!checkPermissions()){
requstPermissions()
}
// if (!checkPermissions()){
// requstPermissions()
// }
}

View File

@@ -118,19 +118,19 @@
android:textSize="14sp"></com.ck.ckcollar.app.widget.CKTextView>
<com.ck.ckcollar.app.widget.CKImageView
<com.makeramen.roundedimageview.RoundedImageView
android:id="@+id/imageContentTo"
android:textIsSelectable="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="200dp"
android:layout_height="200dp"
android:textColor="@color/textColor"
android:background="@drawable/bg_message_to"
android:paddingVertical="3dp"
android:paddingHorizontal="5dp"
android:layout_marginTop="3dp"
android:maxWidth="200dp"
android:scaleType="fitCenter"
android:visibility="gone"
></com.ck.ckcollar.app.widget.CKImageView>
app:riv_corner_radius="8dp"/>
</com.ck.ckcollar.app.widget.CKLinearLayout>
<com.ck.ckcollar.app.widget.CKRoundImageView

View File

@@ -584,7 +584,8 @@
<string name="please_choose_product">请先选择商品</string>
<string name="cancel_account_phone">注销%s绑定的账号</string>
<string name="please_choose_data">请选择原因</string>
<string name="camera_alert">请在设置中允许访问相机</string>
<string name="camera_alert">宠盾需要您的授权,使用相机功能来进行扫码和拍照</string>
<string name="photo_permission_alert">宠盾需要您的授权,访问相册以选择照片</string>
<string name="input_question">请输入问题</string>
<string name="pet_note">宠物常识</string>