| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
| 29 | 30 | 31 |
- include태그
- 안드로이드스튜디오
- hilt오류
- 자바
- glide
- SpringBoot
- 안드로이드 스튜디오 JAVA
- include이벤트처리
- 리사이클러뷰
- SpringWebFlux
- 종속항목삽입
- 안드로이드로딩창
- 프론트엔드
- 공공데이터포털리사이클러뷰
- Hilt
- 안드로이드 스튜디오
- 안드로이드 스튜디오 API
- kotlin
- 데이터바인딩
- Today
- Total
내일은개발왕
안드로이드 스튜디오 - 리사이클러뷰를 이용해서 사용자가 입력한 값 대로 공공데이터 포털 API에서 결과값 가져오기 - (2) 본문
| ※ 주의사항 및 안내 1. 독학으로 진행하였기 때문에, 잘못된 부분이 있을 수 있습니다. 잘못된 부분은 언제든지 댓글로 피드백 해주세요. 빠르게 고치겠습니다. 2. 모르시는 부분이 있으시다면 언제든지 댓글을 남겨주세요. 제 힘이 닿는 곳까지 도와드리겠습니다. 3. 안드로이드 스튜디오를 설치 하셨다는 가정하에 진행합니다. 4. JAVA로 진행합니다. |
https://imformation-program-forme.tistory.com/8
안드로이드 스튜디오 - 리사이클러뷰를 이용해서 사용자가 입력한 값 대로 공공데이터 포털 API
※ 주의사항 및 안내 1. 독학으로 진행하였기 때문에, 잘못된 부분이 있을 수 있습니다. 잘못된 부분은 언제든지 댓글로 피드백 해주세요. 빠르게 고치겠습니다. 2. 모르시는 부분이 있으시다면
imformation-program-forme.tistory.com
위 글과 이어지는 글입니다!
1장에서 UI 및 사용자로부터 값을 받아오는 소스코드를 작성했었다. 그리고 Intent를 이용해 입력받은 값을 다른 액티비티로 넘겨줄 수 있도록 코드도 작성해뒀다.
그럼 이제 받아온 값을 이용해 공공데이터 포털 API와 연결해 데이터를 가져올 수 있도록 UI와 소스코드를 작성해야 한다.
사용할 API는 아래와 같다.
https://www.data.go.kr/tcs/dss/selectApiDataDetailView.do?publicDataPk=15006353
해양수산부_선박운항정보
항만, 호출부호, 선명, 입출항일시, 입출항목적, 최종목적지 등 전국무역항에 대한 선박의 입항 및 출항 신고 정보(조회기간은 입항일기준 검색시작일 ~ 검색종료일)
www.data.go.kr
먼저 공공데이터 포털 회원가입을 한 후, 개인API를 발급 받아야한다.
개인 API를 발급 받고 난 후, 다시 위 선박운항정보 API에 들어가보면 상세한 설명이 쓰여져 있다.
여기서 우리가 눈여겨 봐야 할 곳은 "요청변수" 라는 부분이다.

이 값들을 입력해서 연결해야 최종적으로 우리가 원하는 데이터 값을 얻어올 수 있다. 근데 얻어오기 전 데이터 구조가 어떻게 되어있는지를 파악해야하니 일단 브라우저에서 데이터 형식을 확인해봐야 한다.
일단 빈 브라우저를 아무거나 실행시키고, 아래 링크를 복사 한다음 내가 발급받은 서비스키 부분을 집어넣어 URL에 붙여넣기를 한다. 그럼 xml 파일 화면이 뜰것이다.
공공데이터 포털에서 제공하는 샘플 데이터 같은 경우, 실존하지 않는 데이터이기에 작년에 연결되는 데이터를 찾아두었었다. 애플리케이션에서 최종적으로 테스트할때도, 이 예제를 사용하면 된다.

이 화면이 공공데이터 포털에서 가져오게 된 결과값이다. xml의 구조를 살펴보자
최상위 부모 태그로 <items> 가 있고, 이 최상위 부모 태그가 모든 자식 태그들을 감싸고 있는 형태다.
부모태그의 자식 태그로 <item> , <item>의 자식 태그로 우리가 원하는 결과값이 들어있다. 그리고 <item>에는 <details> 라는 좀 더 세부적인 정보를 담고있는 태그가 있으며, <detalis>의 자식 태그로 <detail>이 존재함을 확인할 수 있다.

우리는 이것을 보고 <item> ~ </item> 까지가 선박 하나에 대한 입출항 데이터라는 것을 알수있다. 여기서 우리가 필요한 데이터들만 뽑아내야한다.그리고 3개의 결과값이 모두 나타나도록 해야한다. 이에 대한 소스코드를 작성해보자.
1. 리사이클러뷰 UI 만들기 (User Interface)
1장에서 깜빡하고 리사이클러뷰 XML 코드를 안올려서, 여기서부터 시작하겠다. 아래와 같은 XML파일을 만들것이다. 필요한 UI 파일은 올려두었으니, 다운받아서 사용하면 된다.

