반응형
반응형

 

개발을 진행하다 보면 사진 속성값을 수정해야 하는 경우가 있다

사진에 GPS 데이터 값을 넣는다던가 회전값을 알아온다던가...

실제 개발을 하다가 사용해 본 내용을 정리해보고자 한다.

 

물론 ExifInterface를 이용해서 다른 정보들을 확인하는 글들은 많이 확인할 수 있을 것이다.

아래 구글 공식문서를 확인해도 가능하니 확인해 본다면 좋을 것이다.


# 개요 : 전달받은 사진에 현재 GPS 데이터를 삽입해라!! 

# 사용 라이브러리 : https://developer.android.com/jetpack/androidx/releases/exifinterface?hl=ko

 

Exifinterface  |  Android 개발자  |  Android Developers

컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. Exifinterface 이미지 파일 EXIF(데이터) 태그를 읽고 씁니다. 최근 업데이트 안정화 버전 출시 후보 버전 베타 버

developer.android.com

androidx.exifinterface:exifinterface:1.3.6

# GPS 데이터 삽입 코드

// 사진 속성 함수 선언
ExifInterface exif;

// GPS 데이터 중 위경도 좌표가 있는 GPRMC 데이터
String Avalid_GPS_DATA = "$GPRMC,232023.00,A,3724.769351,N,12705.867068,E,019.2,270.0,290419,,,A*5F";

// LAT, LON 값 추출
double latitude = Objects.requireNonNull(DRAW_LOCATION(Avalid_GPS_DATA)).latitude;
double longitude = Objects.requireNonNull(DRAW_LOCATION(Avalid_GPS_DATA)).longitude;

try {
    exif = new ExifInterface(사진파일경로);    // Photo.getpath()
    
    // 도분초 좌표 변환 : LAT
    int num1Lat = (int) Math.floor(latitude);
    int num2Lat = (int) Math.floor((latitude - num1Lat) * 60);
    double num3Lat = (latitude - ((double) num1Lat + ((double) num2Lat / 60))) * 3600000;

	// 도분초 좌표 변환 : LON
    int num1Lon = (int) Math.floor(longitude);
    int num2Lon = (int) Math.floor((longitude - num1Lon) * 60);
    double num3Lon = (longitude - ((double) num1Lon + ((double) num2Lon / 60))) * 3600000;

	// GPS 좌표 삽입
    exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, num1Lat + "/1," + num2Lat + "/1," + num3Lat + "/1000");
    exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, num1Lon + "/1," + num2Lon + "/1," + num3Lon + "/1000");

	// 북위, 남위 정보 삽입
    if (latitude > 0) {
        exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, "N");
    } else {
        exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, "S");
    }

	// 동경, 서경  정보 삽입
    if (longitude > 0) {
        exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, "E");
    } else {
        exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, "W");
    }

	// 정보 갱신
    exif.saveAttributes();
} catch (IOException e) {
    Log.e("PictureActivity", Objects.requireNonNull(e.getLocalizedMessage()));
}

 

이렇게 하면 끝~~~!! 

 

사진정보를 확인해 보면 GPS 정보가 삽입되어 있는 것을 확인할 수 있다.

 

이상으로 GPS 정보가 없는 사진에 휴대폰이나 다른 장치에서 전달받은 GPS 데이터를 삽입하는 방법이었다.

 

오늘도 모두 즐코딩 합시다~!!

반응형
반응형
반응형

음....

 

이번글에는 안드로이드에서 구현하기 귀찮은 부분을 편하게 구현시킨 라이브러리를 하나 공유!!!!

 

- 이름 : WifiUtils

- Github : https://github.com/ThanosFisherman/WifiUtils

 

GitHub - ThanosFisherman/WifiUtils: Easily Connect to WiFi Networks

Easily Connect to WiFi Networks. Contribute to ThanosFisherman/WifiUtils development by creating an account on GitHub.

github.com

 

와이파이 통신을 구현하기 위해서는 Wifimanager를 이용해서 구현을 해야 함

- 구글문서 : https://developer.android.com/reference/android/net/wifi/WifiManager

 

WifiManager  |  Android Developers

 

developer.android.com

 

진행 절차는 간단함

1. WIFI 동작가능한지 확인

2. WIFI Scan 시작

3. 신호 확인 후 접속

 

근데!! 

 

해보신 분들은 해당 부분 구현이 어렵다는 것을 알 것임 

 

그냥 Connect을 한다고 되는 것도 아니고 요즘은 특정 WiFi 에 접속하려면 WiFiSuggestion을 사용해야 한다.

- 참고 내용 : https://developer.android.com/reference/android/net/wifi/WifiNetworkSuggestion.Builder

 

WifiNetworkSuggestion.Builder  |  Android Developers

 

developer.android.com

 

Wi-Fi Suggestion 관련해서는 다음에 정리하도록 하겠음

 

오늘은 라이브러리를 사용하는 법을 알아볼 거니깐?!!

 

 

자!! 아무튼 저 귀찮은 작업을 한방에 없애는 방법이 WiFiUtils 라이브러리가 되시겠다

 

 

 

방법은 간단하다

 

1. 라이브러리 implemetation 

implementation("io.github.thanosfisherman.wifiutils:wifiutils:1.6.6")

2. WiFi 권한설정

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

3. WiFiUtils Log 설정

WifiUtils.enableLog(true);
WifiUtils.forwardLog(new Logger() {
    @Override
    public void log(int priority, String tag, String message) {
        Log.e(tag, message);
    }
});

4. WiFi 검색

