NOW OR NEVER

[Android] 사진 저장 & Network 본문

Android

[Android] 사진 저장 & Network

LAURA 2023. 7. 18. 17:28
반응형

사진 저장

  • 권한
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION"/>
  • 매번 실행할 때 마다 이미지, 음악 등을 검색해서 보여주는 것이 아니기 때문에 로딩이 느리지 않다. 정보를 추출하여 자기가 관리하는 데이터베이스에 저장하고 있다가 그 정보를 전달하는 개념
  • 에뮬레이터 이용하는 경우 사진 미리 저장해두는 법
    • ~/Library/Android/sdk/avd/[에뮬레이터 이름]/sdcard/ : Mac의 경우 이 경로로 에뮬레이터의 가상 SD 카드 디렉토리로 이동한 다음, 해당 디렉토리에 사진 파일을 복사해 넣기

네트워크

socket server

  • 서버는 인텔리 제이 작업 / 클라이언트는 안드로이드 스튜디오 작업
  • 서버 프로젝트 실행 후 클라이언트 프로젝트 실행
  • 서버
    • 서버가 클라이언트에게 데이터 전달
    • 특정 클라이언트가 문제가 생기면 그 클라이언트 연결만 끊으면 되지만 서버의 경우 에러가 나면 다 문제가 생길 수 있다.
    • 서버의 경우 모든 예상 가능한 문제에 대비하더라도 예상 못한 문제가 발생할 수 있는 변수가 있기 때문에 그만큼 소켓서버를 안정적으로 운영하는 것이 어렵다.
    • ServerSocket()
      •  코틀린 프로젝트 생성 시 가장 먼저 객체 생성해야 하는 클래스
      •  정해진 포트 번호를 쓰자 약속을 위해 만듦
    • 서버 포트 이미 쓰고 있는 경우 해당 에러 발생하므로 포트 번호 바꾸거나 컴퓨터 재부팅 시행(Address already in use)
    •  
  • 클라이언트
    • 안드로이드(클라이언트 쪽) 코드 작성 시 네트워크 관련 코드는 thread 안에서 작성해야 한다
    • kotlin 언어 사용하는 경우 runOnUiThread는 작성하지 않아도 된다.
    •  안드로이드 어플리케이션 제작 시 ip주소 127.0.0.1은 단말기 자체를 의미하기 때문에 ip주소는 개발자 컴퓨터의 ip주소(공유기 상에서의 ip 주소)를 사용해야 한다.
      • 같은 공유기에 서버와 클라이언트가 연결되어 있어야만 테스트 가능
      • 가정용 ip 주소는 변경되므로 집에서 서버 운영하면 안된다.
      • IP 주소 확인(mac) : 시스템 설정 - 네트워크 - 초록색 들어온 거 클릭 (wifi 등)- 세부사항 - ip주소 or 터미널에서 ifconfig

XML과 JSON 통신

 

Big List of Free and Open Public APIs (No Auth Needed) [2023]

An API (Application Programming Interface) allows you to send and receive data from a remote server, like querying a database. This is helpful when you're building an app or pulling metrics for…

mixedanalytics.com

  • xml이나 JSON이나 받아들이는 것은 문자열이다.

 XML

  • 공식 표준 문서 : 전자 문서 등을 위해 만들어짐.
  • xml에서 간단하게 작성하고 코드에서 처리하자는 방식으로 많이 감
  • 태그와 태그 사이에 값 작성
  • 태그 안에 속성 작성 가능
  • xml문서에 대한 설명 문서가 필요하다(태그 의미, 태그 안 값 의미 등 설명되어 있는 것)
  • xml 규격 양식 : xml문서는 항상 모든 태그들을 둘러싸고 있는 최상위 태그가 반드시 존재해야 한다. 없으면 해석과 분석 불가

