라 쓰고 나의 삽질 여정기라 읽는다

 

1. 블루투스 퍼미션 선언

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

 

2. 위치권한 요청

//위치권한 요청
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    checkPermissions(permission);
}
//퍼미션 체크
@RequiresApi(api = Build.VERSION_CODES.M)
public void checkPermissions(String permissions) {

    int permissionCheck = ContextCompat.checkSelfPermission(this, permission);
    if (permissionCheck == PackageManager.PERMISSION_DENIED) {
        if (shouldShowRequestPermissionRationale("위치")) {
            //권한 설명 필요
            Toast.makeText(this, "블루투스 사용을 위해 권한이 필요합니다", Toast.LENGTH_SHORT).show();
        } else {
            requestPermissions(
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    REQUEST_CODE);
        }
    }
}

//안드로이드 퍼미션 요청결과
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
                                       int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case REQUEST_CODE:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                //권한 승인
            } else {
                //권한 거부
                Toast.makeText(this, "위치 권한을 허용해주세요.", Toast.LENGTH_SHORT).show();
            }
            return;
    }
}

 

3. 블루투스 연결

//블루투스 연결
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
//블루투스가 켜져있을 때
if (bluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
    bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
    bluetoothLeScanner.startScan(scanCallback);
} else if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) { 
//꺼져있을때
    Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult(intent, REQUEST_ENABLE_BT);
}
//스캔콜백
scanCallback = new ScanCallback() {
            @Override
            public void onScanResult(int callbackType, ScanResult result) {
                super.onScanResult(callbackType, result);

                if (result.getScanRecord().getDeviceName() == null) {
                //원하는 이름과 일치하는 디바이스가 없음
                    scanDeviceName = "Unknown";
                } else {
                    scanDeviceName = result.getScanRecord().getDeviceName();
                    Log.i("scanDeviceName", scanDeviceName);
                    if (scanDeviceName.equals(deviceName)) {
                    //원하는 이름과 일치하는 디바이스가 있을때 address 받아오기
                        scanDeviceAddress = result.getDevice().getAddress();
                        //스캔종료
                        bluetoothLeScanner.stopScan(scanCallback);
			//해당 주소로 연결
                        connection(scanDeviceAddress);
                    }
                }
            }
        };
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public void connection(String scanDeviceAddress) {
    bluetoothDevice = bluetoothAdapter.getRemoteDevice(scanDeviceAddress);
    bluetoothGatt = bluetoothDevice.connectGatt(getApplicationContext(), false, bluetoothGattCallback);

}

 

 

1. 안드로이드 디벨로퍼 저전력 블루투스

https://developer.android.com/guide/topics/connectivity/bluetooth-le?hl=ko#java 

 

저전력 블루투스 개요  |  Android 개발자  |  Android Developers

저전력 블루투스 개요 Android 4.3(API 레벨 18)에서는 저전력 블루투스(BLE)에 대한 플랫폼 내 지원을 핵심적 역할로 도입하고 앱이 기기를 검색하고, 서비스를 쿼리하고, 정보를 전송하는 데 사용할

developer.android.com

https://github.com/googlearchive/android-BluetoothLeGatt/blob/master/Application/src/main/java/com/example/android/bluetoothlegatt/BluetoothLeService.java

 

GitHub - googlearchive/android-BluetoothLeGatt: Migrated:

Migrated:. Contribute to googlearchive/android-BluetoothLeGatt development by creating an account on GitHub.

github.com

==> 오래되서 도움 안됨 deprecate 된것도 있고 노쓸모

 

2. 뭐라그러더라 개발문서? 새벽이라 까먹음 여튼 안드로이드 Docs

https://developer.android.com/reference/android/bluetooth/BluetoothGatt?hl=ko 

 

BluetoothGatt  |  Android Developers

 

developer.android.com

==> 위에것보다 나음. 메소드들 역할 알수있어서 이게 나음

 

3. 블루투스 연결 예제 샘플

https://github.com/android/connectivity-samples/blob/master/BluetoothLeGatt/Application/src/main/java/com/example/android/bluetoothlegatt/DeviceControlActivity.java

 