리사이클러뷰를 내가 이해한대로 설명해보자면, 결과값의 수대로 출력되는 부분적인 화면을 만들어 보여주는 기능이라고 생각하면 된다. 출력해야 하는 결과가 몇개인지 알더라도, 그 수대로 파일을 하나하나 만들어서 출력하는 것은 굉장히 비효율적이다. 그래서 리사이클러뷰를 사용하여 하나의 xml파일로 여러개의 결과값을 추출할 것이다.
수많은 데이터 목록 중 우리가 뽑아낼 데이터 목록 총 15가지로 다음과 같다. 표를 올리는 이유는 사용할 변수명을 공공데이터 포탈에서 제공하는 이름과 동일하게 적용할 것이기 때문이다.
| <item>부분 | <detail>부분 | |||
| 항구청코드 | prtAgCd | 입항일시 | 입항일시 | |
| 항구청명 | prtAgNm | 출항일시 | tkoffDt | |
| 호출부호 | clsgn | 내외항구분명 | ibobprtNm | |
| 선박명 | vsslNm | 계선시설명 | laidupFcltyNm | |
| 선박국가명 | vsslNltyNm | 화물명세 | ldadngFrghtClCd | |
| 선박종류명 | vsslKndNm | 총톤수 | grtg | |
| 입항목적명 | etryptPurpsNm | 신고업체명 | satmntEntrpsNm | |
| 목적지항구명 | dstnPrtNm | |||
그럼 이제 XML 파일을 만들어보자
res -> layout -> 우클릭 -> new -> layout resiurce를 클릭해 새로운 xml 파일을 생성해준다

그럼 가운데에 hello wolrd!가 있는 빈 창이 만들어질텐데, 그 텍스트를 클릭 후 delete키를 눌러 지워주자

