DB 테이블에서 datetime으로 되어 있는 컬럼을 시간 기준으로 검색하고자 할 때, 다음과 같이 where 절에서 datetime의 format을 변경해 준 다음 between을 사용하여 검색하면 시간을 기준으로 select 할 수 있다.

select send_date
from tb_send_result
where date_format(send_date,'%T') between '00:00:00' and '06:00:00'
order by send_date desc

 

php를 사용하여 데이터베이스 처리를 할 때 isset과 empty를 사용하여 데이터의 유효성을 확인할 수 있다.

 

isset()

변수의 유효성을 확인할 때, (NULL) 값인지 아닌지만을 확인함.

변수에 0, "" 과 같은 값이 들어 있을 때 변수에 값이 있다고 판단하여 TRUE 반환.

 

empty()

변수의 유효성을 확인할 때, (NULL) 값뿐만 아니라 0, "" 과 같은 값이 들어 있을 때 변수에 값이 없다고 판단하여 TRUE 반환.

 

따라서 (NULL)만 확인하면 되는지, 아니면 변수에 0이나 ""도 확인을 해야하는지에 따라 두 가지 함수를 쓰면 됨.

API 29 이상에서는 외부 저장소 접근을 하려고 하면 filenotfoundexception open failed eacces (permission denied) 에러가 발생한다.

이는 API 29 이상에서 부터는 외부 저장소에 접근하기 위해 범위 지정 저장소를 사용하기 때문에 발생하는 문제인데 다음과 같이 범위 지정 저장소 사용을 일시적으로 해제 하여 접근 가능하다.

 

※ 타겟 SDK 레벨에 상관없이 모든 앱의 내년도 주요 플랫폼 출시에는 범위 지정 저장소가 요구됩니다. 그러므로 앱이 범위 지정 저장소를 잘 사용하는지 미리 확인하는 것이 좋습니다

 

이는 파일의 위치에 접근하지 못하여 발생하는 문제로 AndroidManifest.xm 파일을 다음과 같이 수정하면 쉽게 해결 가능하다. 

manifest에 다음과 같이 파일의 위치에 접근 권한을 추가한다.

<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
범위 지정 저장소를 일시적으로 선택 해제할 수 있다. (API 29 이상에서는 디폴트 값이 fasle)

<application 
      android:requestLegacyExternalStorage="true" >

 

 

참고
 

범위가 지정된 외부 저장소 액세스 관리하기  |  Android 개발자  |  Android Developers

사용자에게 파일의 더 많은 권한을 제공하고 파일이 복잡해지는 것을 제한하기 위해, Android 10(API 레벨 29) 이상을 타겟팅하는 앱은 외부 저장소로 범위가 지정된 액세스 또는 범위 지정 저장소

developer.android.com

 

애플리케이션에서 핸드폰 번호를 가져오기 위해서 TelephonyManager의 getLine1Number()를 사용하면 된다.

하지만 AndroidMenifest에서 uses-permission을 다음과 같이 적고 

<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />

permission도 다음과 같이 체크했음에도 불구하고 앱이 정상적으로 작동하지 않았다.

if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED 
	|| ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_PHONE_NUMBERS) != PackageManager.PERMISSION_GRANTED) {
    	ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.READ_PHONE_STATE,
        android.Manifest.permission.READ_PHONE_NUMBERS
    }

 

이럴 땐, @SuppressLint("MissingPermission")을 다음과 같이 사용하면 된다.

@SuppressLint("MissingPermission") String mobile = TelephonyManager.getLine1Number(); //전화번호
if (mobile.startsWith("+82"))
	mobile = mobile.replace("+82", "0");

 

bitbucket에서 비공개 저장소에 push를 하려고 하니 fatal: Could not read from remote repository. 와 같은 에러가 발생하며 진행되지 않았다.

ssh 키를 저장소에 저장했지만 역시나 계속 에러가 발생해서 알아보니 ssh 키를 저장소에 저장하는 것이 아니라 개인 세팅에서 저장해주어야했다.

