모바일 쿠폰이나 입장 QR을 앱에서 보여주는 화면을 만들었는데, 테스트하다 보니 문제가 하나 있었다. 사용자가 화면 밝기를 낮춰둔 상태면 QR 리더기가 코드를 잘 못 읽는다. 매장에서 "밝기 좀 올려주세요"라는 말을 듣게 되는 바로 그 상황이다. 밝기는 사용자가 알아서 올려야 하는 게 아니라, 코드를 보여주는 동안 앱이 알아서 올려줬다가 원래대로 돌려놓는 게 맞다.
Expo라면 expo-brightness 하나로 된다.
설치
npx expo install expo-brightness
화면 들어올 때만 밝게, 나갈 때 원복
핵심은 "QR 화면에 있는 동안만" 밝기를 올리는 거다. 밝혀놓고 안 돌려놓으면 사용자 입장에선 앱이 멋대로 밝기를 바꿔버린 꼴이 된다. 그래서 들어올 때 원래 밝기를 저장해두고, 나갈 때 그 값으로 복원하는 패턴을 쓴다. useEffect의 cleanup에 딱 맞다.
import { useEffect } from 'react';
import * as Brightness from 'expo-brightness';
function useBoostBrightness() {
useEffect(() => {
let original = 1;
let active = true;
(async () => {
original = await Brightness.getBrightnessAsync();
if (active) await Brightness.setBrightnessAsync(1); // 0~1
})();
return () => {
active = false;
Brightness.setBrightnessAsync(original); // 원래 밝기로 복원
};
}, []);
}
active 플래그는 밝기를 읽어오는 비동기 작업이 끝나기 전에 화면을 빠르게 벗어났을 때, 뒤늦게 최대 밝기로 올려버리는 걸 막는 안전장치다. 이게 없으면 화면을 나갔는데 밝기만 올라가 있는 경우가 생긴다.
이제 QR 화면 컴포넌트에서 한 줄 호출하면 끝이다.
function TicketScreen() {
useBoostBrightness();
return <QRCodeView value={ticketCode} />;
}
권한 없이 되는 범위를 알아두자
여기서 쓴 setBrightnessAsync는 앱 안에서만 밝기를 바꾸는 함수라 별도 권한이 필요 없다. iOS에서는 앱이 백그라운드로 가면 시스템이 알아서 원래 밝기로 되돌려준다.
반면 시스템 전체 밝기를 영구적으로 바꾸는 setSystemBrightnessAsync는 Android에서 WRITE_SETTINGS 권한이 필요하다. QR 보여주기 정도엔 과하니 앱 범위 함수로 충분하다.
const { status } = await Brightness.requestPermissionsAsync(); // 시스템 밝기 쓸 때만
정리
- QR·바코드·모바일 티켓 화면은 밝기를 자동으로 올려주면 완성도가 확 올라간다.
getBrightnessAsync로 원래 값을 저장 →setBrightnessAsync(1)→ cleanup에서 복원.- 비동기 순서 꼬임은
active플래그로 막는다. - 권한 없이 쓰려면
setBrightnessAsync(앱 범위), 시스템 전체 밝기는 권한이 필요하다.
밝기 자동 조절은 사용자가 의식하지 못하는 디테일이지만, 매장에서 QR이 한 번에 찍히느냐 아니냐를 가른다.