지웠다면 split을 클릭해 코드와 화면을 동시에 볼 수 있도록 하자. 먼저, 레이아웃의 크기를 조금 줄여줄것이다.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_width="match_parent"
android:layout_height="630dp"
android:layout_marginTop="5dp">
높이는 630dp으로, 넓이는 현재 레이아웃의 크기만큼으로 설정해줬고, 좌/우/위로 간격을 5dp씩 주었다. 레이아웃 크기 조절은 여기서 끝이다. 그럼 이제 UI를 적용시켜보자
drawable에 첨부파일에 있던 이미지들을 복사 붙여넣기하고, 붙여넣기한 이미지 자료 중, recycler_background 라는 이미지가 있을것이다. 그 이미지를 가져오자
필자는 이름을 result_ship_data 로 변경해둬서 이름만 다르다.
<ImageView
android:id="@+id/imageView7"
android:layout_width="403dp"
android:layout_height="626dp"
android:background="#00ffffff"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@drawable/result_ship_data" />
배경 이미지를 가져와줬으니, 이제 가져온 데이터를 보여줄 텍스트들을 추가하자
텍스트를 추가하는 것은 간단하기에 굳이 설명하지 않겠다. TextView를 사용하면 된다. (그냥 끌어와서 배치하면 된다.) 단, 여기서 중요한 것은 결과값을 보여 줄 text에는 id를 적어두어야 하는데, 잘 구분할 수 있도록 공공데이터 포털측에서 제공했던 변수 이름을 사용할 것이다. 필자가 사용한 id는 아래 표와 같다.
| <item>부분 | <detail>부분 | |||
| 항구청코드 | shipdata_adapter_prtAgCd | 입항일시 | shipdata_adapter_ etryptDt |
|
| 항구청명 | shipdata_adapter_prtAgNm | 출항일시 | shipdata_adapter_ tkoffDt |
|
| 호출부호 | shipdata_adapter_clsgn | 내외항구분명 | shipdata_adapter_ ibobprtNm |
|
| 선박명 | shipdata_adapter_ vsslNm |
계선시설명 | shipdata_adapter_ laidupFcltyNm |
|
| 선박국가명 | shipdata_adapter_ vsslNltyNm |
화물명세 | shipdata_adapter_ ldadngFrghtClCd |
|
| 선박종류명 | shipdata_adapter_ vsslKndNm |
총톤수 | shipdata_adapter_grtg | |
| 입항목적명 | shipdata_adapter_ etryptPurpsNm |
신고업체명 | shipdata_adapter_ satmntEntrpsNm |
|
| 목적지항구명 | shipdata_adapter_ dstnPrtNm |
|||
그리고 recylcer 사용을 위한 xml의 전체 코드는 아래와 같다.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_width="match_parent"
android:layout_height="630dp"
android:layout_marginTop="5dp">
<ImageView
android:id="@+id/imageView7"
android:layout_width="403dp"
android:layout_height="626dp"
android:background="#00ffffff"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@drawable/result_ship_data" />
<TextView
android:id="@+id/shipdata_adapter_prtAgCd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_medium"
android:text="항구청코드"
android:textColor="#303030"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="@+id/imageView7"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/textView62"
app:layout_constraintTop_toTopOf="@+id/imageView7"
app:layout_constraintVertical_bias="0.328" />
<TextView
android:id="@+id/shipdata_adapter_etryptPurpsNm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_medium"
android:gravity="left"
android:text="입항목적명"
android:textColor="#303030"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/textView65"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.8" />
<TextView
android:id="@+id/shipdata_adapter_prtAgNm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_medium"
android:gravity="left"
android:text="항구청명"
android:textColor="#303030"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/imageView7"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/textView60"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.399" />
<TextView
android:id="@+id/shipdata_adapter_vsslKndNm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_medium"
android:gravity="left"
android:text="선박종류명"
android:textColor="#303030"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="@+id/imageView7"
app:layout_constraintEnd_toEndOf="@+id/imageView7"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/textView61"
app:layout_constraintTop_toTopOf="@+id/imageView7"
app:layout_constraintVertical_bias="0.473" />
<TextView
android:id="@+id/shipdata_adapter_clsgn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_medium"
android:text="호출부호"
android:textColor="#303030"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="@+id/imageView7"
app:layout_constraintEnd_toEndOf="@+id/imageView7"
app:layout_constraintHorizontal_bias="0.011"
app:layout_constraintStart_toEndOf="@+id/textView59"
app:layout_constraintTop_toTopOf="@+id/imageView7"
app:layout_constraintVertical_bias="0.259" />
<TextView
android:id="@+id/shipdata_adapter_grtg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_medium"
android:gravity="left"
android:text="총톤수"
android:textColor="#303030"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="@+id/imageView7"
app:layout_constraintEnd_toEndOf="@+id/imageView7"
app:layout_constraintHorizontal_bias="0.007"
app:layout_constraintStart_toEndOf="@+id/textView67"
app:layout_constraintTop_toTopOf="@+id/imageView7"
app:layout_constraintVertical_bias="0.986" />
<TextView
android:id="@+id/shipdata_adapter_etryptDt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:fontFamily="@font/kopubworld_dotum_pro_medium"
android:gravity="left"
android:text="입항일시"
android:textColor="#081442"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/imageView7"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.366"
app:layout_constraintStart_toStartOf="@+id/imageView7"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.1" />
<TextView
android:id="@+id/shipdata_adapter_tkoffDt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_medium"
android:gravity="left"
android:text="출항일시"
android:textColor="#081442"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/imageView7"
app:layout_constraintEnd_toEndOf="@+id/imageView7"
app:layout_constraintHorizontal_bias="0.436"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/imageView7"
app:layout_constraintVertical_bias="0.156" />
<TextView
android:id="@+id/shipdata_adapter_vsslNm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_medium"
android:gravity="left"
android:text="선박명"
android:textColor="#081442"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/imageView7"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.213"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.041" />
<TextView
android:id="@+id/textView50"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:fontFamily="@font/kopubworld_dotum_pro_bold"
android:text="입항일시"
android:textColor="#081442"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/imageView7"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.015"
app:layout_constraintStart_toStartOf="@+id/imageView7"
app:layout_constraintTop_toTopOf="@+id/imageView7"
app:layout_constraintVertical_bias="0.1" />
<TextView
android:id="@+id/textView51"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_bold"
android:text="출항일시"
android:textColor="#081442"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/imageView7"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.063"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.157" />
<TextView
android:id="@+id/shipdata_adapter_vsslNltyNm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_medium"
android:gravity="left"
android:text="선박국가명"
android:textColor="#303030"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/textView63"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.541" />
<TextView
android:id="@+id/shipdata_adapter_ibobprtNm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_medium"
android:gravity="left"
android:text="내외항구분명"
android:textColor="#303030"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="@+id/imageView7"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.005"
app:layout_constraintStart_toEndOf="@+id/textView64"
app:layout_constraintTop_toTopOf="@+id/imageView7"
app:layout_constraintVertical_bias="0.732" />
<TextView
android:id="@+id/shipdata_adapter_laidupFcltyNm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_medium"
android:gravity="left"
android:text="계선시설명"
android:textColor="#303030"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="@+id/imageView7"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/textView69"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.666" />
<TextView
android:id="@+id/shipdata_adapter_dstnPrtNm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_medium"
android:text="목적지항구명"
android:textColor="#303030"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="@+id/imageView7"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.01"
app:layout_constraintStart_toEndOf="@+id/textView68"
app:layout_constraintTop_toTopOf="@+id/imageView7"
app:layout_constraintVertical_bias="0.607" />
<TextView
android:id="@+id/shipdata_adapter_ldadngFrghtClCd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_medium"
android:gravity="left"
android:text="화물명세"
android:textColor="#303030"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="@+id/imageView7"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/textView70"
app:layout_constraintTop_toTopOf="@+id/imageView7"
app:layout_constraintVertical_bias="0.925" />
<TextView
android:id="@+id/shipdata_adapter_satmntEntrpsNm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_medium"
android:gravity="left"
android:text="신고업체명"
android:textColor="#303030"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/textView66"
app:layout_constraintTop_toTopOf="@+id/imageView7"
app:layout_constraintVertical_bias="0.869" />
<TextView
android:id="@+id/textView58"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_bold"
android:text="선박명"
android:textColor="#081442"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/imageView7"
app:layout_constraintEnd_toEndOf="@+id/imageView7"
app:layout_constraintHorizontal_bias="0.058"
app:layout_constraintStart_toStartOf="@+id/imageView7"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.041" />
<TextView
android:id="@+id/textView59"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_bold"
android:text="호출부호 : "
android:textColor="#303030"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/imageView7"
app:layout_constraintEnd_toEndOf="@+id/imageView7"
app:layout_constraintHorizontal_bias="0.066"
app:layout_constraintStart_toStartOf="@+id/imageView7"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.259" />
<TextView
android:id="@+id/textView60"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="280dp"
android:fontFamily="@font/kopubworld_dotum_pro_bold"
android:text="항구청코드 : "
android:textColor="#303030"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/imageView7"
app:layout_constraintEnd_toEndOf="@+id/imageView7"
app:layout_constraintHorizontal_bias="0.066"
app:layout_constraintStart_toStartOf="@+id/imageView7"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.743" />
<TextView
android:id="@+id/textView61"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_bold"
android:text="선박종류명 : "
android:textColor="#303030"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/imageView7"
app:layout_constraintHorizontal_bias="0.066"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.473" />
<TextView
android:id="@+id/textView62"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_bold"
android:text="항구청명 : "
android:textColor="#303030"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/imageView7"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.063"
app:layout_constraintStart_toStartOf="@+id/imageView7"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.327" />
<TextView
android:id="@+id/textView63"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_bold"
android:text="선박국가명 : "
android:textColor="#303030"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.066"
app:layout_constraintStart_toStartOf="@+id/imageView7"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.542" />
<TextView
android:id="@+id/textView64"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_bold"
android:text="내외항구분명 : "
android:textColor="#303030"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.073"
app:layout_constraintStart_toStartOf="@+id/imageView7"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.733" />
<TextView
android:id="@+id/textView65"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_bold"
android:text="입항목적명 : "
android:textColor="#303030"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/imageView7"
app:layout_constraintHorizontal_bias="0.066"
app:layout_constraintStart_toStartOf="@+id/imageView7"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.8" />
<TextView
android:id="@+id/textView66"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_bold"
android:text="신고업체명 : "
android:textColor="#303030"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/imageView7"
app:layout_constraintHorizontal_bias="0.066"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.87" />
<TextView
android:id="@+id/textView67"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_bold"
android:text="총톤수 : "
android:textColor="#303030"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/imageView7"
app:layout_constraintHorizontal_bias="0.063"
app:layout_constraintStart_toStartOf="@+id/imageView7"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.987" />
<TextView
android:id="@+id/textView68"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_bold"
android:text="목적지항구명 : "
android:textColor="#303030"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.069"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.606" />
<TextView
android:id="@+id/textView69"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_bold"
android:text="계선시설명 : "
android:textColor="#303030"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.066"
app:layout_constraintStart_toStartOf="@+id/imageView7"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.667" />
<TextView
android:id="@+id/textView70"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_bold"
android:text="화물명세 : "
android:textColor="#303030"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.063"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.927" />
</androidx.constraintlayout.widget.ConstraintLayout>
2. 결과 출력 UI 만들기 (User Interface)
이 결과값을 보여줄 결과화면도 만들어야 한다. 리사이클러뷰는 위에서 말했듯이 "부분적인 화면 조각" 이기 때문에, 결과값을 출력할 화면과 연결해 주어야한다. 새로운 액티비티를 생성해보자. 찾고싶은 단어 검색은 구현을 안해뒀어서, 이 부분은 작성안해도 상관없다.

