2011년 8월 2일 화요일

Android Service에서 AlertDialog 띄우기


Android Service에서 AlertDialog을 원칙적으로 띄울 수는 없다.
Dialog 형태의 Activity을 만들어 띄우는 편법을 사용해야 한다.

Step 1. AlertDialog Activity 정의, theme을 "Theme.Dialog”로 정의해서 PopUp 형태를 취할 수 있게 한다.
<activity
android:name=".AlertDialogActivity"
android:theme="@android:style/Theme.Dialog">
<intent-filter>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

Step 2. AlertDialog Layout “alertdialog.xml”, 원하는 형태의 Dialog Layout을 작성한다.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">

<ImageView
android:id="@+id/imgView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/notification_icon"
android:layout_centerHorizontal="true" />

<ScrollView
android:id="@+id/ScrollView01"
android:layout_width="wrap_content"
android:layout_below="@id/imgView"
android:layout_height="200px">

<TextView
android:text=""
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</ScrollView>

<Button
android:id="@+id/submit"
android:layout_below="@id/ScrollView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="Cancel" />

</RelativeLayout>

Step 3. AlertDialog Activity, notiMessage을 Service로 부터 전달 받게 된다. Button을 클릭하면 Dialog 창을 닫을 수 있게 Activity를 finish 해준다.

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;

public class AlertDialogActivity extends Activity {

private String notiMessage;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
Bundle bun = getIntent().getExtras();
notiMessage = bun.getString("notiMessage");


setContentView(R.layout.alertdialog);

TextView adMessage = (TextView)findViewById(R.id.message);
adMessage.setText(notiMessage);

Button adButton = (Button)findViewById(R.id.submit);

adButton.setOnClickListener(new SubmitOnClickListener());


}
private class SubmitOnClickListener implements OnClickListener {

public void onClick(View v) {
finish();

}
}
}

Step 4. Service에서 AlertDialog 띄우기, intent 전달은 PendingIntent를 사용해야 한다.

Bundle bun = new Bundle();
bun.putString("notiMessage", text);

Intent popupIntent = new Intent(getApplicationContext(), AlertDialogActivity.class);

popupIntent.putExtras(bun);
PendingIntent pie= PendingIntent.getActivity(getApplicationContext(), 0, popupIntent, PendingIntent.FLAG_ONE_SHOT);
try {
pie.send();
} catch (CanceledException e) {
LogUtil.degug(e.getMessage());
}

댓글 11개:

  1. 서비스에서 다이얼로그 띄우는 게 원칙적으로 불가능한 일이었군요. 잘 보고 갑니다~

    답글삭제
  2. 감사합니다~ 덕분에 문제 해결했습니다^^

    답글삭제
  3. 작성자가 댓글을 삭제했습니다.

    답글삭제
    답글
    1. 찾아서 드리고 싶은데.. 소스를 찾아봤는데 없네요. 죄송합니다.^^

      삭제
    2. 작성자가 댓글을 삭제했습니다.

      삭제
    3. 작성자가 댓글을 삭제했습니다.

      삭제
    4. Step 4번의 코드는 GCM의 PUSH을 받는 BroadcastReceiver을 구현한 클래스의 "handleMessage" operation에 들어갑니다.

      실제 사용된 코드
      private void handleMessage(Context context, Intent intent) {
      Log.d(this.getClass().getSimpleName(), "handleMessage");
      String msg = intent.getStringExtra("msg");
      showNotification(context, "알리미", msg);
      }

      private void showNotification(Context context, String title, String message) {
      NotificationManager notiManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

      Notification n = new Notification();

      n.flags |= Notification.FLAG_SHOW_LIGHTS;
      n.flags |= Notification.FLAG_AUTO_CANCEL;
      n.defaults = Notification.DEFAULT_ALL;
      n.icon = R.drawable.notify;
      n.when = System.currentTimeMillis();

      Bundle bun = new Bundle();
      bun.putString("entryPath", "push");

      Intent intent = new Intent();
      intent.putExtras(bun);
      intent.setClass(context,LoginActivity.class);
      PendingIntent pi = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
      n.setLatestEventInfo(context, title, message, pi);

      notiManager.notify(0, n);

      Bundle bune = new Bundle();
      bune.putString("notiMessage", message);

      Intent popupIntent = new Intent(context, AlertDialogActivity.class);

      popupIntent.putExtras(bune);
      PendingIntent pie= PendingIntent.getActivity(context, 0, popupIntent, PendingIntent.FLAG_ONE_SHOT);
      try {
      pie.send();
      } catch (CanceledException e) {
      Log.d(this.getClass().getSimpleName(), e.getMessage());
      }
      }

      삭제
  4. TelephonyManager.CALL_STATE_OFFHOOK 상태에서 alertDialog를 띄우고 싶은데 혹시 가능한 방법이 없을 까요?

    답글삭제
    답글
    1. 내용을 정확히는 모르겠지만요. 제 글 http://daddycat.blogspot.kr/2011/05/android-broadcastreceiver-event-catch.html 을 보시면 참고가 될것 같습니다.

      삭제
  5. 좋은정보 감사히 보구 갑니다 ^^ 하나 궁금한게 있는데요, 저렇게 dialog형식의 activity를 띄우게 되면 다른 activity들의 동작은 자동적으로 onpaus상태로 넘어가게 되나요?

    답글삭제
  6. 큰 도움 되었습니다. 정말 감사합니다~~!!

    답글삭제

ETL 솔루션 환경

ETL 솔루션 환경 하둡은 대용량 데이터를 값싸고 빠르게 분석할 수 있는 길을 만들어줬다. 통계분석 엔진인 “R”역시 하둡 못지 않게 관심을 받고 있다. 빅데이터 역시 데이터라는 점을 볼때 분산처리와 분석 그 이전에 데이터 품질 등 데이...