본문 바로가기
안드로이드

[WindowManager] 윈도우 매니저 개선하기 3 (실험 앱 만들기) Firebase Storage

by keel_im 2021. 1. 2.
반응형

이전글

2020/12/29 - [안드로이드] - [WindowManger] 윈도우 매니저 개선하기 2 (환경 구성하기)

 

[WindowManger] 윈도우 매니저 개선하기 2 (환경 구성하기)

2020/12/29 - [안드로이드] - [WindowManager] 윈도우 매니저 개선하기 1 빌드--> 포팅) 싸이클을 반복하여 프로젝트를 진행하였습니" data-og-host="keelim.tistory.com" data-og-source-url="https://keelim.tis..

keelim.tistory.com

이번 화에서 프로젝트에서 만든 앱에서 FIrebase 로 데이터를 저장을 하였는데 그 구성을 법을 적어보고자 합니다. 

Firebase

파이어베이스는 구글에서 사용을 할 수 있는 개발 플랫폼으로써 직접적인 백엔드의 구현없이 빠르게
사용을 할 수 있는 플랫폼입니다.  물론 비즈니스적으로 확장적으로 사용할 수 있다. (개인적으로 그렇게 생각한다.) 

first

위 사진처럼 다양한 서비스를 사용할 수 있습니다. 제가 이것을 사용을 하고자 했던 이유는 애플리케이션에서 측정한 데이터를 빠르고 간편하게 저장하고 외부로 빼냈으면 했습니다. 그래서 저는 Firebase 에서 Storage 를 사용했습니다. 

 

프로젝트 만들기

안드로이드 스튜디오를 사용을 한다면 정말 빠르게 설정을 할 수 있습니다. 저는 웹 환경에서 프로젝트를 설정하는 방법을 알려드립니다. 

https://console.firebase.google.com/

 

로그인 - Google 계정

하나의 계정으로 모든 Google 서비스를 Google 계정으로 로그인

accounts.google.com

위 링크로 접속을 하시어 파이어베이스 콘솔로 이동을 하여 웹페이지 상단에 보이는 프로젝트 추가를 눌러 줍니다.

위 설치 과정에 대로 설치를 해주시면 됩니다.

first

본인의 패키지 파일 형식에 맞추어 기입을 해줍니다.

특히 디버그 서명 인증서 SHA-1 를 기입을 하는 부분을 제일 어려워 하십니다.
문서에서는 자바에서 실행을 하는 방법, 따로 keytool 를 이용하는 방법이 있지만
저는 gradle task를 이용하는 방법이 제일 간편한것 같아 이를 소개합니다.

우선 안드로이드 스튜디오를 여시고 gradle task 를 실행해줍니다.
(shift*2 번을 누르시고 execute gradle task 를 눌러 주시면 됩니다.)

first

signinReport 기입해주시면 gradle task 가 실행이 되고 원하시는 값을 확인 할 수 있습니다.

Variant: debug 를 잘 확인을 하시면 됩니다.

이제 storage 를 쓰는 방법은 간단 합니다. -> 안드로이드 스튜디오의 firebase storage 관한 dependency
를 설정을 해주시고 코드를 작성해주시면 됩니다.

보안 설정이 기본인 경우는 따로 코드를 조작을 할 필요가 없이 접근만으로 파일 등을 업로드 할 수 있습니다.

onCreate 에서 인스턴스를 받아주셔야 합니다.

first

그리고 원하시는 부분에 아래 함수처럼 코드 로직을 작성을 하시고 버튼이나 따른 비즈니로직에서 붙여주시면
원하시는 데이터 파일이 바로 Firebase 스토리지의 저장이 되고 이를 확인할 수 있습니다.

 