UI작성은 첨부파일에 있는 이미지를 보고 가져와 구성하면 된다. 단, 다른점이 하나 있다면 리사이클러뷰를 추가해 주어야 한다는 것이다. UI구성을 다 했다면 RecyclerView를 끌어오면 된다. 이곳에 우리가 만든 리사이클러뷰 XML파일이 출력될것이다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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"
android:fitsSystemWindows="true"
android:background="@drawable/ship_data_result2"
tools:context=".MainActivity_Shipdata_Result">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar_shipdata_result"
android:layout_width="0dp"
android:layout_height="50dp"
android:background="#FF578DFF"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent">
<ImageButton
android:id="@+id/btn_shipdata_replay_go"
android:layout_width="347dp"
android:layout_height="60dp"
android:background="#00ffffff"
android:scaleType="fitXY"
app:srcCompat="@drawable/research_data_button"/>
<ImageButton
android:id="@+id/btn_shipdata_go_main"
android:layout_width="65dp"
android:layout_height="60dp"
android:background="#00ffffff"
android:scaleType="fitXY"
app:srcCompat="@drawable/go_pm_main_shipresult" />
<TextView
android:id="@+id/textView121"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_weight="1"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/ship_recyclerview"
android:layout_width="413dp"
android:layout_height="471dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="@+id/linearLayout2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/toolbar_shipdata_result"
app:layout_constraintVertical_bias="0.77" />
<ImageView
android:id="@+id/imageView2"
android:layout_width="399dp"
android:layout_height="38dp"
android:background="#00ffffff"
android:scaleType="fitXY"
app:layout_constraintBottom_toTopOf="@+id/ship_recyclerview"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/toolbar_shipdata_result"
app:layout_constraintVertical_bias="0.68"
app:srcCompat="@drawable/board_message_search" />
<TextView
android:id="@+id/textView116"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/kopubworld_dotum_pro_bold"
android:text="찾고 싶으신 특정 결과가 있으신가요?"
android:textColor="@color/white"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="@+id/imageView2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.098"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/toolbar_shipdata_result"
app:layout_constraintVertical_bias="0.553" />
<EditText
android:id="@+id/etext_search_data_in_shipdata"
android:layout_width="311dp"
android:layout_height="39dp"
android:background="#00ffffff"
android:ems="10"
android:fontFamily="@font/kopubworld_dotum_pro_medium"
android:hint="단어를 입력하세요"
android:inputType="textPersonName"
android:textSize="17sp"
app:layout_constraintBottom_toBottomOf="@+id/imageView2"
app:layout_constraintEnd_toEndOf="@+id/imageView2"
app:layout_constraintHorizontal_bias="0.647"
app:layout_constraintStart_toStartOf="@+id/imageView2"
app:layout_constraintTop_toTopOf="@+id/imageView2"
app:layout_constraintVertical_bias="1.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
3. 리사이클러뷰 어댑터(Adapter)만들기
우리가 가져와야 하는 item의 목록은 총 3개다. 각각의 item에 포함되어 있는 값들을 가져와 출력할 때 마다 새로운 화면이 필요하다. 그래서 그때마다 우리가 만든 recycler xml 파일을 가져와 데이터를 적용시켜주어야 한다.
이 역할을 하는것이 어댑터다. 일단 어댑터 소스코드를 작성하기에 앞서, 데이터를 담을 객체가 필요하다. 결과 액티비티에서 xml parser를 사용할건데, parser를 통해 얻은 값들을 저장해 둘 공간이 필요하기 때문이다.
그러니 자바 소스코드 파일을 하나 만들어주자. 파일명은 동일하게 하지 않아도 된다.

