아래의 글은 이메일로 문의를 준 학생들에게 대답해줬던(사실 방금..) 내용입니다.
배터리 관련 내용들은 여기저기 많으므로 별로 필요없을거라고 생각하긴 하지만, 그래도 블로그에는 적어두려고 옮깁니다. (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 을 띄운다거나 하는 건, 구글링만 해도 많이 여러 참고 자료들이 많이 나오므로, 자세한 코드들은 생략합니다.

제가 만들었던 앱의 전체적인 늬앙스 위주로 설명이 됐네요.
그럼 수고하세요~


Posted by croute

댓글을 달아 주세요