GitHub - android/connectivity-samples: Multiple samples showing the best practices in connectivity on Android.

Multiple samples showing the best practices in connectivity on Android. - GitHub - android/connectivity-samples: Multiple samples showing the best practices in connectivity on Android.

github.com

==> 저전력 아니고 클래식임

 

4. 코틀린.. 그리고 nRF Connect 앱

https://m.blog.naver.com/PostView.naver?blogId=yuyyulee&logNo=221685206562&targetKeyword=&targetRecommendationCode=1 

 

[Kotlin Tip] 안드로이드에서 BLE(Bluetooth Low Energy) 통신하기 (2)

이전 포스팅에 이어서 BLE 연결하기부터 시작. >> 이전 포스팅 https://blog.naver.com/yuyyulee/...

blog.naver.com

==> 스캔하면 나오는 여러 UUID 중에 어떤거를 써야할지 방향성을 알려줌 nRF 커넥트 앱.. ㄳㄳ 최고 도움된 글

 

5. 블루투스 BLE 연결 샘플

https://github.com/joelwass/Android-BLE-Connect-Example/blob/master/app/src/main/java/com/example/joelwasserman/androidbleconnectexample/MainActivity.java

 

GitHub - joelwass/Android-BLE-Connect-Example: Simple example application that allows you to scan, and connect to a ble device o

Simple example application that allows you to scan, and connect to a ble device on Android (M) API 23 - GitHub - joelwass/Android-BLE-Connect-Example: Simple example application that allows you to ...

github.com

 

==> 6years ago.. 옙.. 그래도 도움되었다

 

6. UUID 뜻을 알게된..

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=geniusus&logNo=221761337501 

 

BLE(Bluetooth Low Energy)의 이해와 UUID목록

아두이노를 사용하다보면 BLE(Bluetooth Low Energy)모듈을 사용하여 다양한 앱과 장치를 연결하여야...

blog.naver.com

==> UUID 목록들 참고참고

 

7. 아두이노와 연결하는 코드

https://remnant24c.tistory.com/297

 

아두이노 나노(Arduino Nano 33 IoT) BLE 값을 송수신 가능한 BLE 안드로이드 앱 만들기

안녕하세요.  이전 아두이노 나노 IoT에서 자이로 센서 값을 RFConn 프로그램으로 받는 것을 실험해보았습니다. 그러나 실제로 RFConn 프로그램은 우리가 원하는 BLE 앱으로 배포할 수 없습니다. 그

remnant24c.tistory.com

==> 자바로 쓰여있고 최근 글이라 참고 많이 됨

 

8. BLE의 작동 방식

https://binux.tistory.com/26

 

Bluetooth Low Energy (BLE)

Bluetooth Low Energy (BLE) BLE란? 과거부터 기기들간의 무선 연결은 주로 Bluetooth 기술을 사용해왔다. 이들은 기기간에 마스터, 슬레이브 관계를 형성하여 통신하는 Bluetooth Classic이라는 방식을 이용했

binux.tistory.com

==> 어떻게 작동하느냐에 대해 알수있음

 

9. UUID 목록

https://www.bluetooth.com/specifications/assigned-numbers/

 

Assigned Numbers | Bluetooth® Technology Website

Assigned Number Type Details 16-bit UUIDs The 16-bit UUID Numbers Document contains the following value types: GATT Service, GATT Unit, GATT Declaration, GATT Descriptor…

www.bluetooth.com

==> UUID 목록 있음..

 

10. ble와 gatt의 이해

https://enidanny.github.io/ble/ble-att-gatt/

 

BLE (3) - ATT/GATT 이해하기

3. ATT/GATT

enidanny.github.io

==>많이 봤으나.. 또 봄

 

11. 파이썬이랑 라즈베리파이

https://m.blog.naver.com/juke45ef/220834141429

 

블루투스 4.0 BLE 프로그래밍

블루투스 4.0 BLE 프로그래밍 작성자: 매발톱수정: 2016.08.23버전: 1 1. BLE 통신 소개 블루투스 4....