예시 코드

  1. package com.keelim.testing.ui.result
  2.  
  3. import android.app.ProgressDialog
  4. import android.net.Uri
  5. import android.os.Bundle
  6. import android.view.View
  7. import android.view.animation.Animation
  8. import android.view.animation.AnimationUtils
  9. import android.widget.Toast
  10. import androidx.appcompat.app.AppCompatActivity
  11. import androidx.recyclerview.widget.LinearLayoutManager
  12. import com.google.android.material.snackbar.Snackbar
  13. import com.google.firebase.storage.FirebaseStorage
  14. import com.google.firebase.storage.StorageReference
  15. import com.keelim.testing.R
  16. import kotlinx.android.synthetic.main.activity_result.*
  17. import java.io.BufferedWriter
  18. import java.io.File
  19. import java.nio.charset.Charset
  20. import java.text.SimpleDateFormat
  21. import java.util.*
  22.  
  23. class ResultActivity : AppCompatActivity()View.OnClickListener {
  24.     private lateinit var resultArray: ArrayList<Long>
  25.     private lateinit var fab_open: Animation
  26.     private lateinit var fab_close: Animation
  27.     private lateinit var writer: BufferedWriter
  28.     private lateinit var ref: StorageReference
  29.     private var isFabOpen = true
  30.  
  31.     override fun onCreate(savedInstanceState: Bundle?) {
  32.         super.onCreate(savedInstanceState)
  33.         setContentView(R.layout.activity_result)
  34.  
  35.         ref = FirebaseStorage.getInstance().reference // 파이어베이스 스토리지지
  36.  
  37.         fab_open = AnimationUtils.loadAnimation(applicationContext, R.anim.fab_open);
  38.         fab_close = AnimationUtils.loadAnimation(applicationContext, R.anim.fab_close);
  39.  
  40.         resultArray = intent.getSerializableExtra("result") as ArrayList<Long>
  41.         // array List 를 받는다.
  42.         result_recycler.apply {
  43.             setHasFixedSize(true)
  44.             layoutManager = LinearLayoutManager(this@ResultActivity)
  45.             adapter = ResultAdapter(resultArray)
  46.         }
  47.  
  48.         fab1.setOnClickListener(this);
  49.         fab2.setOnClickListener(this);
  50.         fab3.setOnClickListener(this);
  51.     }
  52.  
  53.     override fun onClick(v: View) {
  54.         val id = v.id
  55.         when (id) {
  56.             R.id.fab1 -> {anim()}
  57.             R.id.fab2 -> {makingData()}
  58.             R.id.fab3 -> {uploadToServer()}
  59.         }
  60.     }
  61.  
  62.     fun anim() {
  63.         if (isFabOpen) {
  64.             fab2.startAnimation(fab_close)
  65.             fab3.startAnimation(fab_close)
  66.             fab2.isClickable = false
  67.             fab3.isClickable = false
  68.             isFabOpen = false
  69.         } else {
  70.             fab2.startAnimation(fab_open)
  71.             fab3.startAnimation(fab_open)
  72.             fab2.isClickable = true
  73.             fab3.isClickable = true
  74.             isFabOpen = true
  75.         }
  76.     }
  77.  
  78.     private fun uploadToServer() { // 서버에 올린다 파이어 스토어
  79.         //if there is a file to upload
  80.         val file = File(application.filesDir, getString(R.string.file))
  81.  
  82.         if (!file.exists()) {
  83.             Toast.makeText(this"데이터 파일을 확인해세요", Toast.LENGTH_SHORT).show()
  84.             return
  85.         }
  86.  
  87.         val filePath = Uri.fromFile(file)
  88.         //displaying a progress dialog while upload is going on
  89.         val progressDialog = ProgressDialog(this)
  90.             .setTitle("Uploading...")
  91.             .show()
  92.  
  93.         val timestamp = SimpleDateFormat("yyyyMMdd_HHmmss"Locale.KOREA).format(Date())
  94.         val riversRef: StorageReference = ref.child("data/data${timestamp}.csv")
  95.  
  96.         riversRef.putFile(filePath)
  97.                 .addOnSuccessListener {
  98.                     progressDialog.dismiss()
  99.                     Toast.makeText(this"File Uploaded", Toast.LENGTH_LONG).show()
  100.                 }
  101.                 .addOnFailureListener { exception ->
  102.                     progressDialog.dismiss()
  103.                     Toast.makeText(this, exception.message, Toast.LENGTH_LONG).show()
  104.                 }
  105.                 .addOnProgressListener { taskSnapshot ->
  106.  
  107.                     val progress = 100.0 * taskSnapshot.bytesTransferred / taskSnapshot.totalByteCount
  108.                     progressDialog.setMessage("Uploaded " + progress.toInt() + "%...")
  109.                 }
  110.     }
  111.  
  112.     private fun makingData() {
  113.         val lineSeparator = System.getProperty("line.separator")
  114.         val fOut = openFileOutput(getString(R.string.file), MODE_PRIVATE)
  115.  
  116.         for (in resultArray) {
  117.             fOut.apply {
  118.                 write(i.toString().toByteArray(Charset.defaultCharset()))
  119.                 write(lineSeparator.toByteArray(Charset.defaultCharset()))
  120.                 fOut.flush()
  121.             }
  122.         }
  123.  
  124.         fOut.close()
  125.  
  126.         val file = File(application.filesDir, getString(R.string.file))
  127.         if (file.exists()) Snackbar.make(result_container, "파일이 정상적으로 생성되었습니다. ", Snackbar.LENGTH_SHORT).show()
  128.         else Snackbar.make(result_container, "파일 생성에 오류가 있습니다.", Snackbar.LENGTH_SHORT).show()
  129.     }
  130. }
  131.  

🧶 모든 문서는 수정될 수 있습니다. 

반응형

댓글