Google Play Service 연결하기
- 이클립스 – Windows – Android SDK Manager 를 연다.
- 목록의 제일 아래쪽에 Goole Play Services 선택한다.
- 오른쪽 아래의 Install 버튼을 누른다.
- 설치가 끝나면 이클립스의 프로젝트 목록에서 오른쪽 클릭해서 import 메뉴를 선택하고,{sdk}/extras/google/google_play_services/ 를 선택한다.
- 작성할 프로젝트의 오른쪽 클릭 메뉴 – properties – Android – Library – Add… 버튼을 누른다.
- google-play-services_lib 를 선택한다.
Manifest 편집
kr.mint.testgcm 이라고 적힌 부분은 실제 패키지 경로로 바꿔야 함.
Permission
XHTML
1
2
3
4
5
6
7
8
9
10
11
|
<uses-permission android:name=“android.permission.INTERNET” />
<uses-permission android:name=“android.permission.GET_ACCOUNTS” />
<uses-permission android:name=“android.permission.WAKE_LOCK” />
<uses-permission android:name=“com.google.android.c2dm.permission.RECEIVE” />
<uses-permission android:name=“android.permission.VIBRATE” />
<permission
android:name=“kr.mint.testgcm.permission.C2D_MESSAGE”
android:protectionLevel=“signature” />
<uses-permission android:name=“kr.mint.testgcm.permission.C2D_MESSAGE” />
|
activity
XHTML
1
2
3
4
5
6
7
8
9
|
<activity
android:name=“.MainActivity”
android:launchMode=“singleTask” // notification bar에서 클릭할 때를 위해
android:label=“@string/app_name” >
<intent-filter>
<action android:name=“android.intent.action.MAIN” />
<category android:name=“android.intent.category.LAUNCHER” />
</intent-filter>
</activity>
|
receiver, service, meta-data
XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<receiver
android:name=“.receiver.GcmBroadcastReceiver”
android:permission=“com.google.android.c2dm.permission.SEND” >
<intent-filter>
<action android:name=“com.google.android.c2dm.intent.RECEIVE” />
<category android:name=“kr.mint.testgcm” />
</intent-filter>
</receiver>
<service android:name=“.GcmIntentService” />
<meta-data
android:name=“com.google.android.gms.version”
android:value=“@integer/google_play_services_version” />
|
MainActivity 편집
http://developer.android.com/google/gcm/client.html#sample-register 의 소스를 살짝 바꿨다.
Java
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
public class MainActivity extends Activity
{
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
private static final String SENDER_ID = “388136674604”;
private GoogleCloudMessaging _gcm;
private String _regId;
private TextView _textStatus;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
_textStatus = (TextView) findViewById(R.id.textView1);
// google play service가 사용가능한가
if (checkPlayServices())
{
_gcm = GoogleCloudMessaging.getInstance(this);
_regId = getRegistrationId();
if (TextUtils.isEmpty(_regId))
registerInBackground();
}
else
{
Log.i(“MainActivity.java | onCreate”, “|No valid Google Play Services APK found.|”);
_textStatus.append(“n No valid Google Play Services APK found.n”);
}
// display received msg
String msg = getIntent().getStringExtra(“msg”);
if (!TextUtils.isEmpty(msg))
_textStatus.append(“n” + msg + “n”);
}
@Override
protected void onNewIntent(Intent intent)
{
super.onNewIntent(intent);
// display received msg
String msg = intent.getStringExtra(“msg”);
Log.i(“MainActivity.java | onNewIntent”, “|” + msg + “|”);
if (!TextUtils.isEmpty(msg))
_textStatus.append(“n” + msg + “n”);
}
// google play service가 사용가능한가
private boolean checkPlayServices()
{
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS)
{
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode))
{
GooglePlayServicesUtil.getErrorDialog(resultCode, this, PLAY_SERVICES_RESOLUTION_REQUEST).show();
}
else
{
Log.i(“MainActivity.java | checkPlayService”, “|This device is not supported.|”);
_textStatus.append(“n This device is not supported.n”);
finish();
}
return false;
}
return true;
}
// registration id를 가져온다.
private String getRegistrationId()
{
String registrationId = PreferenceUtil.instance(getApplicationContext()).regId();
if (TextUtils.isEmpty(registrationId))
{
Log.i(“MainActivity.java | getRegistrationId”, “|Registration not found.|”);
_textStatus.append(“n Registration not found.n”);
return “”;
}
int registeredVersion = PreferenceUtil.instance(getApplicationContext()).appVersion();
int currentVersion = getAppVersion();
if (registeredVersion != currentVersion)
{
Log.i(“MainActivity.java | getRegistrationId”, “|App version changed.|”);
_textStatus.append(“n App version changed.n”);
return “”;
}
return registrationId;
}
// app version을 가져온다. 뭐에 쓰는건지는 모르겠다.
private int getAppVersion()
{
try
{
PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
return packageInfo.versionCode;
}
catch (NameNotFoundException e)
{
// should never happen
throw new RuntimeException(“Could not get package name: “ + e);
}
}
// gcm 서버에 접속해서 registration id를 발급받는다.
private void registerInBackground()
{
new AsyncTask<Void, Void, String>()
{
@Override
protected String doInBackground(Void... params)
{
String msg = “”;
try
{
if (_gcm == null)
{
_gcm = GoogleCloudMessaging.getInstance(getApplicationContext());
}
_regId = _gcm.register(SENDER_ID);
msg = “Device registered, registration ID=” + _regId;
// For this demo: we don’t need to send it because the device
// will send upstream messages to a server that echo back the
// message using the ‘from’ address in the message.
// Persist the regID – no need to register again.
storeRegistrationId(_regId);
}
catch (IOException ex)
{
msg = “Error :” + ex.getMessage();
// If there is an error, don’t just keep trying to register.
// Require the user to click a button again, or perform
// exponential back-off.
}
return msg;
}
@Override
protected void onPostExecute(String msg)
{
Log.i(“MainActivity.java | onPostExecute”, “|” + msg + “|”);
_textStatus.append(msg);
}
}.execute(null, null, null);
}
// registraion id를 preference에 저장한다.
private void storeRegistrationId(String regId)
{
int appVersion = getAppVersion();
Log.i(“MainActivity.java | storeRegistrationId”, “|” + “Saving regId on app version “ + appVersion + “|”);
PreferenceUtil.instance(getApplicationContext()).putRedId(regId);
PreferenceUtil.instance(getApplicationContext()).putAppVersion(appVersion);
}
}
|
Received Message
예전에는 브로드캐스트 리시버에서 다 했던 것 같은데, 구글에서 가이드 해줬으니 그거 따라해야지….
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
Log.i(“GcmBroadcastReceiver.java | onReceive”, “|” + “=================”+“|”);
Bundle bundle = intent.getExtras();
for (String key : bundle.keySet())
{
Object value = bundle.get(key);
Log.i(“GcmBroadcastReceiver.java | onReceive”, “|” + String.format(“%s : %s (%s)”, key, value.toString(), value.getClass().getName()) + “|”);
}
Log.i(“GcmBroadcastReceiver.java | onReceive”, “|” + “=================”+“|”);
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(), GcmIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, intent.setComponent(comp));
setResultCode(Activity.RESULT_OK);
}
}
|
Show in Notification bar
노티바에 표시하면서 0.5초 동안 진동하고, 클릭하면 메인화면으로 가는 거 추가
Java
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
public class GcmIntentService extends IntentService
{
public static final int NOTIFICATION_ID = 1;
public GcmIntentService()
{
super(“GcmIntentService”);
}
@Override
protected void onHandleIntent(Intent intent)
{
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
// The getMessageType() intent parameter must be the intent you received
// in your BroadcastReceiver.
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty())
{ // has effect of unparcelling Bundle
/*
* Filter messages based on message type. Since it is likely that GCM
* will be extended in the future with new message types, just ignore
* any message types you’re not interested in, or that you don’t
* recognize.
*/
if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType))
{
sendNotification(“Send error: “ + extras.toString());
}
else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType))
{
sendNotification(“Deleted messages on server: “ + extras.toString());
// If it’s a regular GCM message, do some work.
}
else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType))
{
String msg = intent.getStringExtra(“msg”);
// Post notification of received message.
// sendNotification(“Received: ” + extras.toString());
sendNotification(“Received: “ + msg);
Log.i(“GcmIntentService.java | onHandleIntent”, “Received: “ + extras.toString());
}
}
// Release the wake lock provided by the WakefulBroadcastReceiver.
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
// Put the message into a notification and post it.
// This is just one simple example of what you might choose to do with
// a GCM message.
private void sendNotification(String msg)
{
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(“msg”, msg);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this).setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(“GCM Notification”)
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg)
.setAutoCancel(true)
.setVibrate(new long[] { 0, 500 });
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
}
|
Preference
그냥 구글 소스대로 해놓고 글 작성할 걸 괜히 리팩토링해가지고 불편하게 됐네 ;;;
BasePreferenceUtil
Java
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
public class BasePreferenceUtil
{
private SharedPreferences _sharedPreferences;
protected BasePreferenceUtil(Context $context)
{
super();
_sharedPreferences = PreferenceManager.getDefaultSharedPreferences($context);
}
/**
* key 수동 설정
*
* @param key
* 키 값
* @param value
* 내용
*/
protected void put(String $key, String $value)
{
SharedPreferences.Editor editor = _sharedPreferences.edit();
editor.putString($key, $value);
editor.commit();
}
/**
* String 값 가져오기
*
* @param key
* 키 값
* @return String (기본값 null)
*/
protected String get(String $key)
{
return _sharedPreferences.getString($key, null);
}
/**
* key 설정
*
* @param key
* 키 값
* @param value
* 내용
*/
protected void put(String $key, boolean $value)
{
SharedPreferences.Editor editor = _sharedPreferences.edit();
editor.putBoolean($key, $value);
editor.commit();
}
/**
* Boolean 값 가져오기
*
* @param key
* 키 값
* @param defValue
* 기본값
* @return Boolean
*/
protected boolean get(String $key, boolean $default)
{
return _sharedPreferences.getBoolean($key, $default);
}
/**
* key 설정
*
* @param key
* 키 값
* @param value
* 내용
*/
protected void put(String $key, int $value)
{
SharedPreferences.Editor editor = _sharedPreferences.edit();
editor.putInt($key, $value);
editor.commit();
}
/**
* int 값 가져오기
*
* @param key
* 키 값
* @param defValue
* 기본값
* @return int
*/
protected int get(String $key, int $default)
{
return _sharedPreferences.getInt($key, $default);
}
}
|
PreferenceUtil
Java
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
32
33
34
35
36
37
38
39
|
public class PreferenceUtil extends BasePreferenceUtil
{
private static PreferenceUtil _instance = null;
private static final String PROPERTY_REG_ID = “registration_id”;
private static final String PROPERTY_APP_VERSION = “appVersion”;
public static synchronized PreferenceUtil instance(Context $context)
{
if (_instance == null)
_instance = new PreferenceUtil($context);
return _instance;
}
protected PreferenceUtil(Context $context)
{
super($context);
}
public void putRedId(String $regId)
{
put(PROPERTY_REG_ID, $regId);
}
public String regId()
{
return get(PROPERTY_REG_ID);
}
public void putAppVersion(int $appVersion)
{
put(PROPERTY_APP_VERSION, $appVersion);
}
public int appVersion()
{
return get(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
}
}
|
Registration ID 복사해두기
정상적으로 등록이 됐다면 logcat 에 RegID가 나올텐데, 이걸 복사해뒀다가 송신 서버 만들 때 쓰자.
예제소스
https://github.com/susemi99/GCM-client-sample
{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에 체크가 되어있는지, 프로젝트가 닫혀있지 않는지 확인해보세요
정말 세심한 예제로 잘 보고 갑니다..^^
감사합니다…
^^
Can’t redirect to app settings for google play services 이렇게 에러가뜨는 데 왜그러는걸까요 .ㅠㅠ
음….차근차근 처음부터 다시 해보세요 ;;
여기나와있는소스를 그냥 다 복사붙여넣기해서 돌려보려면 수정해야되는부분이 어디어디인가요?;
kr.mint.testgcm 이런거 밖에 안 보이네요
sdk매니저에서 구글 플레이 서비스도 업데이트도 해보시구요
좋은 글 감사합니다. 이전 gcm.jar를 사용하던 버전과 다른 점이라면 안드로이드 키도 생성하는 부분인 것같습니다. 이 안드로이드 키를 어디서 사용하는지 소스상에도 나와있지 않은것같은데 어디서 사용하는 것인가요?
구글사이트에서 만드는 api key를 말씀하시는 건가요? 기억은 안나는데, 그게없으면 메시지를 못받을겁니다. 아마 해당 패키지이름을 쓰는 앱만 받게돼있는 것 같아요
서버가 없이 앱에서 컨트롤이 가능한건가요..?
어떤 서버를 말씀하시는건가요?
되는지 테스트 해볼라면 서버를 만들어 봐야 겠네요?
감사합니다. 임포트 하는거 구글맵 쓰면서 해봤는데 이상하게 에러나서 에러 잡아볼라고 코쟁이들 질문 답 까지 찾아가면서 1시간 헤메다 짜증나서 지우고 다시 했는데 되네요 ㅋ
http://susemi99.kr/1023
클라이언트만 작성하여 실행하여 로그캣에 RegID가 나오나요???
네(구글 콘솔 작업을 했다면요)
쎄미님 안녕하세요 : )
클량 자당 알렉스입니다. ㅋㅋㅋㅋㅋㅋㅋ
어찌어찌 검색하다보니 쎄미님 글까지 왔네요;
지금 구글에서제공하는 기본 소스 gcm.jar 를 이용해서 gcm을 구현해놓았는데…
포스팅하신 이것과 다른건지 궁금해서 여쭤보려구요.
gcm에서 간혹 특정 디바이스에서 registrationId를 수집해오지 못할때가 있어서…
혹, 쎄미님께서 포스팅하신 방법으로 하면 될까 하고 해보려고 합니다.
안녕하세요~
구글에서 플레이서비스로 자꾸 끌어들이고 있으니 아마 저게 최신 버전일거예요 ㅎㅎ
예제소스 있으니까 한 번 해보시면 되지 않을까요?
감사합니다!
이걸로 하니까 되네요…휴;;;
String regId = GCMRegistrar.getRegistrationId(_context);
으로 안되던게 Google Play Service로 하니까 되는군요… 세미님 덕분에 잘 해결했습니다 ㅎㅎ
다음에 뵈면 맛있는 쪼꼬바 사드릴께요~ ㅎㅎㅎ
네 ㅎㅎ 양갱도 좋아합니다 ㅎㅎ