blog.naver.com

==> 도움됨

 

12. (가장도움됨) 가장 도움됨 말이 필요없음 드디어 값을 받아옴

https://whiteduck.tistory.com/161

 

[Android] Bluetooth BLE 연동 가이드

// 2021. 05.04 에 작성된 가이드입니다. // targetSdkVersion 30 // 참고 : 끝에 full source code 가 있습니다. 급하신 분은 내려서 보시기 바랍니다. Bluetooth BLE Bluetooth BLE 은 Scan 시 다음과 같은 프로..

whiteduck.tistory.com

https://gist.github.com/lhjnano/d72cbf3423201db4d84ca19cc4a53b9e

 

BluetoothGuide.java

GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

 

 

13. 도움 개많이 됨 진짜로 나의 삽질과정을 해결해줌

https://yuar.tistory.com/entry/BLE-%ED%86%B5%EC%8B%A0-%EA%B0%9C%EB%85%90-%ED%86%B5%EC%8B%A0-%EA%B3%BC%EC%A0%95-Notification-%EC%84%A4%EC%A0%95

 

BLE 통신 개념 + 통신 과정 + Notification 설정

  1. BLE 통신 개념 1) 개념 정리 BLE 란? :  2010년, 새로운 Bluetooth 표준으로 Bluetooth 4.0 이 채택이 된다. 기존의 Bluetooth Classic과의 가장 큰 차이는 훨씩 적은 전력을 사용하여 Classic과 비슷한..

yuar.tistory.com

 

14. 도움 조금 됨 1정도..

https://github.com/androidthings/sample-bluetooth-le-gattserver/blob/master/java/app/src/main/java/com/example/androidthings/gattserver/GattServerActivity.java

 

GitHub - androidthings/sample-bluetooth-le-gattserver: Build a Bluetooth GATT server with Android Things

Build a Bluetooth GATT server with Android Things. Contribute to androidthings/sample-bluetooth-le-gattserver development by creating an account on GitHub.

github.com

 

15. 기억이 안나

https://popcorn16.tistory.com/192

 

[Android] 블루투스 통신 예제 (with 아두이노)

이전 포스팅에서 아두이노와 안드로이드가 블루투스로 통신이 되는 걸 확인했습니다. 블루투스 통신 예제는 GitHub에 많아서 금방 개발할 수 있을 거라고 생각했는데, 예상외로 permission과 connected

popcorn16.tistory.com

https://altongmon.tistory.com/436

 

안드로이드 BLE(Bluetooth Low Energy) Scanner 구현 => BluetoothAdapter, BluetoothLeScanner

공감 및 댓글은 포스팅 하는데  아주아주 큰 힘이 됩니다!! 포스팅 내용이 찾아주신 분들께 도움이 되길 바라며 더 깔끔하고 좋은 포스팅을 만들어 나가겠습니다^^ 이번 포스팅에서는 BLE Beacon Sc

altongmon.tistory.com

http://www.digipine.com/index.php?mid=android&document_srl=649 

 

Android - Android - 블루투스 BLE 개발하기

Bluetooth Low Energy 4.3부터 BLE central role을 지원하기 시작했다. 그리고 디바이스 검색과 서비스 검색 그리고 속성들의 읽기/쓰기를 지원한다. BLE를 통해 저전력으로 설계된 다양한 디바이스와통신이

www.digipine.com

https://blog.naver.com/PostView.nhn?blogId=bluecrossing&logNo=221468275427&parentCategoryNo=&categoryNo=83&viewDate=&isShowPopularPosts=true&from=search 

 

[android] BLE 통신

BLE구현 순서 1. 매니페스트에 퍼미션 설정 <uses-permission android:name="android.per...

blog.naver.com

https://www.hardcopyworld.com/?p=3152 

 

[사물 인터넷 네트워크와 서비스 구축 강좌] #3-5 BLE 프로토콜 소개

