일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Machine Learning
- Raspberry
- IMAGE
- keras
- Video
- 라즈베리파이
- 고급C
- Deep Learning
- 정리
- RapidCheck
- Android
- 지능형
- 안드로이드
- FLASK
- 데이터
- 서버
- MySQL
- Python
- 영상분석
- detection
- C언어
- php
- Linux
- sw
- 가상환경
- 머신러닝
- tracking
- Object Detection
- 디버그모드
- tensorflow
- Today
- Total
건프의 소소한 개발이야기
[안드로이드] Google Cloud Message(GCM) 적용시키기 - (2) 본문
안녕하세요, 건프입니다.
시리즈
[안드로이드] Google Cloud Message(GCM) 적용시키기 - (1)
[안드로이드] Google Cloud Message(GCM) 적용시키기 - (2)
[안드로이드] Google Cloud Message(GCM) 적용시키기 - (3)
앞서 google service 에서 push server configuration key 와 file을 발급받았습니다.
이제 안드로이드 스튜디오로 돌아와 작업해주면 됩니다.
1. 디팬던시 설정
가이드 라인을 확인해보면, google-services.json 파일을 app/ 아래에 옮긴뒤에
project-level 아래의 build.gradle 에 classpath 을 입력하고,
app-level 아래의 build.gradle에 plugin 을 입력하라고 되어 있습니다.
다음과 같이 진행하시면 됩니다.
project-level build.gradle
app-level build.gradle
그리고 app-level 의 build.gradle 에 다음과같이 라이브러리를 추가해주면 됩니다.
compile "com.google.android.gms:play-services-gcm:8.3.0"
여기단계에서 싱크 오류가 난다면, 적절히 오류메세지를 보면서, 해달라는대로 버전정보를 바꿔주면 됩니다.
2. Manifest file 수정
AndroidManifest file도 약간 손 바줘야 합니다.
우선 퍼미션입니다.
<!-- [START gcm_permission] -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- [END gcm_permission] -->
GCM이 되기전, 서비스의 이름이 c2dm 였습니다. 아직도 그 흔적이 남아있음을 알 수 있습니다.
그리고 application 태그 아래, 기본적으로 작성해야할 서비스들과 리시버들이 있습니다.
3. receiver
<!-- [START gcm_receiver] -->
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.brianandroid.myzzung.coli.gcm" />
</intent-filter>
</receiver>
<!-- [END gcm_receiver] -->
바꿀 필요없이 그대로 사용하시면 됩니다.
4. GcmListenerService
<!-- [START gcm_listener_service] -->
<service
android:name="com.brianandroid.myzzung.coli.gcm.CoilGcmListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<!-- [END gcm_listener_service] -->
CoilGcmListenerService 클래스를 이따가 구현할 것입니다.
Gcm 을 수령했을때, 발동하는 서비스 클래스 입니다.
5. 기기별 구분 token(key)를 등록하는 서비스 입니다.
<!-- [START gcm_registration_service] -->
<service
android:name="com.brianandroid.myzzung.coli.gcm.RegisterationIntentService"
android:exported="false"/>
<!-- [END gcm_registration_service] -->
RegisterationIntentService 클래스를 이따가 구현할 겁니다.
6. InstanceID 가 변했을 때, 동작하는 서비스 입니다.
<!-- [START instanceId_listener_service] -->
<service
android:name="com.brianandroid.myzzung.coli.gcm.CoilInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
</intent-filter>
</service>
<!-- [END instanceId_listener_service] -->
7. 클래스 구현
7-1) CoilGcmListenerService.java
public class CoilGcmListenerService extends GcmListenerService {
@Override
public void onMessageReceived(String from, Bundle data) {
super.onMessageReceived(from, data);
String title = data.getString("title");
String message = data.getString("message");
String is_notifi = data.getString("notification_type");
if(is_notifi.equals("true")){
CoilNotification cnb = new CoilNotification(getApplicationContext());
cnb.sendNotification(title, message, CoilNotification.BY_GCM);
}
}
}
GCM 메세지가 수신되었을때, 동작하는 서비스 입니다.
CoilNotification 클래스는 노티피케이션 기능을 담당하는 모듈입니다. 이전 포스팅에서 설명한 적이 있으므로 생략하겠습니다.
7-2) 사용자 token 등록하는 서비스 : RegisterationIntentService.java
public class RegisterationIntentService extends IntentService {
private static final String TAG = "RegistrationIntentService";
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* @param name Used to name the worker thread, important only for debugging.
*/
public RegisterationIntentService() {
super(TAG);
}
@SuppressLint("LongLogTag")
@Override
protected void onHandleIntent(Intent intent) {
// GCM Instance ID의 토큰을 가져오는 작업이 시작되면 LocalBoardcast로 GENERATING 액션을 알려 ProgressBar가 동작하도록 한다.
LocalBroadcastManager.getInstance(this)
.sendBroadcast(new Intent(QuickstartPreferences.REGISTRATION_GENERATING));
Log.d(TAG, "in Registerservice");
// GCM을 위한 Instance ID를 가져온다.
InstanceID instanceID = InstanceID.getInstance(this);
String token = null;
try {
synchronized (TAG) {
// GCM 앱을 등록하고 획득한 설정파일인 google-services.json을 기반으로 SenderID를 자동으로 가져온다.
String default_senderId = getString(R.string.gcm_defaultSenderId);
// GCM 기본 scope는 "GCM"이다.
String scope = GoogleCloudMessaging.INSTANCE_ID_SCOPE;
// Instance ID에 해당하는 토큰을 생성하여 가져온다.
token = instanceID.getToken(default_senderId, scope, null);
Log.i(TAG, "GCM Registration Token: " + token);
}
} catch (IOException e) {
e.printStackTrace();
}
// GCM Instance ID에 해당하는 토큰을 획득하면 LocalBoardcast에 COMPLETE 액션을 알린다.
// 이때 토큰을 함께 넘겨주어서 UI에 토큰 정보를 활용할 수 있도록 했다.
Intent registrationComplete = new Intent(QuickstartPreferences.REGISTRATION_COMPLETE);
registrationComplete.putExtra("token", token);
LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
}
}
7-3) CoilInstanceIDListenerService.java
public class CoilInstanceIDListenerService extends InstanceIDListenerService {
private static final String TAG = "MyInstanceIDLS";
@Override
public void onTokenRefresh() {
Intent intent = new Intent(this, RegisterationIntentService.class);
startService(intent);
}
}
7-4) LocalBroadcastManager 에서 사용할 String Flag들
public class QuickstartPreferences {
public static final String REGISTRATION_READY = "registrationReady";
public static final String REGISTRATION_GENERATING = "registrationGenerating";
public static final String REGISTRATION_COMPLETE = "registrationComplete";
}
7-5) 보여질 화면의 xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.brianandroid.myzzung.coli.ui.SettingFragment">
<!-- TODO: Update blank fragment layout -->
<Button android:id="@+id/registrationButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="gcm token 받기" />
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/informationTextView"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/registrationProgressBar" />
</LinearLayout>
7-6) 보여질 화면의 java 코드
public class SettingFragment extends Fragment {
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
private static final String TAG = "MainActivity";
private Button mRegistrationButton;
private ProgressBar mRegistrationProgressBar;
private BroadcastReceiver mRegistrationBroadcastReceiver;
private TextView mInformationTextView;
public SettingFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
ViewGroup rootView = (ViewGroup)inflater.inflate(R.layout.fragment_setting, container, false);
registBroadcastReceiver();
setLocalBoradcastManager(getActivity());
// 토큰을 보여줄 TextView를 정의
mInformationTextView = (TextView) rootView.findViewById(R.id.informationTextView);
//mInformationTextView.setVisibility(View.GONE);
// 토큰을 가져오는 동안 인디케이터를 보여줄 ProgressBar를 정의
mRegistrationProgressBar = (ProgressBar) rootView.findViewById(R.id.registrationProgressBar);
mRegistrationProgressBar.setVisibility(ProgressBar.GONE);
// 토큰을 가져오는 Button을 정의
mRegistrationButton = (Button) rootView.findViewById(R.id.registrationButton);
mRegistrationButton.setOnClickListener(new View.OnClickListener() {
/**
* 버튼을 클릭하면 토큰을 가져오는 getInstanceIdToken() 메소드를 실행한다.
* @param view
*/
@Override
public void onClick(View view) {
Toast.makeText(getActivity(), "click", Toast.LENGTH_SHORT).show();
getInstanceIdToken();
}
});
return rootView;
}
/**
* Google Play Service를 사용할 수 있는 환경이지를 체크한다.
*/
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity());
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, getActivity(),
PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {
Log.i(TAG, "This device is not supported.");
}
return false;
}
return true;
}
/**
* Instance ID를 이용하여 디바이스 토큰을 가져오는 RegistrationIntentService를 실행한다.
*/
public void getInstanceIdToken() {
if (checkPlayServices()) {
// Start IntentService to register this application with GCM.
Intent intent = new Intent(getActivity(), RegisterationIntentService.class);
getActivity().startService(intent);
}else{
Toast.makeText(getActivity(), "no in regis service", Toast.LENGTH_SHORT).show();
}
}
/**
* LocalBoardcastManager 를 등록한다
* @param context
*/
private void setLocalBoradcastManager(Context context){
LocalBroadcastManager.getInstance(context).registerReceiver(mRegistrationBroadcastReceiver,
new IntentFilter(QuickstartPreferences.REGISTRATION_READY));
LocalBroadcastManager.getInstance(context).registerReceiver(mRegistrationBroadcastReceiver,
new IntentFilter(QuickstartPreferences.REGISTRATION_GENERATING));
LocalBroadcastManager.getInstance(context).registerReceiver(mRegistrationBroadcastReceiver,
new IntentFilter(QuickstartPreferences.REGISTRATION_COMPLETE));
}
/**
* LocalBoardcastManager를 해제한다
* @param context
*/
private void deleteLocalBoardcastManager(Context context){
LocalBroadcastManager.getInstance(context).unregisterReceiver(mRegistrationBroadcastReceiver);
}
/**
* LocalBroadcast 리시버를 정의한다. 토큰을 획득하기 위한 READY, GENERATING, COMPLETE 액션에 따라 UI에 변화를 준다.
*/
public void registBroadcastReceiver(){
mRegistrationBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals(QuickstartPreferences.REGISTRATION_READY)){
// 액션이 READY일 경우
mRegistrationProgressBar.setVisibility(ProgressBar.GONE);
mInformationTextView.setVisibility(View.GONE);
} else if(action.equals(QuickstartPreferences.REGISTRATION_GENERATING)){
// 액션이 GENERATING일 경우
mRegistrationProgressBar.setVisibility(ProgressBar.VISIBLE);
mInformationTextView.setVisibility(View.VISIBLE);
mInformationTextView.setText("gcm token 생성중...");
} else if(action.equals(QuickstartPreferences.REGISTRATION_COMPLETE)){
// 액션이 COMPLETE일 경우
mRegistrationProgressBar.setVisibility(ProgressBar.GONE);
mRegistrationButton.setText("gcm token 생성완료!");
mRegistrationButton.setEnabled(false);
String token = intent.getStringExtra("token");
mInformationTextView.setText(token);
}
}
};
}
}
각각의 코드가 어떤 기능을 하는지는, 차근차근 확인해보시면 알 수 있습니다.
여기서는 MainUI 화면에서 getInstanceIdToken() 을 요청하고, LocalBoardcast를 연결해놓습니다.
RegisterationIntentService 에서 사용자 Token 을 얻어오면, Boardcast로 send 합니다.
해당 Intent를 받은 Boardcast Receiver 가 MainUI 에서 잡아내 동작합니다.
이제 메세지를 푸시할 서버를 만들어낼 차례입니다.
' 개발 이야기 > 안드로이드 이야기' 카테고리의 다른 글
[안드로이드] Android RecyclerView with CardView (1) | 2016.05.15 |
---|---|
[안드로이드] Navigation View Header View 관리하기 (4) | 2016.05.07 |
[안드로이드] Google Cloud Message(GCM) 적용시키기 - (1) (0) | 2016.05.07 |
[안드로이드] Material Dialog 관련 라이브러리 사용법 (1) (0) | 2016.05.01 |
[안드로이드] Android Volley 사용 Network 통신하는 법 (6) | 2016.04.23 |