티스토리 뷰

앱위젯에서 어떠한 상태를 저장하기 위해서는 단순히 메모리(static 변수나 intent )를 이용해서는 안됩니다.
그 이유는 핸드폰이 꺼졌을 경우에는 메모리 변수들은 사라지고, 또한 static으로 선언된 메모리 변수는 위젯을 삭제하게 되면 그 시점에서 가장 우선순위가 낮은 프로세스로 이동하게 됩니다. 그렇게 되면 언제든지 OS에 의해 변수를 포함한 프로세스가 종료될 수 있게됩니다.

앱위젯의 설정을 저장하는 것은 여러가지가 있지만, 본 포스트에서는 SharedPreferences 를 이용하여 설정을 저장하고 불러올 수 있도록 하겠습니다.

만들어볼 예제.

 Configure Activity에서 정수값을 저장하고 위젯에서 보여준다. 그 후에,
 위젯에서 Configure Activity로 버튼을 눌러 이동하면, 정수값을 읽어서 변화시키고 저장 후 위젯에서 다시 변화된 값을 보여줄 수 있도록 한다.

앱위젯 버튼에 이벤트를 주는 기본적인 설정은 http://fallingstar.tistory.com/92 포스트를 참고해 주세요. 또한, 본 포스팅 글은 http://fallingstar.tistory.com/92 에서 만들었던 위젯을 이용하여 실습을 진행합니다.


먼저, 포스팅한 글의 코드가 지저분하여 예제파일을 올려드립니다. 실행시켜 보시고, 천천히 포스트와 코드를 참고하여 앱위젯에서 설정을 저장하고 읽어들이는 부분을 이해하실 수 있었으면 좋겠습니다.



1. SharedPreferences 로 정수값을 저장한다.
2. 위젯에서 읽은 후 업데이트 한다. -_ -..

1. SharedPreferences 로 정수값을 저장한다.

엑티비티 내에 어떠한 버튼이 클릭되면, 정수값을 저장하게 하려면, 다음과 같이 하면 된다.

public static final String STATE = "state"; //변수로 선언 후

//버튼 이벤트 안에서
btn.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
    
    //엑티비티에서 버튼이 클릭되면, 그 상태를 변경한다. 여기서는 기존에 저장되어있던 숫자 curPos를 읽어온 후 변경함.
    SharedPreferences pref = context.getSharedPreferences(STATE, Activity.MODE_PRIVATE);
       int curPos = pref.getInt(STATE, 0); //만약 파일에 STATE가 존재하지 않으면 기본으로 0을 가져온다.
 
// 위 2개 줄이 sharedPreferences 를 이용하여 값을 읽어오는 부분이고, 이 아래 부분은 값을 기록하는 부분임.

       Editor e = pref.edit();
       curPos++; //정수값을 변경시키고
       e.putInt(STATE, curPos); //값을 저장한다.
       e.commit(); //해줘야 기록이 된다.
    
      }
  });

생각외로 간단하네요.

2. 위젯에서 읽은 후 업데이트 한다. -_ -..

이게 생각외로 해줄것이 많다.

먼저, AndroidManifest.xml 파일에 사용자 정의 이벤트를 만들어 줘야 한다.

<receiver android:name=".ExampleAppWidgetProvider" >
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        <action android:name="com.ko.ExampleAppWidget.CLICK" /> //사용자 정의 이벤트 포함시키기
    </intent-filter>
    <meta-data android:name="android.appwidget.provider"
               android:resource="@xml/widget_info" />
</receiver>

다음으로, 프로바이더 함수에 Manifest.xml 파일에 추가했던 사용자 정의 이벤트를 선언해 준다.

private static final String CLICK_ACTION = "com.ko.ExampleAppWidget.CLICK";

세번째로, 프로바이더 함수의 onReciver()함수를 Override한다.

여기에서 이전에 엑티비티에서 저장한 정수값(설정값)을 curCount라는 변수로 불러오게 된다.

private int curCount = 0;

@Override
 public void onReceive(Context context, Intent intent)
 {
  if(CLICK_ACTION.equals(intent.getAction()))
  {
   //엑티비티에서 파일로 저장했던 값을 읽어온다.
   SharedPreferences pref = context.getSharedPreferences(ExampleActivity.STATE, Activity.MODE_PRIVATE);
   curCount = pref.getInt(ExampleActivity.STATE, 0);
   
   AppWidgetManager manager = AppWidgetManager.getInstance(context);
   //위젯을 업데이트 하기 위해 onUpdate 함수 호출함.
   this.onUpdate(context, manager, manager.getAppWidgetIds(new ComponentName(context, ExampleAppWidgetProvider.class)));
   
   return;
  }
  else
   super.onReceive(context, intent);
 }

//업데이트 함수는 첨부된 소스코드 참고해 주세요.

네번째, onReceive() 함수를 호출하기 위해, 엑티비티가 종료되기 직전 호출할 사용자 정의 함수를 프로바이더 클래스 안에 만든다. (static으로 만들어야 엑티비티 클래스 에서도 호출 가능하므로, static 함수로 만든다.)

저는 static void updateWidget(...) 을 만들겠습니다. 

//이 함수는 엑티비티 종료 직전 엑티비티 클래스에서 호출하며, 주 업무는 브로드캐스트 메시지인 "CLICK_ACTION" 을 전달한다.
엑티비티 클래스 내에서 XXXXProvider.updateWidget(...)을 호출하여 준다.

 static void updateWidget(Context context,
    AppWidgetManager appWidgetManager,
    int appWidgetId
    ){
     
     Intent intent = new Intent();
     intent.setAction(CLICK_ACTION); //사용자 정의 이벤트를 intent에 설정 후
     context.sendBroadcast(intent); //브로드캐스트로 날려버린다.
}

이렇게 이벤트 CLICK_ACTION을 날려주면, onReceive()에서 이벤트를 받아서 처리해주시면 됩니다. (처리는 위 세번째에서 이미 했지요 ^^;)

예제 파일을 잘 실행시켜 보시면 알 수 있습니다. 본 글들이 이해가 안되시면, 아니되옵니다. ㅠ_ㅠ

안드로이드 포스트를 꼼꼼히 다시 읽어주세요.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함