강좌 전체보기 사물 인터넷 네트워크와 서비스 구축 강좌 목차 . 본격적으로 BLE 에 대한 내용을 다루기 전에 BLE 프로토콜에 대해 먼저 언급을 해야겠습니다. 이미 [3-1 블루투스 소개] 파트에서 BL

www.hardcopyworld.com

 

 

다 읽고나니까 좀 나도 안다고 할수있겠다

 

 

넘버피커

그대로 쓰면 글자가 넘 작어잉

구분선 보기싫어잉

 

1. 구분선 지우기 : xml 넘버피커 속성에 아래 코드 추가

android:selectionDividerHeight="0dp"

 

2. 글자크기 키우기, 색상 바꾸기 : themes.xml에 새로운 테마 선언해서 넘버피커에 테마적용하기

<style name="NumberPickerStyle">
    <!-- 글자 크기 -->
    <item name="android:textSize">26dp</item>
    <!-- 색상변경 -->
    <item name="android:textColorPrimary">하고싶은 색상</item>
</style>

xml  넘버피커 속성에 아래 코드 추가

android:theme="@style/NumberPickerStyle"

 

 

끝!

 

(에디트텍스트컬러로는 안바뀌더라고..)

 

clock 모드에서 색상 옵션 적용부위는 이렇다

https://www.tutorialsbuzz.com/2019/09/android-timepicker-dialog-styling.html

 

 

하지만 스피너 타입이라면 바꿀수있는 색상은 

글자색, 시간과 분을 구분하는 : 정도 아닐까

 

<!-- 오전, 오후, 시간, 분 글자의 색상 -->
<item name="android:textColorPrimary">#EAEAEA</item>


<!-- 시간과 분을 구분하는 : 의 색상 -->
<item name="android:textColor">#EAEAEA</item>

 

검색하다보니까 거의 다들 저 clock 모드에서 적용부위를 써놔서ㅠ

기초적인거겠지만 이렇게 해결~~~

 

타임피커의 스피너처럼 돌아가는 회전형 커스텀 메뉴를 만들고싶었다.

넘버피커를 활용하면 될거같은데?라고 막연히 생각하던중

딱맞는걸 찾았다 대박적

 

출처는 여기

https://stackoverflow.com/questions/33163828/ios-like-spinner

 

1. 일단 xml에서 넘버피커 하나 만들어주기

<NumberPicker
        android:id="@+id/numberpicker"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:selectionDividerHeight="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>

아래 부분은 디바이더가 꼴보기싫어서 없앤것.. 보기싫어..

android:selectionDividerHeight="0dp"

 

 

2. 해당 액티비티에서 마저 작성하기

	NumberPicker numberpicker;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sound_set);
        
        numberpicker = (NumberPicker) findViewById(R.id.numberpicker);
        //Initializing a new string array with elements
        final String[] values= {"아이템 1","아이템 2", "아이템 3"};

        //Populate NumberPicker values from String array values
        //Set the minimum value of NumberPicker
        numberpicker.setMinValue(0); //from array first value
        //Specify the maximum value/number of NumberPicker
        numberpicker.setMaxValue(values.length-1); //to array last value

        //Specify the NumberPicker data source as array elements
        numberpicker.setDisplayedValues(values);

        //Gets whether the selector wheel wraps when reaching the min/max value.
        numberpicker.setWrapSelectorWheel(true);

        //Set a value change listener for NumberPicker
        numberpicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
            @Override
            public void onValueChange(NumberPicker picker, int oldVal, int newVal){
                //Display the newly selected value from picker
                Toast.makeText(getApplicationContext(), "Selected value : " + values[newVal], Toast.LENGTH_SHORT).show();
            }
        });
    }

 

이러면 됨~! 

 

 

1의 방법과 2의방법 모두 작성할텐데

1의 방법은 무쓸모여서 내가 삽질했단게 결론이고

2의 방법으로 해결했다는 것이 요지.

 

 

1. 카카오가 알려준 or 대부분이 알려주는 릴리즈&디버그 키 해시 확인방법

--> open ssl을 통해 키 확인하기

 

