[android] GCM (2) – 클라이언트 만들기

[android] GCM (2) – 클라이언트 만들기

Android Studio에서는 이렇게 해야한다.

 

 
이전 글에서 이어짐

 

Google Play Service 연결하기

  1. 이클립스 – Windows – Android SDK Manager 를 연다.
  2. 목록의 제일 아래쪽에 Goole Play Services 선택한다.
  3. 오른쪽 아래의 Install 버튼을 누른다.
  4. 설치가 끝나면 이클립스의 프로젝트 목록에서 오른쪽 클릭해서 import 메뉴를 선택하고,{sdk}/extras/google/google_play_services/ 를 선택한다.
  5. 작성할 프로젝트의 오른쪽 클릭 메뉴 – properties – Android – Library – Add… 버튼을 누른다.
  6. google-play-services_lib 를 선택한다.
    스크린샷 2014-01-13 오후 5.22.01

 

Manifest 편집

kr.mint.testgcm 이라고 적힌 부분은 실제 패키지 경로로 바꿔야 함.

 

MainActivity 편집

http://developer.android.com/google/gcm/client.html#sample-register  의 소스를 살짝 바꿨다.

 

 Received Message

예전에는 브로드캐스트 리시버에서 다 했던 것 같은데, 구글에서 가이드 해줬으니 그거 따라해야지….

 

 

Show in Notification bar

노티바에 표시하면서 0.5초 동안 진동하고, 클릭하면 메인화면으로 가는 거 추가

 

Preference

그냥 구글 소스대로 해놓고 글 작성할 걸 괜히 리팩토링해가지고 불편하게 됐네 ;;;

 

 

Registration ID 복사해두기

정상적으로 등록이 됐다면 logcat 에 RegID가 나올텐데, 이걸 복사해뒀다가 송신 서버 만들 때 쓰자.

 

 

Error – SERVICE_NOT_AVAILABLE

도움받은 곳 : http://aroundck.tistory.com/2353

이런 에러가 나오면 다른 방법으로 regId를 받아와야한다.

menifest.xml 에 저 부분을 추가하면 broadcast receiver에서 regId를 받아올 수 있다.

preference에 저장하는 부분을 여기서 하면 된다.

 

예제소스

