zhujie
2025-03-26 57d1ff885c981283758d355856012b16b4c7bc5e
app/src/main/java/com/example/firstapp/ui/profile/EditProfileActivity.kt
对比新文件
@@ -0,0 +1,199 @@
package com.example.firstapp.ui.profile
import android.Manifest
import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
import android.view.View
import android.widget.ProgressBar
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import com.bumptech.glide.Glide
import com.example.firstapp.databinding.ActivityEditProfileBinding
import com.example.firstapp.database.service.ApiService
import kotlinx.coroutines.launch
import java.io.File
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.MultipartBody
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody
class EditProfileActivity : AppCompatActivity() {
    private lateinit var binding: ActivityEditProfileBinding
    private var selectedImageUri: Uri? = null
    private lateinit var apiService: ApiService
    private var loadingDialog: AlertDialog? = null
    private val pickImage = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
        if (result.resultCode == Activity.RESULT_OK) {
            result.data?.data?.let { uri ->
                selectedImageUri = uri
                Glide.with(this)
                    .load(uri)
                    .circleCrop()
                    .into(binding.ivAvatar)
            }
        }
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityEditProfileBinding.inflate(layoutInflater)
        setContentView(binding.root)
        // 设置状态栏
        window.statusBarColor = ContextCompat.getColor(this, android.R.color.white)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
        }
        // 获取传入的数据
        val currentNickname = intent.getStringExtra("nickname") ?: ""
        val currentAvatarUrl = intent.getStringExtra("avatar_url")
        // 设置当前数据
        binding.etNickname.setText(currentNickname)
        if (!currentAvatarUrl.isNullOrEmpty()) {
            Glide.with(this)
                .load(currentAvatarUrl)
                .circleCrop()
                .into(binding.ivAvatar)
        }
        // 设置点击事件
        binding.btnBack.setOnClickListener {
            finish()
        }
        binding.ivAvatar.setOnClickListener {
            checkAndRequestPermission()
        }
        binding.btnSaveBottom.setOnClickListener {
            saveAndFinish()
        }
    }
    private fun saveAndFinish() {
        lifecycleScope.launch {
            try {
                binding.btnSaveBottom.isEnabled = false
                showLoading()
                val newNickname = binding.etNickname.text.toString()
                if (newNickname.isEmpty()) {
                    Toast.makeText(this@EditProfileActivity, "昵称不能为空", Toast.LENGTH_SHORT).show()
                    return@launch
                }
                // 准备文件和参数
                val nicknameBody = newNickname.toRequestBody("text/plain".toMediaType())
                // 如果选择了新头像,处理文件
                val avatarPart = selectedImageUri?.let { uri ->
                    val inputStream = contentResolver.openInputStream(uri)
                    val file = File(cacheDir, "avatar_temp")
                    inputStream?.use { input ->
                        file.outputStream().use { output ->
                            input.copyTo(output)
                        }
                    }
                    val requestFile = file.asRequestBody("image/*".toMediaType())
                    MultipartBody.Part.createFormData("avatar", file.name, requestFile)
                }
                // 调用更新接口
                apiService.updateProfile(
                    nickname = nicknameBody,
                    avatar = avatarPart
                )
                Toast.makeText(this@EditProfileActivity, "保存成功", Toast.LENGTH_SHORT).show()
                finish()
            } catch (e: Exception) {
                Toast.makeText(this@EditProfileActivity, "保存失败: ${e.message}", Toast.LENGTH_SHORT).show()
            } finally {
                binding.btnSaveBottom.isEnabled = true
                hideLoading()
            }
        }
    }
    private fun checkAndRequestPermission() {
        when {
            ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.READ_EXTERNAL_STORAGE
            ) == PackageManager.PERMISSION_GRANTED -> {
                openGallery()
            }
            else -> {
                ActivityCompat.requestPermissions(
                    this,
                    arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
                    PERMISSION_REQUEST_CODE
                )
            }
        }
    }
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            PERMISSION_REQUEST_CODE -> {
                if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    openGallery()
                } else {
                    Toast.makeText(this, "需要存储权限来选择头像", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }
    private fun openGallery() {
        val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
        pickImage.launch(intent)
    }
    private fun showLoading() {
        if (loadingDialog == null) {
            loadingDialog = AlertDialog.Builder(this)
                .setView(ProgressBar(this))
                .setCancelable(false)
                .create()
        }
        loadingDialog?.show()
    }
    private fun hideLoading() {
        loadingDialog?.dismiss()
    }
    private fun String.toRequestBody(mediaType: String): RequestBody {
        return this.toRequestBody(mediaType.toMediaType())
    }
    private fun File.asRequestBody(mediaType: String): RequestBody {
        return this.asRequestBody(mediaType.toMediaType())
    }
    companion object {
        private const val PERMISSION_REQUEST_CODE = 100
    }
}