그리고 아래와 같이 소스코드를 작성한다.
package com.example.a2022realproject_pmplusapp;
//선박 입출항 현황 아이템들 정렬
public class shipdata_Item {
String prtAgCd; //항구청코드
String prtAgNm; //항구청명
String clsgn; //호출부호
String vsslNm; //선박명
String vsslNltyNm; //선박 국가명
String vsslKndNm; // 선박종류명
String etryptPurpsNm; //입항목적명
String dstnPrtNm; //목적지항구명
String etryptDt; //입항일시
String tkoffDT; //출항일시
String ibobprtNm; //내외항구분명
String laidupFcltyNm; //계선시설명
String ldadngFrghtClCd; //화물명세
String grtg; // 총톤수
String satmntEntrpsNm; //신고업체명
//xml 데이터는 오름차순으로 파싱되어옴
public void clear(){
prtAgCd = ""; //항구청코드 o
prtAgNm = ""; //항구청명 o
clsgn = ""; //호출부호 o
vsslNm = ""; //선박명 o
vsslNltyNm = ""; //선박 국가명 o
vsslKndNm = ""; // 선박종류명 o
etryptPurpsNm = ""; //입항목적명 o
dstnPrtNm = ""; //목적지항구명 o
etryptDt = ""; //입항일시 o
tkoffDT = ""; //출항일시 o
ibobprtNm = ""; //내외항구분명 o
laidupFcltyNm = ""; //계선시설명 o
ldadngFrghtClCd = ""; //화물명세 o
grtg = ""; // 총톤수 o
satmntEntrpsNm = ""; //신고업체명
}
boolean checkRecvAllData(){
return prtAgCd.length() > 0
&& prtAgNm.length() > 0
&& clsgn.length() > 0
&& vsslNm.length() > 0
&& vsslNltyNm.length() > 0
&& vsslKndNm.length() > 0
&& etryptPurpsNm.length() > 0
&& dstnPrtNm.length() > 0
&& etryptDt.length() > 0
&& tkoffDT.length() > 0
&& ibobprtNm.length() > 0
&& laidupFcltyNm.length() > 0
&& ldadngFrghtClCd.length() > 0
&& grtg.length() > 0
&& satmntEntrpsNm.length() > 0;
}
}
그럼 이제 어댑터 소스코드를 작성해보자. 자바 소스코드 파일을 하나 더 만들어주자. 파일명은 마음대로 작성하면 된다.

