일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 런처만들기
- json파일 읽기
- 글자출력
- 앱리스트보기
- 사진 찍고 글자 출력
- 앱추가
- 기상청 날씨 API
- 단기예보 조회서비스
- 안드로이드 내장db
- ssh에러
- 홈앱
- ssh원격
- 홈앱만들기
- 사진에서 텍스트
- Android ocr
- 홈 런처 만들기
- 공공데이터포털 날씨API
- 동네예보 조회서비스 폐지
- sqlit
- 글씨출력
- 사진에서글자
- 홈만들기
- json파일 입출력
- Android
- jsonobject to jsonarray
- JSONArray to JSONObject
- java
- json파일 작성
- AndroidStudio
- json파일 작성하기
- Today
- Total
주니어개발자_ฅʕ•̫͡•ʔฅ
기상청 날씨 api_엑셀파일에서 지역 격자값 가져와 날씨 가져오기 (feat.공공데이터포털) 본문
전에 날씨 api를 사용하여
날씨 정보 가져오기를 해봤다.
이번엔 여기에 좀 더 난이도를 높여서
현재 위치를 읽어와
해당 지역에 맞는 날씨를
조회하고자 한다.
먼저
공공데이터포털에서 날씨 api를 신청하지 않았다면
위에 첨부한 블로그를 보고 따라한 후에 시작하길 바란다.
그리고 공공데이터 포털에서
밑에 빨간 동그라미 친 파일을 다운 받아 압축을 풀어준다.
본인은 해당 엑셀 파일에서 격자값만 필요했기에
필요 없는 부분은 지워서 새로 저장했다.
상단에 A,B,C 등 알파벳으로 열이 나뉘어져 있는데
필요하지 않은 부분은
알파벳 부분을 눌러 열(세로) 단위로 지웠다.
하지만 굳이 지우지 않아도 괜찮다...
엑셀 파일이 준비가 되었다면
앱에 넣어줍니다.
먼저 프로젝트에 assets폴더를 만들어준다.
그럼 app\src\main 위치에 assets라는 폴더가 생성 되는데
그 폴더 안에 위에서 다운 받은 엑셀 파일을 넣어주면 된다.
이제 엑셀 파일을 읽어 올 준비를 해보자.
먼저 엑셀파일을 읽을 수 있게 해주는
jxl-2.6.12.jar 라이브러리를 다운 받아 준다.
다운 받는 곳은 찾아보면 있겠지만
찾아서 넣는게 귀찮아서 그냥 파일 올렸습니다.
위의 파일을 다운받은 후
적용할 프로젝트 파일에 추가해줍니다.
파일 추가 순서는
다운 받은 jxl 파일을 프로젝트 app\libs\ 위치에 포함시킨 후
프로젝트로 돌아와 file -> Project Stucture 을 눌러
Project Stucture 창이 뜨면 Dependencies 항목을 선택한다.
+ 를 누른 후 jar Dependency 항목을 선택한다.
파일을 추가할 수 있게
밑에 이미지와 같은 창이 뜨면
libs\jxl-2.6.12.jar 입력 후
ok 버튼을 누르면
프로젝트에 jxl 라이브러리 적용이 끝난다.
여기까지 날씨를 가져오기 위한 준비가 완료되었다.
본격적으로 현재 위치의 날씨를 가져와 보자.
1. 현재 위치 가져오기
현재 위치를 가져오는 방법은 밑의 블로그를 참고했다.
https://webnautes.tistory.com/1315
위의 블로그를 참고하여 현재 위치를 가져왔다면
현재 위치 내용은 밑에와 같이 구했을 것이다.
address = getCurrentAddress(latitude, longitude);
// address 변수는 현재 위치 정보(대한민국 서울특별시 xx구 xx동 xx-x) 넣을 변수, String형
여기서 나는 xx구 부분 추출을 위해
문자열 배열에 현재 위치를
띄어쓰기 기준으로 나누어 넣었다.
String[] local = address.split(" ");
// local[0] = 대한민국
// local[1] = 서울특별시
// local[2] = xx구
.
.
.
String localName = local[2]; //xx구 이름
2. 엑셀파일에서 현재 위치의 격자값 읽어오기
엑셀파일 읽어오는 것은 밑의 블로그를 참고했다.
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=gjdeveloper&logNo=220558182815
// 엑셀 파일에서 xx구 이름을 가지고 격자값 구하는 메소드 readExcel()
readExcel(localName);
readExcel 소스코드
public void readExcel(String localName) {
try {
InputStream is = getBaseContext().getResources().getAssets().open("local_name.xls");
Workbook wb = Workbook.getWorkbook(is);
if (wb != null) {
Sheet sheet = wb.getSheet(0); // 시트 불러오기
if (sheet != null) {
int colTotal = sheet.getColumns(); // 전체 컬럼
int rowIndexStart = 1; // row 인덱스 시작
int rowTotal = sheet.getColumn(colTotal - 1).length;
for (int row = rowIndexStart; row < rowTotal; row++) {
String contents = sheet.getCell(0, row).getContents();
if (contents.contains(localName)) {
x = sheet.getCell(1, row).getContents();
y = sheet.getCell(2, row).getContents();
row = rowTotal;
}
}
}
}
} catch (IOException e) {
Log.i("READ_EXCEL1", e.getMessage());
e.printStackTrace();
} catch (BiffException e) {
Log.i("READ_EXCEL1", e.getMessage());
e.printStackTrace();
}
// x, y = String형 전역변수
Log.i("격자값", "x = " + x + " y = " + y);
}
격자 값을 구했다면
현재 시간 및 날짜를 구해보자
이 부분은 밑의 블로그를 참고했다.
https://kiwinam.com/posts/6/android-simple-date-format/
현재 시간은 시, 분, 초에서 시만 구한다.
만약 시간이 02:22:35 이렇게 된다면
0200으로 바꿔준다.
본인은
time = time.substring(0, time.IndexOf(":"));
// time = String형 시간을 받아오는 변수
위와 같은 방법으로 바꿨지만
다른 편한 방법이 있다면 그렇게 해도 상관없다.
그리고 날짜는 20210101 같은 형식으로 있어야해서
date = date.replaceAll("-", "");
//date = String형 날짜 받아오는 변수
위와 같은 방법으로 "-" 부분을 없애준다.
마지막으로 밑에 했던 부분을 응용하여
현재 위치의 날씨를 받아오는
전체 소스 코드를 정리해 보면
(현재위치를 받아오는 GpsTracker 클래스와 퍼미션부분은 따로 포함하지 않았습니다.)
MainActivity
import부분과 날짜 및 시간 구하는 부분 간단한 부분으로 생략했다.
public class MainActivity extends AppCompatActivity {
private GpsTracker gpsTracker;
private String x = "", y = "", address = "";
private date = "", time = "";
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gpsTracker = new GpsTracker(this);
double latitude = gpsTracker.getLatitude();
double longitude = gpsTracker.getLongitude();
address = getCurrentAddress(latitude, longitude);
String[] local = address.split(" ");
String localName = local[2];
readExcel(localName); //행정시 이름으로 격자값 구하기
String weather = "";
WeatherData wd = new WeatherData();
try {
// date와 time에 값을 넣어야함
// ex) date = "20210722", time = "0500"
weather = wd.lookUpWeather(date, time, x, y);
} catch (IOException e) {
Log.i("THREE_ERROR1", e.getMessage());
} catch (JSONException e) {
Log.i("THREE_ERROR2", e.getMessage());
}
Log.i("현재날씨",weather);
}
public void readExcel(String localName) {
try {
InputStream is = getBaseContext().getResources().getAssets().open("local_name.xls");
Workbook wb = Workbook.getWorkbook(is);
if (wb != null) {
Sheet sheet = wb.getSheet(0); // 시트 불러오기
if (sheet != null) {
int colTotal = sheet.getColumns(); // 전체 컬럼
int rowIndexStart = 1; // row 인덱스 시작
int rowTotal = sheet.getColumn(colTotal - 1).length;
for (int row = rowIndexStart; row < rowTotal; row++) {
String contents = sheet.getCell(0, row).getContents();
if (contents.contains(localName)) {
x = sheet.getCell(1, row).getContents();
y = sheet.getCell(2, row).getContents();
row = rowTotal;
}
}
}
}
} catch (IOException e) {
Log.i("READ_EXCEL1", e.getMessage());
e.printStackTrace();
} catch (BiffException e) {
Log.i("READ_EXCEL1", e.getMessage());
e.printStackTrace();
}
Log.i("격자값", "x = " + x + " y = " + y);
}
}
WeatherData
날씨 구하는 클래스
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.WorkSource;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
public class WeatherData{
private String weather = "", tmperature = "";
public String lookUpWeather(String baseDate, String time, String nx, String ny) throws IOException, JSONException {
// String baseDate = date;//"20210531";//date //조회하고싶은 날짜
String baseTime = timeChange(time); //"0500";//timeChange(time); //조회하고싶은 시간
String type = "json"; //조회하고싶은 시간
String apiUrl = "http://apis.data.go.kr/1360000/VilageFcstInfoService/getVilageFcst";
// 홈페이지에서 받은 키
String serviceKey = "홈페이지에서 받은 키를 이곳에 넣어주세요";
StringBuilder urlBuilder = new StringBuilder(apiUrl);
urlBuilder.append("?" + URLEncoder.encode("ServiceKey", "UTF-8") + "=" + serviceKey);
urlBuilder.append("&" + URLEncoder.encode("nx", "UTF-8") + "=" + URLEncoder.encode(nx, "UTF-8")); //경도
urlBuilder.append("&" + URLEncoder.encode("ny", "UTF-8") + "=" + URLEncoder.encode(ny, "UTF-8")); //위도
urlBuilder.append("&" + URLEncoder.encode("base_date", "UTF-8") + "=" + URLEncoder.encode(baseDate, "UTF-8")); /* 조회하고싶은 날짜*/
urlBuilder.append("&" + URLEncoder.encode("base_time", "UTF-8") + "=" + URLEncoder.encode(baseTime, "UTF-8")); /* 조회하고싶은 시간 AM 02시부터 3시간 단위 */
urlBuilder.append("&" + URLEncoder.encode("dataType", "UTF-8") + "=" + URLEncoder.encode(type, "UTF-8")); /* 타입 */
/*
* GET방식으로 전송해서 파라미터 받아오기
*/
URL url = new URL(urlBuilder.toString());
//어떻게 넘어가는지 확인하고 싶으면 아래 출력분 주석 해제
//System.out.println(url);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-type", "application/json");
BufferedReader rd;
if (conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300) {
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
} else {
rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
}
StringBuilder sb = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
conn.disconnect();
String result = sb.toString();
// response 키를 가지고 데이터를 파싱
JSONObject jsonObj_1 = new JSONObject(result);
String response = jsonObj_1.getString("response");
// response 로 부터 body 찾기
JSONObject jsonObj_2 = new JSONObject(response);
String body = jsonObj_2.getString("body");
// body 로 부터 items 찾기
JSONObject jsonObj_3 = new JSONObject(body);
String items = jsonObj_3.getString("items");
Log.i("ITEMS", items);
// items로 부터 itemlist 를 받기
JSONObject jsonObj_4 = new JSONObject(items);
JSONArray jsonArray = jsonObj_4.getJSONArray("item");
for (int i = 0; i < jsonArray.length(); i++) {
jsonObj_4 = jsonArray.getJSONObject(i);
String fcstValue = jsonObj_4.getString("fcstValue");
String category = jsonObj_4.getString("category");
if (category.equals("SKY")) {
weather = "현재 날씨는 ";
if (fcstValue.equals("1")) {
weather += "맑은 상태로";
} else if (fcstValue.equals("2")) {
weather += "비가 오는 상태로 ";
} else if (fcstValue.equals("3")) {
weather += "구름이 많은 상태로 ";
} else if (fcstValue.equals("4")) {
weather += "흐린 상태로 ";
}
}
if (category.equals("T3H") || category.equals("T1H")) {
tmperature = "기온은 " + fcstValue + "℃";
}
Log.i("날씨", fcstValue);
Log.i("카테고리", category);
Log.i("지금 날씨는", weather + tmperature);
}
return weather + tmperature;
}
public String timeChange(String time)
{
// 현재 시간에 따라 데이터 시간 설정(3시간 마다 업데이트) //
/**
시간은 3시간 단위로 조회해야 한다. 안그러면 정보가 없다고 뜬다.
0200, 0500, 0800 ~ 2300까지
그래서 시간을 입력했을때 switch문으로 조회 가능한 시간대로 변경해주었다.
**/
switch(time) {
case "0200":
case "0300":
case "0400":
time = "0200";
break;
case "0500":
case "0600":
case "0700":
time = "0500";
break;
case "0800":
case "0900":
case "1000":
time = "0800";
break;
case "1100":
case "1200":
case "1300":
time = "1100";
break;
case "1400":
case "1500":
case "1600":
time = "1400";
break;
case "1700":
case "1800":
case "1900":
time = "1700";
break;
case "2000":
case "2100":
case "2200":
time = "2000";
break;
default:
time = "2300";
}
return time;
}
}
'AndroidStudio' 카테고리의 다른 글
Android 앱 런처 만들기2 (홈 만들기, 앱 추가하기) (0) | 2021.08.17 |
---|---|
Android app을 앱 런처로 만들기 (홈 만들기) (0) | 2021.07.23 |
기상청 날씨 api (feat.공공데이터포털) (5) | 2021.05.31 |
Android Youtube api jar 추가 (0) | 2021.05.28 |
Android Youtube api 검색 및 재생, 영상 끝났을때 자동종료 (안드로이드 유튜브 api, JAVA) (0) | 2021.05.28 |