본문 바로가기

ANDROID의 속삭임

[android][googlePlayService]google GCM Push Message.

- 푸쉬 예제소스는 두개의 프로젝트로 나뉜다. 하나는 서버단이고, 하나는 디바이스에서 작동하는 클라이언트 단.





* 클라이언트 소스

- 필요 라이브러리

  • gcm.jar

* GCMIntentService.java [기본 패키지에 위치 시키며, 클래스 명을 지켜 줘야 된다.]

package com.example.gcm;


import java.util.Iterator;


import android.content.Context;

import android.content.Intent;

import android.os.Bundle;

import android.util.Log;


import com.example.gcm.config.Const;

import com.google.android.gcm.GCMBaseIntentService;


public class GCMIntentService extends GCMBaseIntentService {

    

    public GCMIntentService(){ 

    this( Const.SENDER_ID ); 

}

   

    public GCMIntentService(String project_id) {

    super(project_id); 

}

 

    

    /**

     * 메세지를 받았을때 이벤트 동작.

     */

    @Override

    protected void onMessage(Context context, Intent intent) {

   

    Log.d( this.getClass().getName(), "==========================EVENT ON====================");

        

    Bundle b = intent.getExtras();


        Iterator<String> iterator = b.keySet().iterator();

        

        StringBuffer values = new StringBuffer();

        while(iterator.hasNext()) {

            String key = iterator.next();

            String value = b.get(key).toString();

            Log.d( this.getClass().getName(), "onMessage. " + key + " : " + value);

            values.append(value);

        }

        Intent pushpopintent = new Intent(context,PushPopLayout.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        pushpopintent.putExtra("pushMessage", values.toString());

        context.startActivity(pushpopintent);

        

        Log.d( this.getClass().getName(), "==========================EVENT OFF====================");

        

    }


    /**

     * 에러 발생시 이벤트 동작.

     */

    @Override

    protected void onError(Context arg0, String arg1) {

    Log.e( this.getClass().getName(), "==========================EVENT ON====================");

        Log.e( this.getClass().getName(), "on_error. errorId : " + arg1);

        Log.e( this.getClass().getName(), "==========================EVENT OFF====================");

    }

 

    /**

     * 등록 아이디 발급 되었을때 ( 앱을 설치시 동작 )

     */

    @Override

    protected void onRegistered(Context context, String regId) {

    Log.i( this.getClass().getName(), "==========================EVENT ON====================");

        Log.i( this.getClass().getName(), "onRegistered. regId : "+regId);

        Log.i( this.getClass().getName(), "==========================EVENT OFF====================");

        

    }


    /**

     * 등록 아이디 패기 할때 ( 앱을 삭제시 동작 ) 

     */

    @Override

    protected void onUnregistered(Context context, String regId) {

    Log.i( this.getClass().getName(), "==========================EVENT ON====================");

        Log.i( this.getClass().getName(), "onUnregistered. regId : "+regId);

        Log.i( this.getClass().getName(), "==========================EVENT OFF====================");

    }


}


* MainActivity.java

package com.example.gcm;


import android.app.Activity;

import android.os.Bundle;

import android.util.Log;

import android.view.Menu;


import com.example.gcm.config.Const;

import com.google.android.gcm.GCMRegistrar;


public class MainActivity extends Activity {


    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        

        Log.d( this.getClass().getName(), "==========================Program Start==========================");

        

        GCMRegistrar.checkDevice(this);

        GCMRegistrar.checkManifest(this);

        

        final String regId = GCMRegistrar.getRegistrationId(this);

        

        if( "".equals( regId ) ){   //등록 아이디 체크

        

        GCMRegistrar.register(this, Const.SENDER_ID);

       

        }

        

        Log.d( this.getClass().getName(), "==========================Program End==========================");

        

    }

    


    @Override

    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.

        getMenuInflater().inflate(R.menu.main, menu);

        return true;

    }

    

}



* PushPopLayout.java

package com.example.gcm;


import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.view.WindowManager;

import android.widget.Button;

import android.widget.TextView;


public class PushPopLayout extends Activity {

private Button checkbtn;

private Button closebtn;


/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_push_pop_layout);


// pushContext =this;


// 잠자는 폰 깨우기

getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED /* 화면이 잠겨있을때 보여주기 */

| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD /* 키잠금 해제하기 */

| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); // 화면 켜기


TextView textView1 = (TextView)findViewById(R.id.textView1);

textView1.setText("푸쉬 메시지 벨류 : " + getIntent().getStringExtra("pushMessage"));

checkbtn = (Button) findViewById(R.id.PushCheckBtn);

closebtn = (Button) findViewById(R.id.PushcloseBtn);


checkbtn.setOnClickListener(new OnClickListener() {

public void onClick(View v) {

Intent intent = new Intent( PushPopLayout.this, MainActivity.class );

startActivity(intent);

finish();

}

});


closebtn.setOnClickListener(new OnClickListener() {

public void onClick(View v) {

// TODO Auto-generated method stub

finish();

}

});

}


}


* Const.java

package com.example.gcm.config;


public class Const {


public final static String SENDER_ID = "???????????????";

}


* AndroidMainfest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.example.gcm"

    android:versionCode="1"

    android:versionName="1.0" >

    

    

<!-- GCM 관련 퍼미션 -->

<permission android:name="com.example.gcm.permission.C2D_MESSAGE" android:protectionLevel="signature" />

<uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" /> 

<!-- GCM 받기 -->

<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

