본문 바로가기
CODING/Android Studio

[안드로이드/인스타그램클론] # 6 사진 업로드 페이지 만들기

by 밍톨맹톨 2020. 8. 17.
728x90
728x90

[ 이전 글 ] 에서 메인 화면 네비게이션 바를 만들어 보았고 이번에는 사진을 업로드 할 수 있는 페이지를 만들어 볼 것이다.

 

이전에 main activity - add photo부분은 

R.id.action_add_photo->{
               
                return true
            }

이렇게 비어있어서 아무런 기능을 하지 않았는데 이제는

이렇게 에뮬레이터 안에 있는 갤러리를 열어 사진firebase storage에 넣어줄 수 있도록 만들어 볼 것이다 ! 

 


일단 새로운 Empty Acivitiy [ "AddPhotoActivity" ] 를 만들어준다

그리고 나서 activity_add_photo.xml 에 들어가서

 

⬇️ [ activity_add_photo.xml ] 전체

더보기
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".AddPhotoActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/my_toolbar"
        android:layout_width="match_parent"
        android:layout_height="35dp">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/logo_title"/>
    </androidx.appcompat.widget.Toolbar>
    <LinearLayout
        android:id="@+id/toolbar_division"
        android:background="@color/colorDivision"
        android:layout_below="@id/my_toolbar"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="1dp"></LinearLayout>
    <ImageView
        android:id="@+id/addphoto_image"
        android:layout_margin="8dp"
        android:layout_below="@id/toolbar_division"
        android:layout_width="100dp"
        android:layout_height="100dp"/>
        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/editText"
            android:layout_below="@id/toolbar_division"
            android:layout_toRightOf="@id/addphoto_image"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <EditText
                android:gravity="top"
                android:id="@+id/addphoto_edit_explain"
                android:hint="@string/hint_image_content"
                android:layout_width="match_parent"
                android:layout_height="100dp"/>
        </com.google.android.material.textfield.TextInputLayout>
        <Button
            android:id="@+id/addphoto_btn_upload"
            android:text="@string/upload_image"
            android:layout_below="@id/editText"
            android:layout_toRightOf="@id/addphoto_image"
            android:theme="@style/ButtonStyle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
</RelativeLayout>

툴바는 저번과 같이 구성해주고

사진이 들어갈 부분 ]

   <ImageView
        android:id="@+id/addphoto_image"
        android:layout_margin="8dp"
        android:layout_below="@id/toolbar_division"
        android:layout_width="100dp"
        android:layout_height="100dp"/>

사진에 대한 설명을 쓸 수 있는 부분 ]

<com.google.android.material.textfield.TextInputLayout
            android:id="@+id/editText"
            android:layout_below="@id/toolbar_division"
            android:layout_toRightOf="@id/addphoto_image"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <EditText
                android:gravity="top"
                android:id="@+id/addphoto_edit_explain"
                android:hint="@string/hint_image_content"
                android:layout_width="match_parent"
                android:layout_height="100dp"/>
        </com.google.android.material.textfield.TextInputLayout>

[ 사진 업로드 버튼 ]

<Button
            android:id="@+id/addphoto_btn_upload"
            android:text="@string/upload_image"
            android:layout_below="@id/editText"
            android:layout_toRightOf="@id/addphoto_image"
            android:theme="@style/ButtonStyle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

이렇게 해주면

activity_add_photo.xml 화면


[ Firabase storage 추가

그리고 나서 firebase storage를 사용할 것이기 때문에 

빨간 박스에 들어가서 [ implementation 'com.google.firebase:firebase-storage:19.1.1' ] 을 추가해준 후 sync now를 누른다

강의에서와 버젼이 다르긴 한데 어떻게 맞춰야하지 하다가 firebase-auth랑 똑같이 쓰면 아래와 같이 오류가 나는데 

Show in Project Structure dialog 를 누르면

이 화면이 뜨고 requested version을 눌러 가장 위에 있는 버젼을 선택한 후 OK를 누르면 해결된다.


[ AddPhothActivity.kt ]

더보기
package com.example.mingstagram

import android.app.Activity
import android.content.Intent
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import com.google.firebase.storage.FirebaseStorage
import kotlinx.android.synthetic.main.activity_add_photo.*
import java.text.SimpleDateFormat
import java.util.*

class AddPhotoActivity : AppCompatActivity() {
    var PICK_IMAGE_FROM_ALBUM = 0 // request code
    var storage: FirebaseStorage? = null
    var photoUri: Uri? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_add_photo)

        //Initiate storage
        storage = FirebaseStorage.getInstance()

        //Open the album
        var photoPickerIntent = Intent(Intent.ACTION_PICK)
        photoPickerIntent.type = "image/*"
        startActivityForResult(photoPickerIntent, PICK_IMAGE_FROM_ALBUM)

        //add image upload event
        addphoto_btn_upload.setOnClickListener {
            contentUpload()
        }

    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == PICK_IMAGE_FROM_ALBUM)
            if (resultCode == Activity.RESULT_OK) {
                // This is path to the selected image
                photoUri = data?.data
                addphoto_image.setImageURI(photoUri)
            } else {
                //exit the addPhotoActivity if you leave the album without selecting it
                finish()
            }
    }

    fun contentUpload() {
        //Make file name

        var timestamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
        var imageFileName = "IMAGE_" + timestamp + "_.png"

        var storageRef = storage?.reference?.child("images")?.child(imageFileName)

        //File upload
        storageRef?.putFile(photoUri!!)?.addOnSuccessListener {
            Toast.makeText(this,getString(R.string.upload_success),Toast.LENGTH_LONG).show()
        }
    }
}
var PICK_IMAGE_FROM_ALBUM = 0 // request code
var storage: FirebaseStorage? = null
var photoUri: Uri? = null

