- 원형 이미지 뷰를 클릭하면 앨범을 호출한다.
- 선택 된 이미지의 uri를 전달 받아 ImageView에 표시한다.
- 등록하기 버튼을 클릭하면 Storage에 파일을 업로드한다.
- Storage 파일 업로드가 성공일 경우 Toast 메시지를 띄워준다.
Firebase Console 화면에서 빌드 탭 아래 Storage 메뉴를 클릭한다.
Storage 메뉴에서 시작하기를 클릭한다.
시작하기를 클릭하면 Cloude Storage 설정 팝업이 나타난다. 첫 번째로 보안 규칙을 설정한다.
설정 팝업에서 두 번째로 위치를 설정한다.
설정이 완료되면 보안 규칙(Rules) 탭에서 read, write 설정을 다음과 같이 true로 수정해준다.
모듈(앱 수준) Gradle 파일에서 storage 라이브러리의 종속 항목을 추가한다.
dependencies {
implementation platform('com.google.firebase:firebase-bom:31.2.2')
implementation 'com.google.firebase:firebase-storage-ktx'
}
이미지를 업로드/다운로드 하기 위해 파일을 가리키는 Cloude Storage 참조를 생성한다.
// storage 인스턴스 생성
val storage = Firebase.storage
// storage 참조
val storageRef = storage.getReference("image")
// 파일 경로와 이름으로 참조 변수 생성
val fileName = SimpleDateFormat("yyyyMMddHHmmss").format(Date())
val mountainsRef = storageRef.child("${fileName}.png")
파일을 업로드 하는 함수로 저장되는 파일의 이름이 중복되는 것을 방지하고자 파일명에 날짜를 넣어 저장한다.
파일을 가리키는 참조를 생성한 후 putFile에 이미지 파일 uri를 넣어 파일을 업로드한다.
private fun imageUpload(uri: Uri) {
// storage 인스턴스 생성
val storage = Firebase.storage
// storage 참조
val storageRef = storage.getReference("image")
// storage에 저장할 파일명 선언
val fileName = SimpleDateFormat("yyyyMMddHHmmss").format(Date())
val mountainsRef = storageRef.child("${fileName}.png")
val uploadTask = mountainsRef.putFile(uri)
uploadTask.addOnSuccessListener { taskSnapshot ->
// 파일 업로드 성공
Toast.makeText(getActivity(), "사진 업로드 성공", Toast.LENGTH_SHORT).show();
}.addOnFailureListener {
// 파일 업로드 실패
Toast.makeText(getActivity(), "사진 업로드 실패", Toast.LENGTH_SHORT).show();
}
}
URL을 통해 파일을 다운로드 하는 함수로 성공했을 경우 파일의 url을 가져온다.
private fun imageDownload() {
// storage 인스턴스 생성
val storage = Firebase.storage
// storage 참조
val storageRef = storage.getReference("image")
// storage에서 가져올 파일명 선언
val fileName = SimpleDateFormat("yyyyMMddHHmmss").format(Date())
val mountainsRef = storageRef.child("${fileName}.png")
val downloadTask = mountainsRef.downloadUrl
downloadTask.addOnSuccessListener { uri ->
// 파일 다운로드 성공
// Glide를 사용하여 이미지를 ImageView에 직접 가져오기
Glide.with(mainActivity).load(uri).into(binding.imageArea)
}.addOnFailureListener {
// 파일 다운로드 실패
}
}
파일을 삭제하는 함수로 파일을 가리키는 참조를 생성한 후 delete() 메서드를 호출한다.
private fun imageDelete() {
// storage 인스턴스 생성
val storage = Firebase.storage
// storage 참조
val storageRef = storage.getReference("image")
// storage에서 삭제 할 파일명
val fileName = SimpleDateFormat("yyyyMMddHHmmss").format(Date())
val mountainsRef = storageRef.child("${fileName}.png")
val deleteTask = mountainsRef.delete()
deleteTask.addOnCompleteListener {
// 파일 삭제 성공
}.addOnFailureListener {
// 파일 삭제 실패
}
}
먼저 앱 수준 Gradle 파일에서 원형 이미지뷰를 구현하기 위해 'de.hdodenhof:circleimageview:3.1.0'를 추가하고,
이미지를 다운로드 받아서 이미지뷰에 표시하기 위해 'com.github.bumptech.glide:glide:4.12.0'를 추가해준다.
dependencies {
implementation 'com.github.bumptech.glide:glide:4.12.0'
implementation 'de.hdodenhof:circleimageview:3.1.0'
}
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragment.UserFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="프로필 이미지"
android:textColor="@color/black"
android:textSize="20sp"
android:textStyle="bold" />
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/imageArea"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_gravity="center"
android:layout_margin="20dp"
android:src="@drawable/profile" />
<Button
android:id="@+id/btnRegister"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:background="@color/black"
android:text="업로드하기"
android:textColor="@color/white"
android:textSize="18sp" />
</LinearLayout>
</FrameLayout>
</layout>
📌 registerForActivityResult
- Activity에서 결과를 받아올 때 startActivityForResult() 와 onActivityResult()를 사용 했지만
deprecated 되었기에 registerForActivityResult를 사용한다.- registerForActivityResult는 initialization, onAttach(), onCreate() 에서
registerForActivityResult()를 호출 해야 한다.- 사용 방법
- registerForActivityResult를 사용해서 결과 콜백을 등록한다.
결과를 받기 위해서 액티비티를 실행하는 StartActivityForResult()를 인자 값으로 넣어준다.
result 객체가 파라미터로 전달되고 result 객체를 통해 원하는 데이터를 얻을 수 있다.- launch()를 통해 데이터를 받아올 액티비티를 실행한다.
class UserFragment : Fragment() {
private lateinit var binding: FragmentUserBinding
private lateinit var uri: Uri
lateinit var mainActivity: MainActivity
override fun onAttach(context: Context) {
super.onAttach(context)
mainActivity = context as MainActivity
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_user, container, false)
// 이미지뷰를 눌렀을 경우
binding.imageArea.setOnClickListener {
// ACTION_PICK을 사용하여 앨범을 호출한다.
val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI)
registerForActivityResult.launch(intent)
}
// 등록하기 버튼을 눌렀을 경우
binding.btnRegister.setOnClickListener {
imageUpload(uri)
}
return binding.root
}
private val registerForActivityResult =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
when (result.resultCode) {
AppCompatActivity.RESULT_OK -> {
// 변수 uri에 전달 받은 이미지 uri를 넣어준다.
uri = result.data?.data!!
// 이미지를 ImageView에 표시한다.
binding.imageArea.setImageURI(uri)
}
}
}
private fun imageUpload(uri: Uri) {
// storage 인스턴스 생성
val storage = Firebase.storage
// storage 참조
val storageRef = storage.getReference("image")
// storage에 저장할 파일명 선언
val fileName = SimpleDateFormat("yyyyMMddHHmmss").format(Date())
val mountainsRef = storageRef.child("${fileName}.png")
val uploadTask = mountainsRef.putFile(uri)
uploadTask.addOnSuccessListener { taskSnapshot ->
// 파일 업로드 성공
Toast.makeText(getActivity(), "사진 업로드 성공", Toast.LENGTH_SHORT).show();
}.addOnFailureListener {
// 파일 업로드 실패
Toast.makeText(getActivity(), "사진 업로드 실패", Toast.LENGTH_SHORT).show();
}
}
}