WifiUtils.withContext(context).scanWifi(new ScanResultsListener() {
    @Override
    public void onScanResults(@NonNull List<ScanResult> scanResults) {
        if(scanResults.isEmpty()){
            Log.e("getScanResults", "SCAN RESULTS IT's EMPTY");
            WifiUtils.withContext(context).disableWifi();
            return;
        }

        for(ScanResult result : scanResults){
            if(result.SSID.equals("특정 SSID")){
                // 특정 SSID 신호가 검색됬음을 확인
                Log.e("getScanResults", "FIND ==> " + result);
                break;
            }
        }
    }
}).start();

5. WiFi 접속

WifiUtils.withContext(context)
.connectWith(SSID, BSSID, PASSWORD)
.setTimeout(40000)
.onConnectionResult(new ConnectionSuccessListener() {
    @Override
    public void success() {
        Log.d("WifiUtils_Connect", "Success!!");
    }

    @Override
    public void failed(@NonNull ConnectionErrorCode errorCode) {
        Log.e("WifiUtils_Connect", "Fail!!");
    }
}).start();

※ 여기서 BSSID 값이 뭔지 모르는 분들이 있을 거 같아 말씀드림.

    - BSSID(Basic Service Set Identifier) 는 네트워크 ID라고 생각하면 편하실 거다. 통상 MAC 주소라고 생각하면 됨

      그러면 이 주소값은 어떻게 읽어오냐?? 

      아주 편한 라이브러리라고 말씀드렸었다 ㅎㅎㅎ 

      Scan 결과물에 들어있으니 걱정 안 하셔도 괜찮음

      FIND 로그를 확인해 보면 BSSID 값이 있으니 걱정 마시라 

 

6. WiFi 접속해제

WifiUtils.withContext(context).disconnect(new DisconnectionSuccessListener() {
    @Override
    public void success() {
        WifiUtils.wifiLog("DISCONNECT Success!!");
    }

    @Override
    public void failed(@NonNull DisconnectionErrorCode errorCode) {
        WifiUtils.wifiLog("DISCONNECT Fail : " + errorCode);
    }
});

 

이 정도가 심플하게 사용하는 방법이다!! 

 

좀 더 사용하면서 느낀 점을 말하자면 Wi-Fi 접속을 바로 진행하기보다는 Scan 후 해당 SSID 가 확인 된다면 진행하는 것을 추천한다. 

 

질문은 댓글로 남겨주시면 응답하겠음!! 

 

오늘도 다들 즐코딩~!!

반응형
반응형

오늘은 이메일 형식 체크하는 방법을 간단하게 확인해보자 ㅎㅎ 

반응형

기록용이긴하지만 다들 도움이 되면 좋을꺼같아 남김.

 

이메일 유효성 체크는 아래와 같음.

public static boolean isValidEmail(CharSequence target) {
    return !TextUtils.isEmpty(target) && android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
}

 

오늘도 다들 즐코딩 합시다 ㅎㅎ 

반응형
반응형

 

MySQL 을 사용하다가 아래 3가지가 헷갈려서 정리해봄

1) mysqli_fetch_row

2) mysqli_fetch_assoc

3) mysqli_fetch_array 

반응형
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
  <!-- mysqli_fetch_row 배열 번호를 통해 값 호출 가능-->
  <?php
      $query = "SELECT * FROM Select_Colume_DB";
      $result = mysqli_query($conn, $query);
      $row = mysqli_fetch_row($result);
      echo row[0]. " -> " . row[1] . " -> " row[2];
  ?>
  
  <!-- mysqli_fetch_assoc (assoc -> associative array 약자) 필드명을 통해 값 호출 가능 -->
  <?php
      $query = "SELECT * FROM Select_Colume_DB";
      $result = mysqli_query($conn, $query);
      $row = mysqli_fetch_assoc($result);
      echo row['data1']. " -> " . row['data2'] . " -> " row['data3'];
  ?>
  
  <!-- mysqli_fetch_array 배열 번호와 필드명 두가지 다 사용 가능 -->
  <?php
      $query = "SELECT * FROM Select_Colume_DB";
      $result = mysqli_query($conn, $query);
      $row = mysqli_fetch_array($result);
      echo row[0]. " -> " . row['data1'] . " -> " row[2] . " -> " row['data2'];
  ?>
</body>
</html>
SMALL

오늘도 공부공부!! ㅎㅎ 

반응형
반응형

개발 진행 하다가 하나씩 발견되는 문제점에대하여 오늘 정리해본다.

 

EditText 를 사용하다보면 글자 변경 시 이벤트 처리를 해야할 경우가 발생한다.

 

사용처는 아래와 같음

1) 아이디 입력 시 실시간으로 자동 중복확인

2) 패스워드 입력 시 동일값인 지 실시간 확인

3) 문자열입력 시 조건에 맞는 문자인지 실시간 확인

4) 기타 등등 문자열 입력 혹은 변경 시 실시간 확인 처리가 필요한 부분에서 사용가능!!!

반응형

사용법부터 알아보자!!

 

EditText edittext = findViewById(R.id.edittext);
edittext.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
				// 텍스트가 변경되기 전에 동작
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
				// 텍스트가 변경되는 동시에 동작
            }

            @Override
            public void afterTextChanged(Editable s) {
                // 텍스트가 변경된 후 동작
                Log.d("입력TEXT", s.toString());
            }
        });

 

주의할 점은!!!

 

TextWatcher 에서 EditText 값을 변경하게 된다면 무한루프에 빠질 수 있으니 사용 시 조심!!

 

SMALL

 

반응형

+ Recent posts