2017. 11. 21. 10:04
Azure Notification Hub을 이용하여 Mobile App 에 알림 서비스를 연동 개발 합니다. 개발 도구는 Xamarin.Forms 를 이용하여 Android 및 iOS App 에 연동 테스트를 하겠습니다.
- Google GCM 설정
로그인 후 "+ 프로젝트 추가" 를 선택 합니다.
"프로젝트 이름" 을 입력하고 "프로젝트 만들기" 버튼을 클릭합니다.
프로젝트 생성 후 "Android 앱에 Firebase 추가" 를 선택합니다.
Azure에서 생성 한 Mobile App 다운 로드 소스에서 Android 앱 이름을 입력 합니다. Xamarin.Forms 으로로 다운 받은 소스를 Visual Studio 에서 열면 확인 할 수 있습니다.
해당 내용을 잘 읽고 숙지 합니다. "google-services.json" 파일을 다운로드 합니다.
아래 내용은 Xamarin.Forms 에서는 별도로 설정하지 않습니다. "완료" 버튼을 클릭합니다.
"Android 앱에 Firebase 추가" 완료 후 "Overview" 옆에 있는 설정 아이콘을 클릭하고 "프로젝트 설정"을 선택합니다.
아래 내용 중에서 "서버 키" 및 "발신자 ID"을 기록해 둡니다. 서버 키는 Azure Notification Hub에서 Google GCM을 연결할 때 등록 합니다. 그리고 발신자 ID는 Mobile App 개발 코드에 입력 합니다.
Azure에서 생성 한 Notification Hub 를 선택 하고 "알림 서비스"를 클릭합니다. 그리고 "Google(GCM)"을 클릭합니다.
"API 키" 에 위에서 확인 한 "서버 키"를 입력 후 "저장" 버튼을 클릭합니다.
- Android Mobile App 코드 수정
개발을 위한 IDE는 Windows for Mac 을 사용 하였습니다. (다운로드 및 설치 : https://www.visualstudio.com/ko/vs/visual-studio-mac)
다운로드 받은 파일 중 "XXXXX_Xamarin_Forms.zip" 파일의 압축을 해제 합니다.
해제한 폴더 안에 Visual Studio Solution 파일인 "XXXXX.sin" 파일을 더블 클릭합니다.
Visual Studio for Mac 에서 열면 아래와 같이 각 플랫폼 별로 4개의 항복이 보입니다. 제일 위에 있는 것이 .Forms 코드이고, 솔루션 명 뒤에 .Droid 는 Android 코드, .iOS 는 Apple 코드를, .UWP 는 Windows 코드를 가지고 있습니다.
다운 받은 "google-services.json" 파일을 프로젝트 중 "Droid" 폴더 안에 복사 합니다.
Visual studio에서 "google-services.json" 를 추가 합니다.
XXX.Droid 를 선택하고 확장 합니다. 마우스 오른 쪽 버튼을 클릭해서 "시작 프로젝트"로 설정합니다.
"구성 요소" 를 선택하고 마우스 오른쪽 버튼을 클릭해서 "추가 구성요소 가져오기…" 를 클릭합니다.
구성 요소 관리 창에서 "Google Cloud Messaging Client" 를 검색해서 설치 합니다.
설치 시 Google 계정으로 로그인이 필요 합니다. 설치가 완료 되면 아래와 같이 나타납니다.
그리고 "패키지" 를 확인해서 업데이트가 있으면 모두 업데이트 합니다.
아래 사이트를 방문하여 추가 해야 할 코드를 복사하여 수정 합니다.
"MainActivity.cs" 파일을 열고 코드를 추가 합니다. Gcm 사용을 위해 using 문을 추가합니다.
using Gcm.Client; |
"OnCreate" 메서드에 아래 와 같이 코드를 추가 합니다.
"OnCreate" 메서드 안에 "LoadApplication( new App() ); " 아래에 다음 코드를 추가 합니다.
// Set the current instance of MainActivity.
instance = this;
……….. (중략)
LoadApplication( new App() );
try
{
// Check to ensure everything's set up right
GcmClient.CheckDevice(this);
GcmClient.CheckManifest(this);
// Register for push notifications
System.Diagnostics.Debug.WriteLine("Registering...");
GcmClient.Register(this, PushHandlerBroadcastReceiver.SENDER_IDS);
}
{
CreateAndShowDialog("There was an error creating the client. Verify the URL.", "Error");
}
catch (Exception e)
{
CreateAndShowDialog(e.Message, "Error");
} |
다음으로 message 를 표시 할 수 있도록 "CreateAndShowDialog" 메서드를 추가합니다.
private void CreateAndShowDialog(String message, String title)
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.SetMessage (message);
builder.SetTitle (title);
builder.Create().Show ();
} |
아래 코드를 "CreateAndShowDialog" 메서드 아래에 추가합니다.
// Create a new instance field for this activity.
static MainActivity instance = null;
// Return the current activity instance.
public static MainActivity CurrentActivity
{
get
{
return instance;
}
} |
"GcmService.cs" 를 새 클래스를 빈 클래스로 만듭니다.
"GcmService.cs" 클래스를 생성 후 아래 코드를 복사하여 추가합니다.
using Android.App;
using Android.Content;
using Android.Media;
using Android.Support.V4.App;
using Android.Util;
using Gcm.Client;
using Microsoft.WindowsAzure.MobileServices;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
[assembly: Permission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")]
[assembly: UsesPermission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")]
[assembly: UsesPermission(Name = "com.google.android.c2dm.permission.RECEIVE")]
[assembly: UsesPermission(Name = "android.permission.INTERNET")]
[assembly: UsesPermission(Name = "android.permission.WAKE_LOCK")]
//GET_ACCOUNTS is only needed for android versions 4.0.3 and below
[assembly: UsesPermission(Name = "android.permission.GET_ACCOUNTS")]
namespace demo_notificationhub.Droid
{
//public class GcmService : GcmServiceBase
//{
// public static string RegistrationID { get; private set; }
// public GcmService()
// : base(PushHandlerBroadcastReceiver.SENDER_IDS) { }
//}
[BroadcastReceiver(Permission = Gcm.Client.Constants.PERMISSION_GCM_INTENTS)]
[IntentFilter(new string[] { Gcm.Client.Constants.INTENT_FROM_GCM_MESSAGE }, Categories = new string[] { "@PACKAGE_NAME@" })]
[IntentFilter(new string[] { Gcm.Client.Constants.INTENT_FROM_GCM_REGISTRATION_CALLBACK }, Categories = new string[] { "@PACKAGE_NAME@" })]
[IntentFilter(new string[] { Gcm.Client.Constants.INTENT_FROM_GCM_LIBRARY_RETRY }, Categories = new string[] { "@PACKAGE_NAME@" })]
public class PushHandlerBroadcastReceiver : GcmBroadcastReceiverBase<GcmService>
{
public static string[] SENDER_IDS = new string[] { "622497192006" };
}
[Service]
public class GcmService : GcmServiceBase
{
public static string RegistrationID { get; private set; }
public GcmService()
: base(PushHandlerBroadcastReceiver.SENDER_IDS) { }
protected override void OnRegistered(Context context, string registrationId)
{
Log.Verbose("PushHandlerBroadcastReceiver", "GCM Registered: " + registrationId);
RegistrationID = registrationId;
var push = TodoItemManager.DefaultManager.CurrentClient.GetPush();
MainActivity.CurrentActivity.RunOnUiThread(() => Register(push, null));
}
public async void Register(Microsoft.WindowsAzure.MobileServices.Push push, IEnumerable<string> tags)
{
try
{
const string templateBodyGCM = "{\"data\":{\"message\":\"$(messageParam)\"}}";
JObject templates = new JObject();
templates["genericMessage"] = new JObject
{
{"body", templateBodyGCM}
};
await push.RegisterAsync(RegistrationID, templates);
Log.Info("Push Installation Id", push.InstallationId.ToString());
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
//Debugger.Break();
}
}
protected override void OnMessage(Context context, Intent intent)
{
Log.Info("PushHandlerBroadcastReceiver", "GCM Message Received!");
var msg = new StringBuilder();
if (intent != null && intent.Extras != null)
{
foreach (var key in intent.Extras.KeySet())
msg.AppendLine(key + "=" + intent.Extras.Get(key).ToString());
}
//Store the message
var prefs = GetSharedPreferences(context.PackageName, FileCreationMode.Private);
var edit = prefs.Edit();
edit.PutString("last_msg", msg.ToString());
edit.Commit();
string message = intent.Extras.GetString("message");
if (!string.IsNullOrEmpty(message))
{
createNotification("New todo item!", "Todo item: " + message);
return;
}
string msg2 = intent.Extras.GetString("msg");
if (!string.IsNullOrEmpty(msg2))
{
createNotification("New hub message!", msg2);
return;
}
createNotification("Unknown message details", msg.ToString());
}
void createNotification(string title, string desc)
{
//Create notification
var notificationManager = GetSystemService(Context.NotificationService) as NotificationManager;
//Create an intent to show ui
var uiIntent = new Intent(this, typeof(MainActivity));
//Use Notification Builder
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
//Create the notification
//we use the pending intent, passing our ui intent over which will get called
//when the notification is tapped.
var notification = builder.SetContentIntent(PendingIntent.GetActivity(this, 0, uiIntent, 0))
.SetSmallIcon(Android.Resource.Drawable.SymActionEmail)
.SetTicker(title)
.SetContentTitle(title)
.SetContentText(desc)
//Set the notification sound
.SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Notification))
//Auto cancel will remove the notification once the user touches it
.SetAutoCancel(true).Build();
//Show the notification
notificationManager.Notify(1, notification);
}
protected override void OnUnRegistered(Context context, string registrationId)
{
Log.Error("PushHandlerBroadcastReceiver", "Unregistered RegisterationId : " + registrationId);
}
protected override void OnError(Context context, string errorId)
{
Log.Error("PushHandlerBroadcastReceiver", "GCM Error: " + errorId);
}
}
} |
코드 중 "public static string[] SENDER_IDS = new string[] { "<PROJECT_NUMBER>" };" 에서 <PROJECT_NUMBER> 는 앞에서 설정한 Google Cloud Message 에서 "발신자 ID" 을 입력 합니다.
모든 코드의 추가 및 수정이 끝났습니다. 프로젝트를 빌드합니다.
- Android Emulator 설정
Visual Studio for Mac 에서는 Android 최신 버전 Emulator 를 사용 하기 위해서 아래와 같이 설정 합니다.
메뉴 에서 "도구 > Google 에뮬레이터 관리자" 를 선택합니다.
"Google 에뮬레이터 관리자" 창이 나타나면 메뉴 바에 "Tools" 가 나타납니다. 마우스 오른쪽 버튼으로 클릭하면 나타나는 "Manag SDK…" 를 클릭합니다.
아래 그림을 보시면 Android 8.0.0(API 26) 및 Android 7.1.1 (API 25) 이 모두 Installed로 되어있습니다. 하지만, 처음 Visual Studio for Mac 을 설치 했을 경우에는 Install 되어 있지 않습니다. Android 최신 버전을 테스트 하기 위해서 설치 합니다.
에뮬레이터 설치 후 메뉴에서 "도구 > SDK Manager" 를 선택합니다.
아래 그림과 같이 "플랫폼" 탭에서 사용 하고자 하는 버전의 Image 및 SDK 를 선택하고 "변경 내용 저장" 버튼을 클릭하면 설치됩니다.
- Notification Hub 테스트
테스트를 위해 Azure Portal 로 이동 하여 생성 해둔 "알림 허브"을 선택 합니다.
"알림 서비스"를 선택하면 여러 플랫폼이 나타납니다. 여기서 "Google(GCM)" 을 선택합니다.
Google 에서 GCM 생성 후 "서버 키" 를 입력 하고 "저장" 버튼을 클릭합니다.
프로젝트를 빌드 후에 Emulator 에서 실행 합니다. 실행 하면 Mobile App 이 실행 됩니다.
에디터에 글을 입력 하고 오른 쪽 "+" 를 클릭하면 데이터가 Azure에 생성 해 둔 DB에 저장되고 Emulator 에는 알림 메시가 발생합니다.
정상 적으로 Notification 메시지가 발생 하는 것을 확인 할 수 있습니다.
추가한 데이터를 확인하려면 Azure Portal 에서 생성한 App service를 선택해서 "간편한 테이블"을 클릭해서 볼 수도 있습니다.
테이블 조작 등 컨트롤을 원하면 App service를 생성하면서 함께 생성한 "SQL 데이터베이스"(SQL DB VM 이 아닙니다.)를 선택 합니다. 그리고 "개요"에서 상단의 "도두"를 클릭합니다.
아래와 같이 화면이 나타나면 "Visual Studio에서 열기" 를 클릭하고 "Visual Studio에서 열기" 버튼을 클릭합니다.
"쿼리 편집기(미리 보기)" 는 비용이 발생 할 수 있으므로 확인 후 사용 하십시오.
Visual Studio 에서 해당 테이블을 열면 확인 할 수 있습니다.
'Microsoft Azure > Web + Mobile' 카테고리의 다른 글
Azure Notification Hub : Xamarin.Forms 을 이용한 Mobile App 개발(iOS)-3 (0) | 2017.11.21 |
---|---|
Azure Notification Hub : Xamarin.Forms 을 이용한 Mobile App 개발(구성 및 Back-end)-1 (0) | 2017.11.21 |
Azure Notification Hub 구성 (0) | 2017.11.14 |