🌿 storage - FirebaseStorage 객체를 담은 변수

🌿 photoUri - 사진의 Uri 를 담을 변수

 

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_add_photo)

        //Initiate storage
        storage = FirebaseStorage.getInstance()

        //Open the album
        var photoPickerIntent = Intent(Intent.ACTION_PICK)
        photoPickerIntent.type = "image/*"
        startActivityForResult(photoPickerIntent, PICK_IMAGE_FROM_ALBUM)

        //add image upload event
        addphoto_btn_upload.setOnClickListener {
            contentUpload()
        }

    }

 - storageFirebaseStorage를 가져오고 

 - Intent(Intent.ACTION_PICK)을 사용하면 사진을 가져올 수 있다

 - startActivityForResult(photoPickerIntent, PICK_IMAGE_FROM_ALBUM는 이미지 정보를 넘겨주는 역할을 한다

 - 마지막은 버튼을 누르면 사진firebase에 저장되게 된다.

 

 

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == PICK_IMAGE_FROM_ALBUM)
            if (resultCode == Activity.RESULT_OK) {
                // This is path to the selected image
                photoUri = data?.data
                addphoto_image.setImageURI(photoUri)
            } else {
                //exit the addPhotoActivity if you leave the album without selecting it
                finish()
            }
    }

- requestCodePICK_IMAGE_FROM_ALBUMresultCode가 엑티비티가 성공했을 때, 즉 사진을 골랐을 때라면 photoUri경로를  넣어주고, imageaddphoto_image에 표시할 수 있게 해줌

 

- 그 경우가 아니면 끝내기

 

    fun contentUpload() {
        //Make file name

        var timestamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
        var imageFileName = "IMAGE_" + timestamp + "_.png"

        var storageRef = storage?.reference?.child("images")?.child(imageFileName)

        //File upload
        storageRef?.putFile(photoUri!!)?.addOnSuccessListener {
            Toast.makeText(this,getString(R.string.upload_success),Toast.LENGTH_LONG).show()
        }
    }

 

 - 이미지의 이름이 중복되지 않게 하기 위해서 날짜값을 이미지 파일명으로 지정해주고 

 - storageRef첫번째폴더명, 두번째파일 이름을 넣어준다 

 - 올리고 나면 성공했다고 toast 띄우기

 


이제 메인으로 가서 add photo 를 눌렀을 때 사진을 추가할 수 있도록 해줄 것이다.

[ MainActivity.kt

 

아까 제일 위에서 말했던 비어있던 부분에 아래와 같은 코드를 추가한다.

R.id.action_add_photo->{
                if(ContextCompat.checkSelfPermission(this,android.Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED){
                    startActivity(Intent(this,AddPhotoActivity::class.java))
                }
                return true
            }

  - if 문 안에 있는 코드 - 외부 storage 경로를 가지고 올 수있는지 확인하고 AddPhotoActivity로  보내기

 

그 전에 권한요청을 받기 위해서 OnCreate 부분에

ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.READ_EXTERNAL_STORAGE),1)

 

위와 같은 코드를 넣어줘야한다.

 


[ AndroidManifest.xml ]

 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

사용할 권한을 등록하는 과정 

 

[ Firebase strage 사용 허용 ]

 

 


이렇게 하고 나면 사진을 등록 할 수 있게 된다.

 

동작화면

오늘도 이렇게 끝👩🏻‍💻‼️ 

728x90

댓글