<!-- GCM을 받으려면 구글 계정 필요 -->

<uses-permission android:name="android.permission.GET_ACCOUNTS" />

<!-- 메시지 받을 때 wake up 하기 위해 -->

<uses-permission android:name="android.permission.WAKE_LOCK" />

<!-- 네트워크 접속 권한 -->

<uses-permission android:name="android.permission.INTERNET" />


    <uses-sdk

        android:minSdkVersion="8"

        android:targetSdkVersion="14" />


    <application

        android:allowBackup="true"

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name"

        android:theme="@style/AppTheme" >

        <activity

            android:name="com.example.gcm.MainActivity"

            android:label="@string/app_name" >

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />


                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

        

        <!-- GCM 리시버 -->

<receiver

  android:name="com.google.android.gcm.GCMBroadcastReceiver"

  android:permission="com.google.android.c2dm.permission.SEND" >

  <intent-filter>

     <action android:name="com.google.android.c2dm.intent.RECEIVE" />

     <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

     <category android:name="com.example.gcm" /> <!-- 젤리빈 부터는 category 빼도 된다 -->

  </intent-filter>

</receiver>

<!-- GCM 리시버에서 돌리는 서비스 -->

<service android:name=".GCMIntentService" /><!-- 서비스명 변경하면 안됨 -->

    </application>


</manifest>


* activity_push_pop_layout.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical" >


    <TextView

        android:id="@+id/textView1"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="푸시가 도착 하였습니다. 확인 하시겠습니까?"

        android:textAppearance="?android:attr/textAppearanceLarge" />


    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="wrap_content" >


        <Button

            android:id="@+id/PushCheckBtn"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="ok" />


        <Button

            android:id="@+id/PushcloseBtn"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="no" />


    </LinearLayout>


</LinearLayout>




* 서버 소스

- 필요 라이브러리

  • gcm-server.jar
  • json-simple-1.1.1.jar

*GCMSender.java

package gcmServer;


import java.util.HashMap;

import java.util.List;


import com.google.android.gcm.server.Constants;

import com.google.android.gcm.server.Message;

import com.google.android.gcm.server.MulticastResult;

import com.google.android.gcm.server.Result;

import com.google.android.gcm.server.Sender;


public class GCMSender {


    private String API_KEY = "AI??????????????????????????????????????????????????????????";

    private int reSendCount = 5;


    /**

     * 단일 단말기를 대상으로 푸쉬 메세지 전송.

     * @param key

     * @param value

     * @param regId

     * @return

     * @throws Exception

     */

    public String sendPush(String key, String value, String regId) throws Exception {

        

    Sender sender = new Sender(API_KEY); 

        

        Message msg = new Message.Builder().addData(key, value).build();

   

    Result result = sender.send(msg, regId, reSendCount);

   

    // 결과값 확인

        if (result.getMessageId() != null) {

       

        String canonicalRegId = result.getCanonicalRegistrationId();

       

        if( canonicalRegId != null ){

        // 표준 등록 ID가 반환됨. 대체 필요.

        return "same device has more than on registation ID : " + canonicalRegId + " / "+result.getMessageId();

        }


        // 전송 성공

        return "messageid : "+result.getMessageId();

       

        } else {

       

            String error = result.getErrorCodeName(); // 전송 실패

            

            if( error.equals( Constants.ERROR_NOT_REGISTERED ) ){

            //어플리 케이션이 삭제되었음.

           

            }

            return error;

            

        }

            


    }

    

    /**

     * 다중 단말기를 대상으로 푸쉬 메세지 전송

     * @param key

     * @param value

     * @param regIdList

     * @return

     * @throws Exception

     */

    public HashMap< String, String > sendPush(String key, String value, List<String> regIdList) throws Exception {

        

    Sender sender = new Sender(API_KEY); 

        

    HashMap< String, String > returnValue = new HashMap< String, String >();


        Message msg = new Message.Builder().addData(key, value).build();


        for( int i = 0; regIdList.size() > i; i++ ){


        Result result = sender.send(msg, regIdList.get(i), reSendCount);

       

        // 결과값 확인

            if (result.getMessageId() != null) {

                

            // 전송 성공

            returnValue.put( regIdList.get(i), "success");

           

            } else {

            

            String error = result.getErrorCodeName(); // 전송 실패

                returnValue.put( regIdList.get(i), error);

                

            }

            

        }

        return returnValue;

    }

    

    /**

     * 다중 단말기를 대상으로 푸쉬 메세지 전송

     * @param key

     * @param value

     * @param regIdList

     * @return MulticastResult

     * @throws Exception

     */

    public MulticastResult sendPushMulticastResult(String key, String value, List<String> regIdList) throws Exception {

        

    Sender sender = new Sender(API_KEY);


        Message msg = new Message.Builder().addData(key, value).build();

       

    MulticastResult result = sender.send(msg, regIdList, reSendCount);

       

            

        return result;

    }


}



* Main.java

package gcmServer;


public class Main {


public static void main(String[] args) {

// TODO Auto-generated method stub

        String key = "keyPram2";

        String value = "valuePram2";

        String regId = "AP??????????????????????????????????????????????????????????????????????????????";

        

        

try {

System.out.println("Push Message Sending start.");

String returnValue = new GCMSender().sendPush(key, value, regId);

System.out.println("Push Message Sended Value : " + returnValue);

} catch (Exception e) {

// TODO Auto-generated catch block

System.out.println("Push Message Send File");

System.out.println(e.getMessage());

e.printStackTrace();

}

}


}