아래의 글은 이메일로 문의를 준 학생들에게 대답해줬던(사실 방금..) 내용입니다.
배터리 관련 내용들은 여기저기 많으므로 별로 필요없을거라고 생각하긴 하지만, 그래도 블로그에는 적어두려고 옮깁니다. (2013.08.27)
배터리 스토커는, 실시간(1초 단위의) 정확성 보다는 좀 떨어지더라도, 배터리를 적게 먹도록 하는데 치중을 했고요.
아래 글은 위젯에 대한 얘기기는 하지만, 배터리를 적게 먹도록 하는데 대한 로직? 이라고 할 수 있겠네요.
(사실상 배터리 스토커도 비슷한 방식으로 동작하고요, 사실, 아래 링크는 어플 스토커 쪽에 가까울듯?)
이 링크는 예전에 심심해서 찍어본, 하루 평균 실행시간 통계를 내는 과정입니다.
1. 배터리 변화 Receive 하기
기본적으로 배터리 변화에 대한 BoradCast 를 받기 위해서는,
BroadcastReceiver 를 확장한 클래스(상속받은 클래스)에 아래와 같은 액션을 추가해 줍니다.
<action android:name="android.intent.action.BATTERY_CHANGED"></action>
하지만, 이 액션을 추가한것만으로는 즉시 리시브 할 수 없고요, 이런 코드가 필요하죠.
BatteryStalkerReceiver batteryStalkerReceiver = new BatteryStalkerReceiver();
context.registerReceiver(batteryStalkerReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
!! 문제는 여기서 registerReceiver 를 하게 되면, 쉬지 않고 계속해서 업데이트를 받는다는 것,
배터리 어플이 배터리를 많이 잡아 먹을 필요 없죠.
배터리 변화 데이터를 한번 받고, 등록했던 리시버를 즉시 해제 합니다.
context.unregisterReceiver(batteryStalkerReceiver);
이렇게 등록을 하게되면, 배터리스토커의 경우 BatteryStalkerReceiver (extends BroadcastReceiver) 가 해당 정보를 수신 할 수 있는 상태가 되죠.
이제 Receiver 의 onReceive(...) 메소드에서 Action 을 확인하고 데이터를 처리해주면 됩니다.
뭐 보통은... 아래와 같은 방식이 되겠죠.
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_BATTERY_CHANGED.equal(action)) {
// TODO some codes....
}
}
2. 알람매니저 및 서비스를 활용한 Receiver register 및 Unregister
자세한 코드는 인터넷 여기저기에 많이 있으니, 개념적인 부분만 설명해 볼게요.
이 애플리케이션의 주 목적은 배터리 정보를 캐치해서 노티비케이션으로 보여주는것입니다.
하지만, 'Intent.ACTION_BATTERY_CHANGED' 라는 액션을 receive 하게 되면, 이건 거의 실시간으로 업데이트가 되버리죠. 즉, 백그라운드에서 계속 실행된다는 얘기.
배터리 어플이 배터리를 많이 잡아먹는다는 것 자체가 되어버리는, 그야말로 말이 안되는 상황이 되어버리죠.
그래서 이런 문제점을 해결하고자,
AlaramManager 를 이용합니다.
알람매니저를 통해, 일정시간 이후, 서비스를 실행하도록 하죠.
해당 서비스에서는, [1. 배터리 변화 Receive 하기] 의 registerReceiver / unregisterReceiver 를 실행해줍니다.
추가적으로 '일정시간 이후, 서비스가 실행 될 수 있도록' 다음 알람을 등록해줍니다.
배터리스토커의 경우,
(1) 앱실행 > (2) 알람 즉시 등록
> (3) 서비스 실행됨, 배터리변화 리시버 등록 및 해제, 다음 알람 등록(서비스 실행용)
> (4) 리시버 실행됨, 배터리 데이터 가져와서 노티피케이션에 보여줌
이제 (3) ~ (4) 만 반복이 되겠죠.
3. 추가적인 배터리 변화 체크 Action 들
기본적으로는 Battery changed action 을 통해 왠만한건 처리할 수 있지만, 다른 상태들이 몇개 있죠.
핸드폰을 컴퓨터에 연결한다거나, 충전기에 연결했을 경우, 연결을 분리한 경우도 체크를 해주려면 이 액션들을
예의 리시버에 추가해줍니다.
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"></action>
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"></action>
배터리가 조금있을 때, 적당한상태(OKAY) 로 있을때를 체크해 주는 액션들도 있습니다. 필요할때 추가해주면 되겠죠.
<action android:name="android.intent.action.ACTION_BATTERY_LOW"/>
<action android:name="android.intent.action.ACTION_BATTERY_OKAY"/>
4. 핸드폰 종료/재시작, 부팅완료시의 Action
사용자가 핸드폰을 껐다켰을 때, 해당 배터리앱을 유저가 100% 실행 해줄것이다 라는것 세상에 없습니다.
부팅이 완료된 시점에 자동으로 노티피케이션을 띄우기 위해 Boot completed action 을 추가해줍니다.
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
여기까지 추가하면, Receiver 의 onReceive 메소드는 아래와 같이 처리를 하면 되겠죠.
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(Intent.ACTION_BOOT_COMPLETED.equals(action)) {
...
}
else if(Intent.ACTION_BATTERY_CHANGED.equals(action)) {
...
}
else if(Intent.ACTION_POWER_CONNECTED.equals(action)) {
...
}
else if(Intent.ACTION_POWER_DISCONNECTED.equals(action)) {
...
}
}
Receiver 를 동작한다거나, Service 를 실행시킨다거나, Battery 정보를 Receiver 에서 꺼낸다거나, Notification 을 띄운다거나 하는 건, 구글링만 해도 많이 여러 참고 자료들이 많이 나오므로, 자세한 코드들은 생략합니다.
제가 만들었던 앱의 전체적인 늬앙스 위주로 설명이 됐네요.
그럼 수고하세요~
'Android > Samples & Tips' 카테고리의 다른 글
java.lang.NoClassDefFoundError (1) | 2013.05.30 |
---|---|
[ICS] 안드로이드 ICS AVD 생성 실패!!!!!!! (2) | 2012.03.15 |
[Android] MediaRecorder error - Front Camera: start failed: -16 (1) | 2012.01.17 |
[Android-Tip] Reference(레퍼런스)란? (0) | 2011.12.22 |
[Android tip] XML parser 성능비교 (0) | 2011.11.23 |