Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat/#93] image download 기능 구현 #99

Merged
merged 11 commits into from
Jan 14, 2024
3 changes: 3 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="32"
tools:ignore="ScopedStorage" />

<application
android:name=".MyApp"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
package com.going.presentation.tendency.result

import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.media.MediaScannerConnection
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.text.SpannableString
import android.text.Spanned
import android.text.style.BulletSpan
import androidx.activity.viewModels
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import com.going.presentation.R
Expand All @@ -19,6 +29,8 @@ import com.going.ui.extension.toast
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import java.io.File
import java.io.FileOutputStream

@AndroidEntryPoint
class TendencyResultActivity :
Expand All @@ -27,14 +39,14 @@ class TendencyResultActivity :
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

getuserInfo()
getUserInfo()
observeUserInfoState()
initRestartBtnClickLitener()
initRestartBtnClickListener()
initSaveImgBtnClickListener()
initFinishBtnClickListener()
}

private fun getuserInfo() {
private fun getUserInfo() {
viewModel.getUserInfoState()
}

Expand Down Expand Up @@ -97,15 +109,15 @@ class TendencyResultActivity :
return string
}

private fun initRestartBtnClickLitener() {
private fun initRestartBtnClickListener() {
binding.btnTendencyTestRestart.setOnSingleClickListener {
navigateToTendencyTestScreen()
}
}

private fun initSaveImgBtnClickListener() {
binding.btnTendencyResultDownload.setOnSingleClickListener {
toast("추후 업데이트 예정")
startImageDownload()
}
}

Expand All @@ -129,4 +141,75 @@ class TendencyResultActivity :
startActivity(this)
}
}

private fun startImageDownload() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU && ContextCompat.checkSelfPermission(
this,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
) != PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
PERMISSION_REQUEST_CODE,
)
} else {
saveImageToGallery(resources)
}
}

private fun saveImageToGallery(resources: Resources) {
val imageBitmap: Bitmap = BitmapFactory.decodeResource(
resources,
R.drawable.img_tendency_result_ari,
)
val imageFileName = DOWNLOAD_IMAGE_NAME.replace("%s", viewModel.tendencyId.value.toString())
val path = DOWNLOAD_PATH

val uploadFolder = Environment.getExternalStoragePublicDirectory(path)
if (!uploadFolder.exists()) {
uploadFolder.mkdirs()
}

val imageFile = File(uploadFolder, imageFileName)

val outputStream = FileOutputStream(imageFile)
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
outputStream.flush()
outputStream.close()

scanFile(imageFile, "image/jpeg")

toast(getString(R.string.profile_image_download_success))
}

override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray,
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == PERMISSION_REQUEST_CODE) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startImageDownload()
} else {
toast(getString(R.string.profile_image_download_error))
}
}
}

private fun scanFile(file: File, mimeType: String) {
MediaScannerConnection.scanFile(
this,
arrayOf(file.absolutePath),
arrayOf(mimeType),
null,
)
}

companion object {
const val PERMISSION_REQUEST_CODE = 200
const val DOWNLOAD_PATH = "/Download/"
const val DOWNLOAD_IMAGE_NAME = "img_tendency_result%s.png"
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.going.presentation.tendency.result

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.going.domain.entity.ProfileMock
Expand All @@ -20,10 +21,13 @@ class TendencyResultViewModel @Inject constructor(
private val _userInfoState = MutableStateFlow<UiState<UserProfileRequestModel>>(UiState.Empty)
val userInfoState: StateFlow<UiState<UserProfileRequestModel>> = _userInfoState

val tendencyId = MutableLiveData(0)

fun getUserInfoState() {
viewModelScope.launch {
_userInfoState.value = UiState.Loading
profileRepository.getUserProfile().onSuccess {
tendencyId.value = it.result
_userInfoState.value = UiState.Success(it)
}.onFailure {
_userInfoState.value = UiState.Failure(it.message.toString())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ class TendencyTestActivity :
override fun onAnimationStart(animation: Animator) {
viewModel.clearAllChecked()
setProgressAnimate(binding.pbTendencyTest, viewModel.step.value)
fadeOutList.map {
it.start()
for (i in 1 until fadeOutList.size) {
fadeOutList[i].start()
}
}

Expand Down
2 changes: 2 additions & 0 deletions presentation/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@
<string name="profile_tv_name">두릅이</string>
<string name="profile_tv_one_line">나는 두릅이 좋다.</string>
<string name="profile_tv_restart_button"><u>다시 해볼래요</u></string>
<string name="profile_image_download_success">이미지가 저장되었어요\n친구에게 내 캐릭터를 공유해 보세요</string>
<string name="profile_image_download_error">저장할 수 없습니다\ndoorip에 사진에대한 엑세스 권한이 없습니다</string>

<!--enter_trip-->
<string name="enter_trip_tv_layout">여행 입장하기</string>
Expand Down