keytool -exportcert -alias <--키 alias--> -keystore <--키스토어 경로--> -storepass android -keypass android | openssl sha1 -binary | openssl base64

 

이러면 아주 쓸데없는 값이 나오기 때문에 걍 대충 한줄만 쓰고 말거임

여기에서 나오는거 키 해시에 등록한다?

"아,, 왜안되는거지,,,ㅠㅠ 시키는대로 했는데,,, 다른거 문제인가?"

이러면서 개삽질 쌉가능 쌉파서블임

 

2. 이 방법을 쓰세요. 긴말 안함

--> 디버그키

private void getAppKeyHash() {
    try {
        PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES);
        for (Signature signature : info.signatures) {
            MessageDigest md;
            md = MessageDigest.getInstance("SHA");
            md.update(signature.toByteArray());
            String something = new String(Base64.encode(md.digest(), 0));
            Log.d("Hash key", something);
        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        Log.e("name not found", e.toString());
    }
}

해당 메소드 작성하고 호출하면 디버그 시 로그에 Hash Key 값이 찍힐것임. 그것이 debug hash key 값.

 

--> 릴리즈키

private void getAppKeyHash() {
    try {
        PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES);
        for (Signature signature : info.signatures) {
            MessageDigest md;
            md = MessageDigest.getInstance("SHA");
            md.update(signature.toByteArray());
            String something = new String(Base64.encode(md.digest(), 0));
            /*걍 화면에 텍스트 하나 만들어서 something 출력*/.setText(something);
        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        Log.e("name not found", e.toString());
    }
}

작성 후 build - generate signed bundle / apk 를 통해 release 앱 만들고 실행하면

화면의 text에 위에서 나온 디버깅값도 아니고 1번의 값도 아닌 무뜬금 첨보는 값 나올것임.

그것이 릴리즈키 ㅎ..

 

나는 왜 이것때문에 삽질을 했능가

 

 

 

 

참고링크

https://devtalk.kakao.com/t/topic/623/4

 

Kakao DevTalk

카카오 데브톡. 카카오 플랫폼 서비스 관련 질문 및 답변을 올리는 개발자 커뮤니티 사이트입니다.

devtalk.kakao.com

 

 

 

1. 해당 톰캣 설치된 폴더로 이동

2. logs -> catalina.out 확인

3. 오류가 적혀있다... 나의 오류는

  ---> mysql 커넥터를 내 로컬 톰캣에 넣고 썼는데 프로젝트에 커넥터를 넣지 않았던 것.

  ---> 배포 서버 톰캣의 lib에는 mysql 커넥터가 없었다

  ---> 배포 서버 톰캣에 커넥터를 넣거나 프로젝트에 커넥터를 넣어서 해결..!

 

허무하게 해결

'spring' 카테고리의 다른 글

[스프링] 에러페이지 만들기  (0) 2021.04.29
[스프링] 프로젝트 초기 설정 하기  (0) 2021.04.29

1. 에러를 처리할 패키지 생성

2. 에러 처리할 파일 작성

package <-- 1에서 만든 패키지-->;

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import lombok.extern.log4j.Log4j;

@ControllerAdvice
@Log4j
public class CommonExceptionAdvice {
	
	@ExceptionHandler(Exception.class)
	public String exception(Exception exception, Model model) {
		log.error(exception.getMessage()); //콘솔에서 로그 확인
		return "error_page"; //해당 에러페이지 출력
	}
}

3. servlet-context.xml에서 스캔하도록 추가

<context:component-scan base-package="<-- 해당 에러 패키지-->"/>

** 404의 경우

1. web.xml 수정(throwExceptionIfNoHandlerFound 추가)

	<!-- Processes application requests -->
	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
		</init-param>
		<init-param>
			<param-name>throwExceptionIfNoHandlerFound</param-name>
			<param-value>true</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

2. 에러 처리 파일에 메소드 추가

	@ExceptionHandler(NoHandlerFoundException.class)
	@ResponseStatus(HttpStatus.NOT_FOUND)
	public String handle404(NoHandlerFoundException exception) {
		return "error_page";
	}

 

+ Recent posts