https://github.com/susemi99/GCM-client-sample

  • Pingback: ()

  • 초짜프로그래머

    {sdk}/extras/google/google_play_services/이거어케하는지ㅠㅠㅠ
    아직초짜라 잘모르겟어요ㅠㅠㅠ

    • 쎄미

      안드로이드 개발하려면 sdk를 연결해야하는건 아시죠?
      그 폴더에 가보면 저 경로에 google_play_services 라는 폴더가 있는데, 그 폴더를 import 하세요

  • 초짜프로그래머

    {sdk}/extras/google/google_play_services/
    저거임포트햇는데
    properties – Android – Library – Add에서
    google-play-services_lib이안뜨는데 어케해야하죠??ㅠㅠ

    • 쎄미

      제대로 add 가 됐는지, google_play_services 의 Library의 Is Library에 체크가 되어있는지, 프로젝트가 닫혀있지 않는지 확인해보세요

  • 스마트율

    정말 세심한 예제로 잘 보고 갑니다..^^
    감사합니다…

    • 쎄미

      ^^

  • 엘희v

    Can’t redirect to app settings for google play services 이렇게 에러가뜨는 데 왜그러는걸까요 .ㅠㅠ

    • 쎄미

      음….차근차근 처음부터 다시 해보세요 ;;

      • 엘희v

        여기나와있는소스를 그냥 다 복사붙여넣기해서 돌려보려면 수정해야되는부분이 어디어디인가요?;

        • 쎄미

          kr.mint.testgcm 이런거 밖에 안 보이네요
          sdk매니저에서 구글 플레이 서비스도 업데이트도 해보시구요

  • 좋은 글 감사합니다. 이전 gcm.jar를 사용하던 버전과 다른 점이라면 안드로이드 키도 생성하는 부분인 것같습니다. 이 안드로이드 키를 어디서 사용하는지 소스상에도 나와있지 않은것같은데 어디서 사용하는 것인가요?

    • 구글사이트에서 만드는 api key를 말씀하시는 건가요? 기억은 안나는데, 그게없으면 메시지를 못받을겁니다. 아마 해당 패키지이름을 쓰는 앱만 받게돼있는 것 같아요

  • Pingback: ()

  • 궁금해요

    서버가 없이 앱에서 컨트롤이 가능한건가요..?

    • 쎄미

      어떤 서버를 말씀하시는건가요?

  • 전종호

    되는지 테스트 해볼라면 서버를 만들어 봐야 겠네요?
    감사합니다. 임포트 하는거 구글맵 쓰면서 해봤는데 이상하게 에러나서 에러 잡아볼라고 코쟁이들 질문 답 까지 찾아가면서 1시간 헤메다 짜증나서 지우고 다시 했는데 되네요 ㅋ

  • JackR

    클라이언트만 작성하여 실행하여 로그캣에 RegID가 나오나요???

    • 쎄미

      네(구글 콘솔 작업을 했다면요)

  • 알렉스

    쎄미님 안녕하세요 : )
    클량 자당 알렉스입니다. ㅋㅋㅋㅋㅋㅋㅋ

    어찌어찌 검색하다보니 쎄미님 글까지 왔네요;

    지금 구글에서제공하는 기본 소스 gcm.jar 를 이용해서 gcm을 구현해놓았는데…
    포스팅하신 이것과 다른건지 궁금해서 여쭤보려구요.

    gcm에서 간혹 특정 디바이스에서 registrationId를 수집해오지 못할때가 있어서…
    혹, 쎄미님께서 포스팅하신 방법으로 하면 될까 하고 해보려고 합니다.

    • 쎄미

      안녕하세요~
      구글에서 플레이서비스로 자꾸 끌어들이고 있으니 아마 저게 최신 버전일거예요 ㅎㅎ
      예제소스 있으니까 한 번 해보시면 되지 않을까요?

      • 알렉스

        감사합니다!
        이걸로 하니까 되네요…휴;;;
        String regId = GCMRegistrar.getRegistrationId(_context);
        으로 안되던게 Google Play Service로 하니까 되는군요… 세미님 덕분에 잘 해결했습니다 ㅎㅎ
        다음에 뵈면 맛있는 쪼꼬바 사드릴께요~ ㅎㅎㅎ

        • 쎄미

          네 ㅎㅎ 양갱도 좋아합니다 ㅎㅎ

  • Pingback: ()

  • 초보자

    저… 서버단으로 연결하는 부분이 없는거 같아요 머 서버를 루비로 사용하고 계시는거 같은데 ..;;

    키값이랑 이런걸 어떻게 넘기신건지가 궁금합니다

    • 쎄미

      이 예제는 수신기능만 있습니다.
      실제로 사용하려면 key를 서버로 보내서 저장하게 하는 등의 작업이 필요합니다.
      (서버로 보내는 작업은 http reqest 로 보내면 됩니다)

      • 타롱

        안녕하세요. 죄송합니다만 key를 서버로 보낼때 서버가 어떤 url을 가지고 있는지 예시라도 알 수 없을까요 ㅠ.. 감이안오네요..

        • 쎄미

          서버는 123.123.234.234 같은 아이피를 사용하거나, xxx.co.kr 같은 도메인을 사용합니다.

  • J

    안녕하세요 죄송하지만 클라이언트를 만들려고 하는데 위에 google play services를 설치 후 import를 했는데 8개 폴더중 5개 폴더에서 전부다 오류가 뜨는데 오류 내용은 Unable to resolve target ‘android-9’ 이것입니다. 구글에 찾아서 해봤는데 도저히 안나오는데 좀 알려주실수 있으세요? ㅜ

    • 쎄미

      sdk 매니저에서 9에 해당하는 sdk를 다운받으세요.
      근데 요즘 세상에는 최소 16정도로 맞춰주는게 좋아요

  • 최인영

    안드로이드 푸시 알림 구현을 알아보다 보게되었습니다!
    근데 MainActivity에서 _textStatus = (TextView) findViewById(R.id.textView1); 여기 textView1은 무엇인지 궁금합니다.
    textView1 여기만 오류가 나네요.

    • 최인영

      아 해결되었습니다 ㅎㅎ
      큰 도움이 됐습니다!

      • 쎄미

        다행입니다 ㅎㅎ

    • 이민호

      어떻게 해결하셨나요? 해결책부탁드립니다 ^^

  • 이성하

    C:UsersLeeSeongHaAppDataLocalAndroidandroid-sdkextrasgooglegoogle_play_services/

    왜 IMPORT가 안되는걸까요 …폴더도 있고 안에 jar도 있는데…ㅠㅠ
    그냥 Existing Projects into Workspace로해서 sdk 설치경로에 extras ~ 하는거 맞죠??

    그리고 혹시 extras에서 구글 플레이 서비스말고 다른거 다운 받아야 하는거 있나요???gcm 할때요

    • google_play_services-lib 이라는 폴더를 선택을 안하고 상위 폴더를 선택했다거나 하지는 않았겠죠?
      맥에서는 저렇게만 하면 되는데 이상하네요 ;;;

  • 이정민

    registration id는 한번밖에 못받아오나요 다시 실행하면 비어있네요..

    • getRegistrationId() 에서 null 체크를 해서는 아니고요? 아무튼 처음 받아오면 저장해두고 쓰는걸로 하세요

  • 이민호

    자료감사합니다.~

    private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;

    private static final String SENDER_ID = “”;

    PLAY_SERVICES_RESOLUTION_REQUEST와 SENDER_ID가 의미하는게 무엇인가요? sender id가 프로젝트 넘버인가요?

    그리고 최인영님이 스스로 해결하신 textView1에서 오류가 나네요. 혹시 해결 방법이 있나요?

    • sender_id는 개발자 콘솔 화면에 저거 비슷하게 나오는 그거 쓰면 됩니다.
      PLAY_SERVICES_RESOLUTION_REQUEST는 아무 고유 숫자 적으시고요.

      완전 자세한 정보는 구글링 하면 됩니다.

    • 그리고 프로그래머라면 오류가 났을 때 오류 로그를 올려주는 건 기본 예의겠죠?

      • 이민호

        아 죄송합니다.
        textview1 cannot be resolved or is not a field.
        이클립스 환경해서 하고 있습니다. textview1에 저런 경고문구와 함께 Run이 되지 않네요.

      • 이민호

        layout에 변수를 추가해주니 잘 해결되었습니다. 다음부터 질문할 때는 생각을 좀더하고 질문하도록 하겠습니다.

  • 이민호

    06-03 01:30:34.668: E/AndroidRuntime(18937): FATAL EXCEPTION: main

    06-03 01:30:34.668: E/AndroidRuntime(18937): Process: com.example.gcm4, PID: 18937

    06-03 01:30:34.668: E/AndroidRuntime(18937): java.lang.RuntimeException: Unable to instantiate receiver com.example.gcm4.receiver.GcmBroadcastReceiver: java.lang.ClassNotFoundException: Didn’t find class “com.example.gcm4.receiver.GcmBroadcastReceiver” on path: DexPathList[[zip file “/data/app/com.example.gcm4-1.apk”],nativeLibraryDirectories=[/data/app-lib/com.example.gcm4-1, /vendor/lib, /system/lib]]

    06-03 01:30:34.668: E/AndroidRuntime(18937): at android.app.ActivityThread.handleReceiver(ActivityThread.java:2417)

    06-03 01:30:34.668: E/AndroidRuntime(18937): at android.app.ActivityThread.access$1700(ActivityThread.java:139)

    06-03 01:30:34.668: E/AndroidRuntime(18937): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1276)

    06-03 01:30:34.668: E/AndroidRuntime(18937): at android.os.Handler.dispatchMessage(Handler.java:102)

    06-03 01:30:34.668: E/AndroidRuntime(18937): at android.os.Looper.loop(Looper.java:136)

    06-03 01:30:34.668: E/AndroidRuntime(18937): at android.app.ActivityThread.main(ActivityThread.java:5129)

    06-03 01:30:34.668: E/AndroidRuntime(18937): at java.lang.reflect.Method.invokeNative(Native Method)

    06-03 01:30:34.668: E/AndroidRuntime(18937): at java.lang.reflect.Method.invoke(Method.java:515)

    06-03 01:30:34.668: E/AndroidRuntime(18937): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)

    06-03 01:30:34.668: E/AndroidRuntime(18937): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:606)

    06-03 01:30:34.668: E/AndroidRuntime(18937): at dalvik.system.NativeStart.main(Native Method)

    06-03 01:30:34.668: E/AndroidRuntime(18937): Caused by: java.lang.ClassNotFoundException: Didn’t find class “com.example.gcm4.receiver.GcmBroadcastReceiver” on path: DexPathList[[zip file “/data/app/com.example.gcm4-1.apk”],nativeLibraryDirectories=[/data/app-lib/com.example.gcm4-1, /vendor/lib, /system/lib]]

    06-03 01:30:34.668: E/AndroidRuntime(18937): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)

    06-03 01:30:34.668: E/AndroidRuntime(18937): at java.lang.ClassLoader.loadClass(ClassLoader.java:497)

    06-03 01:30:34.668: E/AndroidRuntime(18937): at java.lang.ClassLoader.loadClass(ClassLoader.java:457)

    06-03 01:30:34.668: E/AndroidRuntime(18937): at android.app.ActivityThread.handleReceiver(ActivityThread.java:2412)

    06-03 01:30:34.668: E/AndroidRuntime(18937): … 10 more

    질문하나만 더 드리겠습니다. 실행하고 나서 몇 초 뒤에 예상치 못하게 앱이 종료됩니다.
    ID는 잘 가져옵니다. 무엇이 문제일까요?

    • 질문할 때 불필요한 부분을 줄이는 것도 능력입니다. 프로그래머 생활을 계속 할거라면, 앞으로도 질문을 많이 하게 될텐데, 부디 답변해줄 사람이 읽기에 가장 좋은 방법의 질문을 해주시기 바랍니다.

      java.lang.RuntimeException: Unable to instantiate receiver com.example.gcm4.receiver.GcmBroadcastReceiver: java.lang.ClassNotFoundException: Didn’t find class “com.example.gcm4.receiver.GcmBroadcastReceiver” on path: DexPathList[[zip file “/data/app/com.example.gcm4-1.apk”],nativeLibraryDirectories=[/data/app-lib/com.example.gcm4-1, /vendor/lib, /system/lib]]

      at android.app.ActivityThread.handleReceiver(ActivityThread.java:2417)
      at android.app.ActivityThread.access$1700(ActivityThread.java:139)
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1276)
      at android.os.Handler.dispatchMessage(Handler.java:102)
      at android.os.Looper.loop(Looper.java:136)
      at android.app.ActivityThread.main(ActivityThread.java:5129)
      at java.lang.reflect.Method.invokeNative(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:515)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:606)
      at dalvik.system.NativeStart.main(Native Method)
      Caused by: java.lang.ClassNotFoundException: Didn’t find class “com.example.gcm4.receiver.GcmBroadcastReceiver” on path: DexPathList[[zip file “/data/app/com.example.gcm4-1.apk”],nativeLibraryDirectories=[/data/app-lib/com.example.gcm4-1, /vendor/lib, /system/lib]]
      at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
      at android.app.ActivityThread.handleReceiver(ActivityThread.java:2412)
      … 10 more

      ======================================================
      Caused by: java.lang.ClassNotFoundException: Didn’t find class “com.example.gcm4.receiver.GcmBroadcastReceiver”

      굳이 설명 안해줘도 원인을 찾을 수 있을거라 생각합니다.

  • 방준서

    안녕하세요. 강좌 잘 봤습니다. 그런데 이게 센더에서 전송과 리시버(앱)에서는 GCM이 잘 되는거 같은데 막상 받으면 앱이 센더로 부터 받은 내용을 잘 해석을 못하는거 같네요.. 로그켓 내용입니다.

    06-11 10:45:58.500 14068-15218/com.junseo.myunginnotice I/GcmIntentService.java | onHandleIntent﹕ Received: Bundle[{from=916827838305, android.support.content.wakelockid=4, 테스트 Key=테스트 Value, collapse_key=do_not_collapse}]

    • 센더에서 msg 라는 키에 아무 내용이나 넣어서 보내보세요

  • 나는그네

    안녕하세요 쎄미님
    쎄미님의 https://github.com/susemi99/GCM-client-sample 에 올라온걸 그대로 프로젝트로 만들어서 작업을 하는데

    [2015-07-06 14:30:18 – testgcm] Android Launch!
    [2015-07-06 14:30:18 – testgcm] adb is running normally.
    [2015-07-06 14:30:18 – testgcm] Performing kr.mint.testgcm.MainActivity activity launch
    [2015-07-06 14:30:19 – testgcm] Automatic Target Mode: using device ‘LGF470K5c5a834b’
    [2015-07-06 14:30:19 – testgcm] Uploading testgcm.apk onto device ‘LGF470K5c5a834b’
    [2015-07-06 14:30:20 – testgcm] Installing testgcm.apk…
    [2015-07-06 14:30:22 – testgcm] Installation error: INSTALL_PARSE_FAILED_MANIFEST_MALFORMED
    [2015-07-06 14:30:22 – testgcm] Please check logcat output for more details.
    [2015-07-06 14:30:22 – testgcm] Launch canceled!

    요런 메세지가 뜨네요 로그캣을 봤더니 뭐 아무것도 없구요

    검색해보니 메니페스트 파일에 문제가 있거나 패키지명에 대문자를 빼라는데 음
    딱히 문제 될것은 없어보이는데 시간되시면 답글 한번만 달아주세요

    감사합니다.

    • 나는그네

      앗 자문자답이군요

      요부분에서 “@integer/google_play_services_version” 관련해서 에러가 떠서 삭제를 했는데

      이부분에 적당한 숫자를 쓰니 해당 문제는 지나갔는데
      뭔가 맞지 않는 숫자 인가봐요 에러로그 봐서 거기에 뜨는 숫자를 입력하니 해결되네요

      • 그 숫자는 항상 최신버전의 숫자가 돼야해요 ㅎㅎ
        잘 해결됐다니 다행입니다.

  • 진진구

    dd

  • 정주

    안녕하세요 ㅎㅎ

    글 보며 많은 진전이 있었습니다.

    현재 레일즈서버의 웹페이지를 웹뷰로 보여주는 앱을 만들고있습니다. 여기에 푸쉬알림기능을 넣을려고합니다.

    앱실행시 regist_id를 받아오고 레일즈서버에서 api_key와 regist_id, message를 보내면 디바이스에 푸쉬알림이 날아오는것까진

    완성이되었는데, 앱실행시 받아온 regist_id를 레일즈서버로 보내 db로 저장하는 부분에서 막혀있습니다.

    어떤방법으로 regist_id를 레일즈서버로 보낼수있는지궁금합니다….ㅠ 레일즈 서버의 작업하고자하는 특정url에 id를직접 파라터미로 던져주는방법밖엔 없나요??

    • restful이나 http post 같은 걸로 검색하세요. 레일스는 기본적으로 create를 주기 때문에 그거에 맞춰서 주면 되지 싶네요

  • 사탕이좋아

    안녕하세요 세미님
    세미님의 글을보면서 push 서버를 하고있는데 클라이언트는 문제없이 작동이 되는거 같습니다.
    그런데 https://gcmsender.herokuapp.com/ 이곳에서 메세지를 전송을 하였는데 757: unexpected token at ‘~~~’ 가 result창에 뜨면서 알람이 안오던데 혹시 보시면 답글 좀 부탁드립니다.

    • 거기에 입력하는 json 포맷이 맞는지 확인하세요