이카루스 테마에서는 사이드바에 광고를 넣을 수 있도록 제공되는데, 여기에 광고를 넣으려면 _config.icarus.yml에서 client_id와 slot_id를 기입해주면 된다.
아래 작업을 하려면 우선 Google AdSense 내에서 계정을 검토하는 과정을 거쳐야하는데, 이게 2주까지 걸릴 수도 있다고 하더니 내 경우 15일 걸렸다. 막 만든 사이트고(2월 1일 신청당시 포스팅 3개), 검토 요청을 한 2월 1-2일이 설연휴라 더 늦어졌을지도 모르겠다.
승인이 나면 승인되었다는 메일이 오고, Adsense 페이지에 들어가면 다음과 같이 [준비됨]이라고 바뀌어있다.
(1) ads.txt 삽입
아래 나오는대로 ads.txt 파일을 다운받아 루트(source/)에 넣고 hexo clean 후 hexo g 하면 public/ 하위에 생성된 것을 볼 수 있을 것이다.
이 문제는 확인되어 해결되는 데까지 며칠 걸리는 것 같지만 광고 노출 자체는 승인 후 하루 지나서 바로 되어 문제삼지 않았다. (저 빨간 “수익 손실 위험” 팝업은 광고가 노출 되어도 계속 떠있었다.)
(2) 신규 광고 단위 만들기: 사이드 메뉴에 광고 넣기
우선 AdSense 사이드 메뉴의 [개요]에서 상단 탭의 [광고 단위 기준]으로 이동하면 디스플레이/인피드/콘텐츠 내 광고 중 타입을 골라서 단위를 생성할 수 있다.
이카루스 테마에서는 _config.icarus.yml 설정파일에서 위젯으로 제공하기 때문에 여기에 넣을 client ID와 unit ID만 만들어주면 된다.
1 2 3 4 5 6 7 8 9
widgets: - # Where should the widget be placed, left sidebar or right sidebar position:left type:adsense # AdSense client ID client_id:'ca-pub-0' # AdSense AD unit ID slot_id:'0000000000'
내 경우 디스플레이 타입으로 생성하여 만들어진 코드에서 data-ad-client, data-ad-slot 속성값을 각각 client_id, slot_id로 붙여넣었다.
(3) 콘텐츠 내에 광고 삽입
콘텐츠 내에 광고는 포스팅 내에 광고 삽입을 말한다. 이 경우 [광고 단위 기준]의 콘텐츠 내 타입으로 생성하였는데 사이드 메뉴에 넣을 디스플레이 타입과는 다르게 아래와 같이 생성된 스크립트 코드를 직접 포스팅 내에 삽입해주어야 한다.
이 글은 실제로는 2021.01에 작성되어 일부 업데이트된 내용이 누락되었을 수 있음을 미리 밝힙니다.
1. 내부 저장소와 외부 저장소
내부 저장소에 저장된 파일은 애플리케이션 전용이며 다른 애플리케이션에서는 액세스 할 수 없다. 내부 저장소는 /data/data/com.example.testapp/ 이와 같은 경로를 말한다.
외부 저장소는 내부 저장소(UT) 또는 이동식 저장소의 어느 위치에나 있을 수 있다. 휴대전화의 OEM 및 Android OS 버전에 따라 달라질 수 있으므로 단말 기종마다 저장되는 위치가 다르다.
/sdcard 및 /storage/emulated/0 와 같은 형식의 패스는 외부 저장소를 가리킨다. 그러나 이것들은 /storage/sdcard0 대한 심볼릭 링크이기 때문에 (예전에는 된 것 같지만) 현재는 이와 같은 패스를 하드코딩하여 사용하지 않는 게 좋다.
2. 접근 권한
READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
접근 권한은 위와 같이 잘 알려진 두 가지가 있으나 Android 11부터 WRITE_EXTERNAL_STORAGE만 권한허용을 해도 READ_EXTERNAL_STORAGE 권한은 자동으로 부여되도록 변경되었다.
Any app that declares the WRITE_EXTERNAL_STORAGE permission is implicitly granted this permission. 역> WRITE_EXTERNAL_STORAGE 권한을 허용한 앱은 내재적으로 READ_EXTERNAL_STORAGE 권한도 허용한다.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss"); String fileName = format1.format(System.currentTimeMillis()) + ".jpg";
ContentValues values = new ContentValues(); // DCIM/ 또는 Pictures/ 이외의 장소에 접근하려고 하면 오류 values.put(MediaStore.Images.Media.RELATIVE_PATH, "DCIM/" + CommConstants.FOLDER_DIRECTORY); values.put(MediaStore.Images.Media.DISPLAY_NAME, fileName); values.put(MediaStore.Images.Media.MIME_TYPE, "image/*"); values.put(MediaStore.Images.Media.IS_PENDING, 1); // 파일을 write중이라면 다른곳에서 데이터요구를 무시
if (imageFile != null) { values.clear(); values.put(MediaStore.Images.Media.IS_PENDING, 0); // 파일을 모두 write하고 다른곳에서 사용할 수 있도록 0으로 업데이트 contentResolver.update(item, values, null, null); } }
(3) MediaStore.MediaColumns.DATA 칼럼 접근 불가
query issue: invalid column latitude
MediaStore.MediaColumns.DATA 칼럼이 android 10부터 deprecated되어 접근할 수 없어서 발생하는 이슈이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
publicstatic String getRealPathFromURI(Context context, Uri contentUri)throws SecurityException { String res = null; String[] proj = {MediaStore.MediaColumns.DATA, MediaStore.MediaColumns.DISPLAY_NAME}; Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null); if (cursor != null && cursor.moveToFirst()) { int columnIndex = (contentUri.toString().startsWith("content://com.google.android.gallery3d")) ? cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME) : cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA); res = cursor.getString(columnIndex); cursor.close(); } if (TextUtils.isEmpty(res)) { res = contentUri.getPath(); } return res; }
따라서 이미지는 Q 미만일 때 위의 코드를 그대로 사용하면서, 비디오를 업로드할 경우는 아래의 코드를 통해 새로 카피본을 만들어 File을 받아 처리하도록 한다.
이미지의 경우, 사진 및 스크린샷을 포함하며 DCIM/ 및 Pictures/ 디렉터리에 저장된다. 시스템은 이러한 파일을 MediaStore.Images 테이블에 추가한다. 즉, 파일 탐색기에서 Images 영역에 가면 저장한 파일을 확인할 수 있다.
만약 DCIM/ 또는 Pictures/ 이외의 장소에 접근하려고 하면 아래와 같은 에러가 뜬다.
Caused by: java.lang.IllegalArgumentException: Primary directory TestDir not allowed for content://media/external_primary/images/media; allowed directories are [DCIM, Pictures]