저장소 ssh에 키를 등록하고 개인 ssh를 등록하려고 하면 이미 등록되어 있다고 뜨니 저장소에 있는 ssh는 삭제한 다음에 개인 세팅에서 ssh 키를 등록하면 문제 없이 push에 성공하였다.

 

ssh 키 생성은 Mac의 경우 다음과 같다.

ssh-keygen //키 생성

//Generating public/private rsa key pair.
//Enter file in which to save the key (/Users/hyunjin/.ssh/id_rsa): 과 같이 뜨면 그냥 enter를 입력하면 된다.

The key's randomart image is:
+---[RSA 3072]----+
|                  .=*  +=.+|
|               oo+o. =+o|
|               E =..oo O+|
|                     .  . .*.X|
|                   S .  .o*+|
|                   * * o.++|
|                    . o ++o|
|                      X o+..|
|                     . oo.+.|
+----[SHA256]-----+
//위와 같은 이미지가 출력된다면 성공적으로 ssh 키 생성

cat ~/.ssh/id_rsa.pub //결과로 나온 ssh를 Add SSH Key의 key* 에 넣어주면 된다.

저장소 관리에서 ssh 키 추가를 하는 것이 아니다.
개인 세팅에서 ssh 키를 추가해야한다.

깃허브의 README.md나 위키에 이미지를 첨부하려고 하면 ![image](http:// 이미지 링크) 마크 다운을 이용하면 된다.

하지만 이미지 링크를 내 컴퓨터를 파일을 쓰고 싶은 경우엔 다음과 같은 방법을 쓸 수 있다.

 

깃허브 저장소의 이슈 탭에 가면 다음과 같은 화면을 볼 수 있는데, write안에 이미지 파일을 드랍하거나 업로드 하면 다음과 같이 마크다운과 링크가 함께 생긴 것을 확인할 수 있다.

이를 복사하면 위키나, README.md에 넣으면 이미지가 잘 올라간 것을 확인할 수 있다.

#include <stdio.h>
#include <stdlib.h>

int main()
{
	int *ptr;

	if (ptr)	//에러 발생
		printf("ptr is not null");
    
	ptr = (int*)malloc(sizeof(int) * 3);
	ptr[0] = 0;
    
	free(ptr);

	if (ptr)	//에러가 발생하지 않음
		printf("ptr is not null : %d", ptr[0]);	//실행됨
        
    return 0;
}

 

8번 라인에서 포인터 변수를 초기화하지 않고 사용을 하면 에러가 발생한다.

malloc을 이용해 int *3 만큼의 메모리 할당을 한 뒤 free를 이용해 할당을 해지하고 ptr을 이용해 데이터에 접근한다면 에러가 발생하지 않는다.

 

이는 free를 하면 할당 되었던 메모리에 다른 포인터가 접근 가능하게 하는 것이지 메모리의 내용을 지우는 것이 아니기 때문에 여전히 그 메모리 공간에 데이터가 그대로 남아있기 때문이다.

 

안전하게 free를 이용하기 위해선 다음과 같은 방식을 이용해 free한 포인터를 이용해 해당 메모리의 접근을 막으면 된다.

#include <stdio.h>
#include <stdlib.h>

int main()
{
	int *ptr;

	ptr = (int*)malloc(sizeof(int) * 3);
	ptr[0] = 0;
    
   	 if(ptr)
 	 {
   		  free(ptr);
   		  ptr = NULL;
 	 }
        
    return 0;
}

 

문제

카카오맵 API에서 키워드로 검색을 사용하기 위해 quey 파라미터를 주는데 다음과 같은 문제를 발견했다.

query=분식,떡볶이일 떄와 query=떡볶이,분식의 경우에 결과가 다른 것을 볼 수 있다.

keyword를 보면, 파라미터에 분식,떡볶이가 하나의 키워드로 묶여서 검색된 것이다.


해결

이를 해결하기 위해선 query 파라미터에 각 파라미터를 ""로 감싸서 보내면 된다.

qurey="분식","떡볶이" 이렇게 보내면 각각 keyword에 따로 들어가 qurey="분식","떡볶이"와 qurey="떡볶이","분식"의 결과가 같은걸 확인 할 수있다.


+ Recent posts