JSON 

  • JavaScript Object Notation
  • 국제 표준 문서 x
  • {}을 통해 간결하게 데이터 표시
  • 문법
    • { } : JSONObject, 이름 - 값 형태
    • [ ] : JSONArray, 0부터 1씩 증가하는 순서값을 가지고 관리
  • 데이터 타입이 다 명시되어 있음
  • xml보다 분석하거나 해석하는 것이 더 쉽다.
  • 서버 직접 만들 경우 JSON 권장

통신 방법

  • SAX : 메모리를 적게 쓰지만 작업이 복잡
  • DOM : 메모리를 많이 쓰지만 작업이 깔끔하고 간결

DOM

  • 클라이언트
    •  Manifest 인터넷 권한 추가 : <uses-permission android:name="android.permission.INTERNET"/>
    • xml
thread {

    // 접속 주소를 관리하는 객체를 생성한다.
    val url = URL(serverAddress)

    // 접속한다.
    val httpUrlConnection = url.openConnection() as HttpURLConnection

    // 웹 브라우저 종류를 확인할 수도 있기 때문에....
    httpUrlConnection.addRequestProperty("User-Agent", "")

    // DOM 방식으로 XML 문서를 분석할 수 있는 도구를 생성한다.
    val documentBuilderFactory = DocumentBuilderFactory.newInstance()
    val documentBuilder = documentBuilderFactory.newDocumentBuilder()
    // 분석 도구를 이용해 XML 문서를 분석해 각 태그들을 모두 객체로 생성한다.
    // 태그들을 관리하는 객체를 반환한다.
    val document = documentBuilder.parse(httpUrlConnection.inputStream)

    // 최 상위 태그를 가져온다.
    val root = document.documentElement

    // data tag를 가져온다.
    val dataTag = root.getElementsByTagName("data")
    // METAR tag를 가져온다.
    val dataElement = dataTag.item(0) as Element // 첫번째 가져오기
    val METATag = dataElement.getElementsByTagName("METAR")

    runOnUiThread {
        textView.text = ""
    }

    // 태그의 수 만큼 반복한다.
    for(idx in 0 until METATag.length){
        // idx 번째 태그 객체를 가져온다.
        val METAElement = METATag.item(idx) as Element

        // META 태그 내에서 필요한 태그들을 가져온다.
        val rawTextList = METAElement.getElementsByTagName("raw_text")
        val stationIdList = METAElement.getElementsByTagName("station_id")
        val latitudeList = METAElement.getElementsByTagName("latitude")
        val longitudeList = METAElement.getElementsByTagName("longitude")

        val rowTextTag = rawTextList.item(0) as Element
        val stationIdTag = stationIdList.item(0) as Element
        val latitudeTag = latitudeList.item(0) as Element
        val longitudeTag = longitudeList.item(0) as Element

        // 태그내의 데이터를 가져온다.
        val rowText = rowTextTag.textContent
        val stationId = stationIdTag.textContent
        val latitude = latitudeTag.textContent.toDouble()
        val longitude = longitudeTag.textContent.toDouble()

        runOnUiThread {
            textView.append("rowText : ${rowText}\n")
            textView.append("stationId : ${stationId}\n")
            textView.append("latitude : ${latitude}\n")
            textView.append("longitude : ${longitude}\n\n")
        }

    }

}

 

  • json
thread{
    // URL 객체 생성
    val url = URL(serverAddress)
    // 접속 후 스트림 추출
    val httpURLConnection = url.openConnection() as HttpURLConnection

    val inputStreamReader = InputStreamReader(httpURLConnection.inputStream, "UTF-8")
    val bufferedReader = BufferedReader(inputStreamReader)

    var str:String? = null
    val stringBuffer = StringBuffer()
    // 문서의 마지막까지 읽어온다.
    do{
        str = bufferedReader.readLine()
        if(str != null){
            stringBuffer.append(str)
        }
    }while(str != null)

    val data = stringBuffer.toString()
    runOnUiThread {
        textView.text = data
    }

 


ETC

  • 권한 설정 시 mainfest 권한 안뜨면 아래 사항 작성했는 지 확인 : import android.Manifest

 

Comments