对比新文件 |
| | |
| | | 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 |
| | | } |
| | | } |