안드로이드 개발 질문/답변
(글 수 45,052)
안녕하세요. 구글링도 해보고 별에 별 곳을 다녀봤지만
그냥 추측성 단서만 얻고 확실한 정보를 찾지 못하여서 이렇게 글을 남깁니다.
현재 Widget을 만들고 있는데 get<Type>Extra() 를 통하여 값을 제대로 가져오질 못하네요.
제가 이해를 잘못 하고있는건지 아닌지 모르겠네요.
문제가 나는 영역은 Widget에서 각 버튼에 대해서 이벤트를 처리하고자 다음과 같이 구성하였습니다.
private static final String INTENT_EXTRA_CONTACT1_MSG = "contact_1_send_msg";
private static final String INTENT_EXTRA_CONTACT2_MSG = "contact_2_send_msg";
private static final String INTENT_EXTRA_CONTACT3_MSG = "contact_3_send_msg";
private static int[] getAppWidgetIds(Context context) {
try {
final AppWidgetManager gm = AppWidgetManager.getInstance(context);
ComponentName thisWidget = ComponentName( context, ContactListWidget.class );
return gm.getAppWidgetIds(thisWidget);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
onReceive()
{
...
if(action.equals(ACTION_CONTACT_MSG)) {
boolean[] isSelectContact = new boolean[3];
isSelectContact[0]= intent.getBooleanExtra(INTENT_EXTRA_CONTACT1_MSG, false);
Log.i(TAG,"onReceive, intent<INTENT_EXTRA_CONTACT1_MSG> : "+bundle.getBoolean(INTENT_EXTRA_CONTACT1_MSG));
isSelectContact[1]= bundle.getBoolean(INTENT_EXTRA_CONTACT2_MSG);
Log.i(TAG,"onReceive, intent<INTENT_EXTRA_CONTACT2_MSG> : "+bundle.getBoolean(INTENT_EXTRA_CONTACT2_MSG));
isSelectContact[2]= bundle.getBoolean(INTENT_EXTRA_CONTACT3_MSG);
Log.i(TAG,"onReceive, intent<INTENT_EXTRA_CONTACT3_MSG> : "+bundle.getBoolean(INTENT_EXTRA_CONTACT3_MSG));
if(isSelectContact[0] == true){
Toast.makeText(context, "Call Compose Message of 1st contact Activity", Toast.LENGTH_SHORT).show();
}
else if(isSelectContact[1] == true) {
Toast.makeText(context, "Call Compose Message of 2nd contact Activity", Toast.LENGTH_SHORT).show();
}
else if(isSelectContact[2] == true) {
Toast.makeText(context, "Call Compose Message of 3rd contact Activity", Toast.LENGTH_SHORT).show();
}
}
...
}
onUpdate()
{
PendingIntent pi;
Intent intent;
...
Uri data = Uri.withAppendedPath(Uri.parse(URI_SCHEME + URI_DATA), String.valueOf(widgetId));
Intent intent1 = new Intent(ACTION_CONTACT_MSG);
intent1.setData(data);
intent1.putExtra(INTENT_EXTRA_CONTACT1_MSG, true);
PendingIntent pi1 = PendingIntent.getBroadcast(context, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
rv.setOnClickPendingIntent(R.id.btn_Contact_1_Msg, pi1);
intent = new Intent(ACTION_CONTACT_MSG);
intent.setData(data);
intent.putExtra(INTENT_EXTRA_CONTACT2_MSG, true);
pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
rv.setOnClickPendingIntent(R.id.btn_Contact_2_Msg, pi);
intent = new Intent(ACTION_CONTACT_MSG);
intent.setData(data);
intent.putExtra(INTENT_EXTRA_CONTACT3_MSG, true);
pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
rv.setOnClickPendingIntent(R.id.btn_Contact_3_Msg, pi);
...
}
대충 안되는 부분만 코드를 옮겼습니다..
onReceive까지 호출이 되구요.
if문까지 들어옵니다.
문제는
getBooleanExtra()를 통해 key가
INTENT_EXTRA_CONTACT1_MSG
INTENT_EXTRA_CONTACT2_MSG
INTENT_EXTRA_CONTACT3_MSG
인 값들이 버튼 1을 2를 3을 터치해도 3번째만 true로 반환이 됩니다.
버튼이 적지 않아서 버튼마다 액션을 부여하기 싫어서 액션을 줄일 수 있으면 줄여보고자 저렇게 하였습니다.
액션을 한개만 사용해서 extra로 구분하려고 저렇게 코딩을 했는데
제가 뭘 잘못 이해한것일까요?
어떻게 하면 해결을 할 수 있을까요?
단지 버튼마다 모든 액션을 달리 부여하는 방법 밖에 없을까요?
아시는 분이 계시다면 꼭
저에게 해결책을 알려주시면 감사하겠습니다. ㅡㅜ
2010.08.03 17:33:37
rv.setOnClickPendingIntent(R.id.btn_Contact_1_Msg, pi1);
...
rv.setOnClickPendingIntent(R.id.btn_Contact_2_Msg, pi);
...
rv.setOnClickPendingIntent(R.id.btn_Contact_3_Msg, pi);
이런식이면 당연히 끝에것만 set이 되죠.. 그래서 마지막것만 오는거구요.
rv라는 객체가 뭔지는 모르지만 결론적으로 rv의 onClickPendingIntent는 마지막것만 적용되겠죠.
나머지는 엎어써서 무효화될거구요.
rv도 각기 rv1, rv2, rv3 이 있는 형태가 아닌지 궁금하군요.
...
rv.setOnClickPendingIntent(R.id.btn_Contact_2_Msg, pi);
...
rv.setOnClickPendingIntent(R.id.btn_Contact_3_Msg, pi);
이런식이면 당연히 끝에것만 set이 되죠.. 그래서 마지막것만 오는거구요.
rv라는 객체가 뭔지는 모르지만 결론적으로 rv의 onClickPendingIntent는 마지막것만 적용되겠죠.
나머지는 엎어써서 무효화될거구요.
rv도 각기 rv1, rv2, rv3 이 있는 형태가 아닌지 궁금하군요.
2010.08.03 18:11:26
답변 감사합니다. rv라는 변수는
RemoteView의 변수 입니다.
widget layout에 대한 View를 가져오기 위해 사용하는 변수 입니다.
아래와 같은 코드로 구성이 되어 있습니다.
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
...
final AppWidgetManager gm = AppWidgetManager.getInstance(context);
gm.updateAppWidget(widgetId, rv);
widget에서 각 UI에 대해 intent를 붙이거나, 리소스를 컨트롤 할 때 위와같이 특정 widget id에 대해 코드를 통하여 어떤 내용이 적용은 최종적으로 updateAppWidget으로 합니다만..
그런데 remote view를 각기 따로 가져와서 update 해야하나요???
2010.08.03 18:13:54
참고로 디버깅을 하였을 때
저 PendingIntent를 통하여 받은 intent에서는
mMap이 null로 날라 옵니다.
다른 Activity로 보내게 하는 PendingIntent
즉 예를 들면 Intent intent = new Intent(context, DetailActivity.class);
이렇게 하여 보내면
mMap이 구성이 되는것을 확인을 하였고
역시나 get<Type>Extra()라는 함수를 통하여 각 key에대한 값을 가져올 수 있었습니다.
widget에서는 왜 도통 안되는지... ㅡㅜ
2010.08.03 18:37:38
저기 추가로 PendingIntent변수도 각각 선언하여 시도해보았습니다만, 역시나 onReceive() 에서 받은 intent의 mMap이 구성되어 있지 않아서인지 무조건 3번째의 값만 true로 되네요
2010.08.03 18:46:42
Intent intent1 = new Intent(ACTION_CONTACT_MSG);
intent1.setData(data);
intent1.putExtra(INTENT_EXTRA_CONTACT1_MSG, true);
PendingIntent pi1 = PendingIntent.getBroadcast(context, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
rv.setOnClickPendingIntent(R.id.btn_Contact_1_Msg, pi1);
intent1.setData(data);
intent1.putExtra(INTENT_EXTRA_CONTACT1_MSG, true);
PendingIntent pi1 = PendingIntent.getBroadcast(context, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
rv.setOnClickPendingIntent(R.id.btn_Contact_1_Msg, pi1);
intent = new Intent(ACTION_CONTACT_MSG);
intent.setData(data);
intent.putExtra(INTENT_EXTRA_CONTACT2_MSG, true);
pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
rv.setOnClickPendingIntent(R.id.btn_Contact_2_Msg, pi);
intent.setData(data);
intent.putExtra(INTENT_EXTRA_CONTACT2_MSG, true);
pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
rv.setOnClickPendingIntent(R.id.btn_Contact_2_Msg, pi);
intent = new Intent(ACTION_CONTACT_MSG);
intent.setData(data);
intent.putExtra(INTENT_EXTRA_CONTACT3_MSG, true);
pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
rv.setOnClickPendingIntent(R.id.btn_Contact_3_Msg, pi);
intent.setData(data);
intent.putExtra(INTENT_EXTRA_CONTACT3_MSG, true);
pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
rv.setOnClickPendingIntent(R.id.btn_Contact_3_Msg, pi);
이 부분을 보면 rv는 전혀 변화가 없는데... 이럴 경우 rv라는 하나의 객체에 onClickPendingIntent는 오직 하나만 남겠죠...
set이라는건 통념적으로 하나를 지정하는 개념에 가까우니까요.
2010.08.03 19:11:12
아 오타가 있었네요 첫pi1이라는 변수는 다른곳에서 동일하게 사용하는 pi입니다.
제가 알기론 RemotrView객체에서setOnClickPendingIntent()를 통하여 각 ui id에 대해서 click 이벤트에 대항 pending intent를 지정하는것으로 알고 있고 마지막으로 AppWidgetManger의 updatAppWidget()을 통하여 RemoteView객체를 갖고 업데이트 하는 것이 흐름 으로 알고 있습니다
제가 전체코드를 올려 드리면 될까요?



