«   2024/12   »
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
Tags
more
Archives
Today
Total
관리 메뉴

올해는 머신러닝이다.

꺼진화면에서 알림창 띄우기 본문

Android/General

꺼진화면에서 알림창 띄우기

행복한 수지아빠 2015. 2. 4. 20:35

카톡 스타일의, 화면 꺼진 상태에서도 푸시가 오면 알림창을 띄우는 기능을 구현해야 했다. 

처리 절차는 다음과 같다.

1. 푸시를 받았는데 화면이 꺼져있다면
2. 락 스크린 위로(!) 특정 액티비티를 실행한다.
3. 이 액티비티에서 원하는 액션을 수행한다. (대게 '보러가기' / '닫기' 수준이겠지)

1번에선 화면이 꺼져있는지 여부를 확인해야 하고, 이는 다음과 같이 확인할 수 있다.


public static boolean isScreenOn(Context context) {
return ((PowerManager)context.getSystemService(Context.POWER_SERVICE)).isScreenOn();
}

2. 락 스크린 위로 액티비티를 보여주기 위해선 보여줄 액티비티가 full screen 이어야 하며, 다음과 같은 window 세팅을 해 줘야 한다. onCreate() 메서드에 넣어두면 된다.

getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);

맨 위의 dismiss keyguard 는 락 까지 해제하겠다는 것인데, 몇 번 테스트 해 보니 일반적인 상황에선 락 화면을 없애지 못했다. 굳이 제거 안되는 락 스크린까지 걷어낼 필요가 없어 그냥 넘어가고.

3번은 case by case 이니 딱히 언급할 필요가 없고.

그런데 내 경우에 화면 표시까진 잘 되었는데, 몇 가지 요상한 문제가 발생했다.

1. recent app 목록에서 앱을 선택하면 원래 앱 화면이 아닌, 저 팝업 화면이 튀어나왔다.
2. 그래서 저 팝업 화면에다 android:excludeFromRecents="true" 를 설정했더니 아얘 recent app 목록에서 사라졌다.

앱을 만들면서 task를 새로 만들어본 적이 한번도 없었는데, push를 받아 activity를 생성할 때 newTask 를 붙여놨다지만 이 pushPopup 과 원래 앱의 taskAffinity 가 동일하다면 (별도로 설정을 하지 않는 이상 동일하다) 실제론 task가 새로 생기지 않으며, 아마도 처음 task를 실행한 pushPopup에서 android:excludeFromRecents 가 true 로 되어 있어 recent 목록에서도 날아간 듯 하다.

해결은

1. pushPopup 액티비티에 별도의 taskAffinity 를 주고,
2. pushPopup 액티비티는 android:excludeFromRecents="true" 를 명시했으며
3. pushPopup 을 띄울 때나, 이 액티비티가 원래의 앱을 호출할 때 모두 Intent.FLAG_ACTIVITY_NEW_TASK 플래그를 달아줬다.

이렇게 하니
1. recent 목록에서 원래 앱이 날아가는 문제도 없고
2. recent 목록의 항목을 선택하면 원래 앱의 원래 화면으로 잘 찾아들어갔다.

* activity 정의

<activity 
android:name=".activity.PushPopup_"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:excludeFromRecents="true"
android:taskAffinity="{my_pkg_name}.popup"/>* 화면 꺼졌을 때 activity 호출


if (!Util.isScreenOn(context)) {
context.startActivity( new Intent(context, PushPopup_.class).putExtra( blah blah).setFlags( Intent.FLAG_ACTIVITY_NEW_TASK));
}

* popup activity 의 oncreate에서 flag 설정

getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
1
김윤중님의 프로필 사진이줭님의 프로필 사진김미혜님의 프로필 사진Sewon Ann님의 프로필 사진
댓글 16
김윤중
2013. 8. 13.
 
 
안녕하세요. 안드로이드 공부하는 학생입니다. 중복으로 푸쉬를 보내면 맨처음 푸쉬창을 사용자가 없애지 않으면 다음 푸쉬가 안보내지는데, 중복푸쉬를 가능하게 하는 방법이 있나요?
Sewon Ann
2013. 8. 13.
 
 
+김윤중  안녕하세요. 제가 이 글을 쓴 지 너무 오래되어 저도 기억이 잘 안나는데, 푸시창이라고 하신게 화면 꺼짐상태의 창을 말씀하신거지요? 이 경우 제일 좋은 방법은 이미 열려있는 화면 꺼짐 창의 내용을 갱신하는 것입니다. 메서드가 잘 기억이 나진 않는데 현재 알림 창이 떠 있는지 확인하고, 떠 있다면 액티비티의 내용을 갱신하기 위해 broadcast 를 날리던지 intent를 날리던지 하는 방식으로 처리할 수 있을거에요. 저도 그렇게 했던 것 같구요.
김윤중
2013. 8. 13.
 
 
빠른 답변 감사합니다!! 네 맞습니다. 화면이 꺼진상태에서 푸시가 날라오면 알림창을 보여주는 것이죠. 하지만 연속으로 푸시를 보내면 첫번째 푸시만 알림창으로 나오고 다음 푸시는 나오지 않는 문제가 있는데 그 문제를 해결 못하고 있습니다ㅠ
Sewon Ann
2013. 8. 13.
 
 
+김윤중 제 경우엔 푸시팝업 화면을 singleTop인가 singleInstance로 띄우고, 여기에 intent를 다시 보냈던 것 같아요. 이 때 푸시팝업 activity는 onNewIntent() 로 새 인텐트를 받게 되고, 이 메서드안에서 내용을 갱신하도록 구현했습니다.
김윤중
2013. 8. 13.
 
 
우와!! 감사합니다! +Sewon Ann 님 말씀대로 하니까 푸쉬팝업이 연속적으로 꺼진상태에서 작동하긴 하나 아쉽게도 출력되는 데이터 값이 이전 데이터가 찍히는 상황이 벌어지네요. 아무래도 onNewIntent()에서 값을 제대로 받아 오지 못하는 것 같습니다.ㅠㅠ;;
Sewon Ann
2013. 8. 13.
 
 
@김윤중아마도 getIntent() 로 데이터를 가져오신 것 같은데 onNewIntent() 의 parameter로 넘어온 intent 값을 사용하셔야 해요. getIntent() 를 쓰시고 싶다면 onNewIntent() 안에서 새로 넘어온 intent 객체를 setIntent() 로 설정해서 사용하시면 되지 싶습니다. 도움이 되시길 :-)
김윤중
2013. 8. 13.
+
1
2
1
 
 
+Sewon Ann  감사합니다. 도움되었습니다! 정말정말 감사합니다!!! 와 감동의 눈물이 ㅠㅠㅠㅠㅠ 삼일 해매던걸 여기와서 한퀴에 해결했네요 ㅠㅠ 너무 감사합니다.
김윤중
2013. 8. 13.
 
 
으아!! 너무 감사드립니다 ^_^ 앞으로 종종 찾아뵐께요 !!
이줭
2013. 10. 31.
 
 
안녕하세요~ 저는 폰이 sleep mode로 넘어간뒤 일정 지나면 푸쉬를 보내도 onReceive() 에 들어오지 않는데요... 혹시 방법 아시나요?ㅜㅜ , 폰이 활성->슬립모드로 들어가자마자 푸쉬를 보내면 onReceive()에 들어와서 화면을 깨우고 팝업을 보여줍니다.
Sewon Ann
2013. 10. 31.
 
 
+이주영  아마도 서버에서 푸시를 보낼 때 delay_while_idle 속성을 true로 해 두셨을거에요. 이걸 true로 해 두면 첫번째 푸시는  receive로 들어오지만, 이 때 바로 폰은 "아, 나는 이제 자는 상태니 푸시 보내지마" 상태로 접어들기 때문에  이후 푸시가 화면 켜야 들어옵니다. 그래서 일단 delay_while_idle 를 확인해보시는 게 좋을겁니다. false 여야 자고 있는 상태에서도 깨우는 처리가 될 거에요. 

http://developer.android.com/google/gcm/server.html
이줭
2013. 10. 31.
 
 
우와!! 감사합니다 ㅜㅜ 몇일째 헤매던건데 바로 해결해주셨어요!!댓글도 바로 달아주시구!!!! 두번 감사해요ㅎㅎㅎ 
Sewon Ann
2013. 10. 31.
 
 
+이졍 네, 저도 이것때문에 한참 고생을 했어서 마침 기억을 하고 있었네요.
김미혜
2014. 3. 15.
 
 
gcm 서버로부터 메시지를 받기는 합니다. 화면이 꺼져있을때 깨우면서 최상위로 activity를 띄우게 하고 싶은데요. 2번대로는 해봤는데 1번이 없어서그런지 안되더라구요.
Sewon Ann
2014. 3. 15.
 
 
+김미혜 깨우는 게 문제라면 wake lock 쪽을 살펴보시면 될 것 같네요