그리고 아래와 같이 소스코드를 작성해주자
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class ShipAdapter extends RecyclerView.Adapter <ShipAdapter.ViewHolder>{
ArrayList<shipdata_Item> items = new ArrayList<shipdata_Item>(); //items 배열리스트 생성
//타입이 shipData_Item
public void setItems(ArrayList<shipdata_Item> items){ //위에서 만든 배열리스트를 사용할것이라고 명시
this.items = items;
}
public void clearItems(){ //초기화
items.clear();
}
public void addItem(shipdata_Item item) { //shipdata_item에 있던 결과값을 추가
items.add(item);
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View itemView = inflater.inflate(R.layout.shipdata_adapter, parent, false);
return new ViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
shipdata_Item item =items.get(position);
holder.setItem(item);
}
@Override
public int getItemCount() {
return items.size();
}
//화면에 표시하기 위한 메소드 정의( setItem ), id 값들 전부 가져오기기
static class ViewHolder extends RecyclerView.ViewHolder {
TextView a_prtAgCd; //항구청코드
TextView a_prtAgNm; //항구청명
TextView a_clsgn; //호출부호
TextView a_vsslNm; //선박명
TextView a_vsslNltyNm; //선박 국가명
TextView a_vsslKndNm; // 선박종류명
TextView a_etryptPurpsNm; //입항목적명
TextView a_dstnPrtNm; //목적지항구명
TextView a_etryptDt; //입항일시
TextView a_tkoffDT; //관제작업일시
TextView a_ibobprtNm; //시설코드
TextView a_laidupFcltyNm;
TextView a_ldadngFrghtClCd; //관제작업일시
TextView a_grtg; //시설코드
TextView a_satmntEntrpsNm;
public ViewHolder(@NonNull View itemView) {
super(itemView);
a_prtAgCd = itemView.findViewById(R.id.shipdata_adapter_prtAgCd);
a_prtAgNm = itemView.findViewById(R.id.shipdata_adapter_prtAgNm);
a_clsgn = itemView.findViewById(R.id.shipdata_adapter_clsgn);
a_vsslNm = itemView.findViewById(R.id.shipdata_adapter_vsslNm);
a_vsslNltyNm = itemView.findViewById(R.id.shipdata_adapter_vsslNltyNm);
a_vsslKndNm = itemView.findViewById(R.id.shipdata_adapter_vsslKndNm);
a_etryptPurpsNm = itemView.findViewById(R.id.shipdata_adapter_etryptPurpsNm);
a_dstnPrtNm = itemView.findViewById(R.id.shipdata_adapter_dstnPrtNm);
a_etryptDt = itemView.findViewById(R.id.shipdata_adapter_etryptDt);
a_tkoffDT = itemView.findViewById(R.id.shipdata_adapter_tkoffDt);
a_ibobprtNm = itemView.findViewById(R.id.shipdata_adapter_ibobprtNm);
a_laidupFcltyNm = itemView.findViewById(R.id.shipdata_adapter_laidupFcltyNm);
a_ldadngFrghtClCd = itemView.findViewById(R.id.shipdata_adapter_ldadngFrghtClCd);
a_grtg = itemView.findViewById(R.id.shipdata_adapter_grtg);
a_satmntEntrpsNm = itemView.findViewById(R.id.shipdata_adapter_satmntEntrpsNm);
}
public void setItem(shipdata_Item item){
a_prtAgCd.setText(item.prtAgCd);
a_prtAgNm.setText(item.prtAgNm);
a_clsgn.setText(item.clsgn);
a_vsslNm.setText(item.vsslNm);
a_vsslNltyNm.setText(item.vsslNltyNm);
a_vsslKndNm.setText(item.vsslKndNm);
a_etryptPurpsNm.setText(item.etryptPurpsNm);
a_dstnPrtNm.setText(item.dstnPrtNm);
a_etryptDt.setText(item.etryptDt);
a_tkoffDT.setText(item.tkoffDT);
a_ibobprtNm.setText(item.ibobprtNm);
a_laidupFcltyNm.setText(item.laidupFcltyNm);
a_ldadngFrghtClCd.setText(item.ldadngFrghtClCd);
a_grtg.setText(item.grtg);
a_satmntEntrpsNm.setText(item.satmntEntrpsNm);
}
}
}
우리가 위에서 만들었던 객체에 있던 정보를 ArrayList에 담고, ArrayList에 있는 값들을 가져와 TextView에 적용시켜주는 코드다. 새로운 item객체가 생성된다면, 리사이클러뷰에서 어댑터를 호출하고, 그 객체에 있는 값들을 가져와 xml 화면에 연결시켜준다는 것이다.
4. 결과 화면 소스코드 작성하기 - xmlPullParserFactory 사용하기
https://developer.android.com/reference/org/xmlpull/v1/XmlPullParserFactory#newPullParser()
https://developer.android.com/reference/org/xmlpull/v1/XmlPullParser#END_DOCUMENT
XmlPullParser | Android Developers
developer.android.com
XmlPullParserFactory | Android Developers
developer.android.com
▲ 공식 문서
위에서 결과 화면 제작을 위해 빈 액티비티를 하나 생성하면서, XML 파일 및 소스코드 파일이 동시에 만들어졌을 것이다. 그 액티비티에 소스코드를 작성할 것이다.
위에서 언급했던 것 처럼 <item>~</item>이 한 덩어리다. 즉, <item>이라는 태그를 만난다면 데이터 수집을 시작하고 </item>을 만나면 수집을 종료한다는 것이다. 이 행동을 문서의 끝을 만날때까지 반복해야, 3가지 경우의 결과를 모두 가져올 수 있다.
공공데이터 포털에서 제공하는 데이터는 xml 형식이기에, 가져오려면 xml parser를 사용해야한다.
일단 필자가 작성했던 소스코드 일부를 먼저 살펴보자. 핵심 부분을 일부 가져온것이기에 이해하는 용도로 읽어보면 된다.
먼저, 사용자가 입력한 값을 intent로 가져온다음, 변수에 저장을 해주었다. 그리고 해당 xml파일에 접근할 수 있도록 문자열을 연결해주었다. 이렇게 해서 사용자가 원하는 데이터를 조회할 수 있다!
<TIP!>Intent 사용할 때 데이터를 4개 넘겼었다면, 받을때도 반드시 4개 전부 다 받아두어야 한다. 적게 받아도 에러난다.
Intent intent = getIntent();
//인텐트 문제인 듯? 이 부분을 수정해보기
rs_sc = intent.getStringExtra("prt"); //prtAgCd, 020
rs_day1 = intent.getStringExtra("sde"); //sde
rs_day2 = intent.getStringExtra("ede"); //ede
rs_call = intent.getStringExtra("clsgnll"); //clsgn
//xml 문서 연결
Request.Method.GET,
"http://apis.data.go.kr/1192000/VsslEtrynd2/Info?serviceKey=NYQp85bV4GjxauduBdSwaoZb3uT9jcgbECXr1WNuzKbPSx5%2Fdv7m%2B5gV6xRZk3yYt5M4dzOuspvMzSwrPgtd7g%3D%3D" +
"&sde=" + rs_day1 + "&ede=" + rs_day2 + "&prtAgCd=" + rs_sc + "&clsgn=" + rs_call + "&pageNo=1&numOfRows=50",
xml parser를 위한 xmlpullparser 객체를 하나 생성해주었다. 그리고 문서 끝까지 읽어내야 하므로, 더 이상 파서를 이용할 수 없을때까지 코드를 돌리면 된다. 그래서 그 역할을 하는 end_document 소스코드를 작성해주었다.
end_document 는 xml 문서의 논리적 끝을 판단하는 기능을 한다.
만약 문서 끝이 아니라면 무언의 데이터가 있다는 뜻이기에 시작태그를 찾아주어야 한다.
시작태그를 찾으면 그 태그에 있는 text들을 읽어들인다. 단, 우리가 찾는 값이 있는 태그여야한다.
우리가 찾는 값은 <item> ~ </item>에 들어있다. 그렇기에 <item>태그를 만났을 때 파싱을 시작하면 되는것이다!
우리가 사용하는 공공데이터 포털 API에서 제공하는 문서를 살펴보면 어떤 태그가 어떤 데이터를 제공하는지를 알 수 있다. 그러니 만약, 우리가 원하는 값을 가지고 있는 태그라면 그 태그의 text값을 가져와 위에서 만들었던 shipdata_item에 저장해주면 된다.
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
while (eventType != XmlPullParser.END_DOCUMENT) { //문서 끝까지 읽어들이자
...
curr_tag = xpp.getName();
if (xpp.getName().equals("item")) { //item 태그를 기준으로 돌거임 <item> ~ </item> 이 1회 도는거임
ditem = new shipdata_Item(); //item이라면 새로운 결과값에 도달한것이므로 새 객체 생성
count++; //ITEM 태그를 만난 횟수 세어주기
}
...
else if (eventType == XmlPullParser.TEXT) {
//태그 종류별로 기록
switch (curr_tag) {
case "prtAgCd":
ditem.prtAgCd = xpp.getText();
Log.d("please",ditem.prtAgCd); //로그를 통해 데이터가 잘 나오는지 확인
break;
이렇게 하면 우리는 원하던 모든 값들을 가져올 수 있다. 전체 소스코드는 다음과 같다.
package com.example.a2022realproject_pmplusapp;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.ImageButton;
import android.widget.Toast;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
public class MainActivity_Shipdata_Result extends AppCompatActivity {
ImageButton replay_shipdata;
ImageButton no_replay_main;
Toolbar toolbar;
Button test;
String rs_day1, rs_day2, rs_call, rs_sc;
int count = 0; //몇개의 결과가 조회되었는지 셀 변수
RecyclerView review;
static RequestQueue requestQueue;
String TAG = "data list";
ShipAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_shipdata_result);
toolbar = (Toolbar)findViewById(R.id.toolbar_shipdata_result);
setSupportActionBar(toolbar); //툴바를 불러오고
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.baseline_chevron_left_white_24dp);
getSupportActionBar().setTitle("선박 입출항 현황 조회결과");
Intent intent = getIntent();
//인텐트 문제인 듯? 이 부분을 수정해보기
rs_sc = intent.getStringExtra("prt"); //prtAgCd, 020
rs_day1 = intent.getStringExtra("sde"); //sde
rs_day2 = intent.getStringExtra("ede"); //ede
rs_call = intent.getStringExtra("clsgnll"); //clsgn
//문제가 지금 null값 나오고 있음
Log.d("dataintent", rs_sc);
Log.d("dataintent", rs_day1);
Log.d("dataintent", rs_day2);
Log.d("dataintent", rs_call); //사용자로부터 입력받은 값이 잘 나오는지 확인
replay_shipdata = (ImageButton) findViewById(R.id.btn_shipdata_replay_go);
no_replay_main = (ImageButton) findViewById(R.id.btn_shipdata_go_main);
replay_shipdata.setOnClickListener(v -> {
Intent re_start = new Intent(getApplicationContext(), MainActivity_ShipData.class);
startActivity(re_start);
});
no_replay_main.setOnClickListener(v -> {
Intent no_start = new Intent(getApplicationContext(), MainActivity_PM_Main.class);
startActivity(no_start);
});
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
adapter = new ShipAdapter();
review = findViewById(R.id.ship_recyclerview);
review.setLayoutManager(layoutManager);
review.setAdapter(adapter); //레이아웃 어댑터 연결
requestQueue = Volley.newRequestQueue(getApplicationContext()); //volley로 데이터를 가져올거
StringRequest request = new StringRequest(
Request.Method.GET,
"http://apis.data.go.kr/1192000/VsslEtrynd2/Info?serviceKey=NYQp85bV4GjxauduBdSwaoZb3uT9jcgbECXr1WNuzKbPSx5%2Fdv7m%2B5gV6xRZk3yYt5M4dzOuspvMzSwrPgtd7g%3D%3D" +
"&sde=" + rs_day1 + "&ede=" + rs_day2 + "&prtAgCd=" + rs_sc + "&clsgn=" + rs_call + "&pageNo=1&numOfRows=50",
new Response.Listener<String>() {
@SuppressLint("NotifyDataSetChanged")
@Override
public void onResponse(String response) {
Log.d(TAG, "onResponse : " + response);
String curr_tag = ""; //<tag>의 이름을 저장할 변수
//ArrayList<Station> arrStation = new ArrayList<>();
shipdata_Item ditem = new shipdata_Item();
adapter.clearItems(); //아이템 정리
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput(new StringReader(response));
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_DOCUMENT) {
//System.out.println("Start document");
} else if (eventType == XmlPullParser.START_TAG) {
//시작하는 tag 기억
curr_tag = xpp.getName();
if (xpp.getName().equals("item")) { //item 태그를 기준으로 돌거임 <item> ~ </item> 이 1회 도는거임
ditem = new shipdata_Item();
count++; //ITEM 태그를 만난 횟수 세어주기
}
} else if (eventType == XmlPullParser.END_TAG) {
//item 태그 종료시 추가
if (xpp.getName().equals("item")) {
if (ditem.checkRecvAllData()) {
adapter.addItem(ditem);
}
}
curr_tag = "";
} else if (eventType == XmlPullParser.TEXT) {
//태그 종류별로 기록
switch (curr_tag) {
case "prtAgCd":
ditem.prtAgCd = xpp.getText();
Log.d("please",ditem.prtAgCd); //로그를 통해 데이터가 잘 나오는지 확인
break;
case "prtAgNm":
ditem.prtAgNm = xpp.getText();
Log.d("please",ditem.prtAgNm);
break;
case "clsgn":
ditem.clsgn = xpp.getText();
Log.d("please",ditem.clsgn);
break;
case "vsslNm":
ditem.vsslNm = xpp.getText();
Log.d("please",ditem.vsslNm);
break;
case "vsslNltyNm":
ditem.vsslNltyNm = xpp.getText();
Log.d("please",ditem.vsslNltyNm);
break;
case "vsslKndNm":
ditem.vsslKndNm = xpp.getText();
Log.d("please",ditem.vsslKndNm);
break;
case "etryptPurpsNm":
ditem. etryptPurpsNm = xpp.getText();
Log.d("please",ditem.etryptPurpsNm);
break;
case "dstnPrtNm":
ditem.dstnPrtNm= xpp.getText();
Log.d("please",ditem.dstnPrtNm);
break;
/*item태그안의 자식태그들*/
/*item 태그안의 자식 태그들 중 detail 부분의 태그들*/
case "etryptDt":
ditem.etryptDt = xpp.getText();
Log.d("please",ditem.etryptDt);
break;
case "tkoffDt":
ditem.tkoffDT = xpp.getText();
Log.d("please",ditem.tkoffDT);
break;
case "ibobprtNm":
ditem.ibobprtNm = xpp.getText();
Log.d("please",ditem.ibobprtNm);
break;
case "laidupFcltyNm":
ditem.laidupFcltyNm = xpp.getText();
Log.d("please",ditem.laidupFcltyNm);
break;
case "ldadngFrghtClCd":
ditem. ldadngFrghtClCd = xpp.getText();
Log.d("please",ditem.ldadngFrghtClCd);
break;
case "grtg":
ditem.grtg= xpp.getText();
Log.d("please",ditem.grtg);
break;
case "satmntEntrpsNm":
ditem.satmntEntrpsNm = xpp.getText();
Log.d("please",ditem.satmntEntrpsNm);
break;
}
}
eventType = xpp.next();
} //while문 종료
} catch (Exception e) {
e.printStackTrace();
}
if(count == 0){
Intent fail = new Intent(getApplicationContext(),MainActivity_Shipdata_Result_Fail.class);
startActivity(fail);
}else{
adapter.notifyDataSetChanged();
}
Toast.makeText(getApplicationContext(), count+"개의 결과가 조회되었어요.", Toast.LENGTH_LONG).show();
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "onErrorResponse : " + error.toString());
}
}
) {
@Nullable
@Override
protected Map<String, String> getParams() throws AuthFailureError {
//요청 객체가 하나 만들어짐
Map<String, String> params = new HashMap<String, String>();
//요청 큐에 넣어주면 된다
return super.getParams();
}
};
request.setShouldCache(false);
requestQueue.add(request);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) { //뒤로가기 했을 때
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}
return super. onOptionsItemSelected(item);
}
}
이렇게 하면 사용자가 입력한 값에 따른 조회결과를 얻을 수 있다.
'프론트앤드' 카테고리의 다른 글
| [안드로이드 스튜디오] Hilt에 대해 알아보자(1) - 종속 항목 삽입이 뭔데? (2) | 2024.07.18 |
|---|---|
| [안드로이드 스튜디오] ProgressBar가..죽었네? 로딩창 직접 만들자 (0) | 2024.07.01 |
| [안드로이드 스튜디오] include 태 그 조 아. (1) | 2024.03.03 |
| 선박 입출항 조회 기능 영상 (0) | 2023.01.17 |
| 안드로이드 스튜디오 - 리사이클러뷰를 이용해서 사용자가 입력한 값 대로 공공데이터 포털 API에서 결과값 가져오기 - (1) (0) | 2023.01.17 |