Share via


Xamarin.Android 앱에 푸시 알림 추가

개요

이 자습서에서는 푸시 알림을 Xamarin.Android 빠른 시작 프로젝트에 추가하여 레코드가 삽입될 때마다 디바이스에 푸시 알림이 전송됩니다.

다운로드한 빠른 시작 서버 프로젝트를 사용하지 않는 경우 푸시 알림 확장 패키지가 필요합니다. 자세한 내용은 Azure Mobile Apps용 .NET 백 엔드 서버 SDK 사용 가이드를 참조하세요.

필수 구성 요소

이 자습서에는 다음 설정이 필요합니다.

알림 허브 구성

Azure App Service의 Mobile Apps 기능은 Azure Notification Hubs를 사용하여 푸시를 보내므로 모바일 앱에 대해 알림 허브가 구성됩니다.

  1. Azure Portal에서 App Services로 이동한 다음, 앱 백 엔드를 선택합니다. 설정에서 푸시를 선택합니다.

  2. 앱에 알림 허브 리소스를 추가하려면 연결을 선택합니다. 허브를 만들거나 기존 허브에 연결할 수 있습니다.

    허브 구성

이제 알림 허브를 Mobile Apps 백 엔드 프로젝트에 연결했습니다. 나중에 디바이스에 푸시하는 PNS(플랫폼 알림 시스템)에 연결하도록 이 알림 허브를 구성합니다.

Firebase Cloud Messaging 사용

  1. Firebase 콘솔에 로그인합니다. 아직 없는 경우 새 Firebase 프로젝트를 만듭니다.

  2. 프로젝트를 만든 후 Android 앱에 Firebase 추가를 선택합니다.

    Android 앱에 Firebase 추가

  3. Android 앱에 Firebase 추가 페이지에서 다음 단계를 수행합니다.

    1. Android 패키지 이름에서 애플리케이션의 build.gradle 파일에 있는 applicationId 값을 복사합니다. 이 예에서는 com.fabrikam.fcmtutorial1app입니다.

      패키지 이름 지정

    2. 앱 등록을 선택합니다.

  4. google-services.json 다운로드를 선택하고 프로젝트의 app 폴더에 파일을 저장한 후 다음을 선택합니다.

    google-services.json 다운로드

  5. Android Studio의 프로젝트에서 다음과 같은 구성 변경 작업을 수행합니다.

    1. project-level build.gradle 파일(<project>/build.gradle)에서 dependencies 섹션에 다음 명령문을 추가합니다.

      classpath 'com.google.gms:google-services:4.0.1'
      
    2. app-level build.gradle 파일(<project>/<app-module>/build.gradle)에서 dependencies 섹션에 다음 명령문을 추가합니다.

      implementation 'com.google.firebase:firebase-core:16.0.8'
      implementation 'com.google.firebase:firebase-messaging:17.3.4'
      
    3. app-level build.gradle 파일 끝부분에서 dependenices 섹션 다음에 다음 줄을 추가합니다.

      apply plugin: 'com.google.gms.google-services'
      
    4. 도구 모음에서 지금 동기화를 선택합니다.

      build.gradle 구성 변경

  6. 다음을 선택합니다.

  7. 이 단계 건너뛰기를 선택합니다.

    마지막 단계 건너뛰기

  8. Firebase 콘솔에서 프로젝트의 톱니바퀴를 선택합니다. 그런 후 프로젝트 설정을 선택합니다.

    프로젝트 설정 선택

  9. Android Studio 프로젝트의 app 폴더에 google-services.json 파일을 다운로드하지 않은 경우 이 페이지에서 다운로드할 수 있습니다.

  10. 맨 위에 있는 클라우드 메시징 탭으로 전환합니다.

  11. 나중에 사용하기 위해 서버 키를 복사하고 저장합니다. 이 값을 사용하여 허브를 구성합니다.

푸시 요청을 전송하도록 Azure 구성

  1. Azure Portal에서 모두 찾아보기>App Services > Mobile Apps 백 엔드를 클릭합니다. 설정 아래에서 App Service 푸시를 클릭한 후 알림 허브 이름을 클릭합니다.

  2. Google(GCM)로 이동하고, 이전 절차에서 Firebase로부터 얻은 Server Key 값을 입력한 다음 저장을 클릭합니다.

    포털에서 API 키 설정

이제 Mobile Apps 백 엔드가 Firebase Cloud Messaging을 사용하도록 구성됩니다. 알림 허브를 사용하여 Android 디바이스에서 실행 중인 앱에 푸시 알림을 보낼 수 있습니다.

푸시 알림을 전송하도록 서버 프로젝트 업데이트

이 섹션에서는 새 항목이 추가될 때마다 푸시 알림을 보내도록 기존 Mobile Apps 백 엔드 프로젝트의 코드를 업데이트합니다. 이 프로세스는 플랫폼 간 푸시를 구현하는 Azure Notification Hubs의 템플릿 기능으로 구동됩니다. 템플릿을 사용한 푸시 알림에 대해 다양한 클라이언트가 등록되며 단일 범용 푸시를 통해 모든 클라이언트 플랫폼을 가져올 수 있습니다.

백 엔드 프로젝트 유형( .NET 백 엔드 또는 Node.js 백 엔드)과 일치하는 다음 절차 중 하나를 선택합니다.

.NET 백 엔드 프로젝트

  1. Visual Studio에서 서버 프로젝트를 마우스 오른쪽 단추로 클릭합니다. 그런 다음, NuGet 패키지 관리를 클릭합니다. Microsoft.Azure.NotificationHubs를 검색한 다음, 설치를 선택합니다. 이 프로세스는 백 엔드에서 알림을 보내기 위한 Notification Hubs 라이브러리를 설치합니다.

  2. 서버 프로젝트에서 컨트롤러>TodoItemController.cs를 엽니다. 그런 다음, 명령문을 사용하여 다음을 추가합니다.

    using System.Collections.Generic;
    using Microsoft.Azure.NotificationHubs;
    using Microsoft.Azure.Mobile.Server.Config;
    
  3. PostTodoItem 메서드에서 InsertAsync에 대한 호출 뒤에 다음 코드를 추가합니다.

    // Get the settings for the server project.
    HttpConfiguration config = this.Configuration;
    MobileAppSettingsDictionary settings =
        this.Configuration.GetMobileAppSettingsProvider().GetMobileAppSettings();
    
    // Get the Notification Hubs credentials for the mobile app.
    string notificationHubName = settings.NotificationHubName;
    string notificationHubConnection = settings
        .Connections[MobileAppSettingsKeys.NotificationHubConnectionString].ConnectionString;
    
    // Create a new Notification Hub client.
    NotificationHubClient hub = NotificationHubClient
    .CreateClientFromConnectionString(notificationHubConnection, notificationHubName);
    
    // Send the message so that all template registrations that contain "messageParam"
    // receive the notifications. This includes APNS, GCM, WNS, and MPNS template registrations.
    Dictionary<string,string> templateParams = new Dictionary<string,string>();
    templateParams["messageParam"] = item.Text + " was added to the list.";
    
    try
    {
        // Send the push notification and log the results.
        var result = await hub.SendTemplateNotificationAsync(templateParams);
    
        // Write the success result to the logs.
        config.Services.GetTraceWriter().Info(result.State.ToString());
    }
    catch (System.Exception ex)
    {
        // Write the failure result to the logs.
        config.Services.GetTraceWriter()
            .Error(ex.Message, null, "Push.SendAsync Error");
    }
    

    이 프로세스는 새 항목이 삽입된 경우 item.Text가 포함된 템플릿 알림을 보냅니다.

  4. 서버 프로젝트를 다시 게시합니다.

백 엔드 프로젝트 Node.js

  1. 백 엔드 프로젝트를 설정합니다.

  2. todoitem.js의 기존 코드를 다음 코드로 바꿉니다.

    var azureMobileApps = require('azure-mobile-apps'),
    promises = require('azure-mobile-apps/src/utilities/promises'),
    logger = require('azure-mobile-apps/src/logger');
    
    var table = azureMobileApps.table();
    
    table.insert(function (context) {
    // For more information about the Notification Hubs JavaScript SDK,
    // see https://aka.ms/nodejshubs.
    logger.info('Running TodoItem.insert');
    
    // Define the template payload.
    var payload = '{"messageParam": "' + context.item.text + '" }';  
    
    // Execute the insert. The insert returns the results as a promise.
    // Do the push as a post-execute action within the promise flow.
    return context.execute()
        .then(function (results) {
            // Only do the push if configured.
            if (context.push) {
                // Send a template notification.
                context.push.send(null, payload, function (error) {
                    if (error) {
                        logger.error('Error while sending push notification: ', error);
                    } else {
                        logger.info('Push notification sent successfully!');
                    }
                });
            }
            // Don't forget to return the results from the context.execute().
            return results;
        })
        .catch(function (error) {
            logger.error('Error while running context.execute: ', error);
        });
    });
    
    module.exports = table;  
    

    이 프로세스는 새 항목이 삽입된 경우 item.text가 포함된 템플릿 알림을 보냅니다.

  3. 로컬 컴퓨터에서 파일을 편집할 때 서버 프로젝트를 다시 게시합니다.

푸시 알림에 대한 클라이언트 프로젝트 구성

  1. 솔루션 보기(또는 Visual Studio의 솔루션 탐색기)에서 구성 요소 폴더를 마우스 오른쪽 단추로 클릭하고 추가 구성 요소 가져오기...를 클릭하고 Google Cloud Messaging Client 구성 요소를 검색하여 프로젝트에 추가합니다.

  2. ToDoActivity.cs 프로젝트 파일을 열고 클래스에 다음 using 문을 추가합니다.

    using Gcm.Client;
    
  3. TodoActivity 클래스에 다음 새 코드를 추가합니다.

    // Create a new instance field for this activity.
    static ToDoActivity instance = new ToDoActivity();
    
    // Return the current activity instance.
    public static ToDoActivity CurrentActivity
    {
        get
        {
            return instance;
        }
    }
    // Return the Mobile Services client.
    public MobileServiceClient CurrentClient
    {
        get
        {
            return client;
        }
    }
    

    그러면 푸시 처리기 서비스 프로세스에서 모바일 클라이언트 인스턴스에 액세스할 수 있습니다.

  4. MobileServiceClient가 만들어지고 나면 다음 코드를 OnCreate 메서드에 추가합니다.

    // Set the current instance of TodoActivity.
    instance = this;
    
    // Make sure the GCM client is set up correctly.
    GcmClient.CheckDevice(this);
    GcmClient.CheckManifest(this);
    
    // Register the app for push notifications.
    GcmClient.Register(this, ToDoBroadcastReceiver.senderIDs);
    

이제 ToDoActivity 이 푸시 알림 추가를 위해 준비됩니다.

앱에 푸시 알림 코드 추가

  1. ToDoBroadcastReceiver(이)라는 프로젝트에서 새 클래스를 만듭니다.

  2. ToDoBroadcastReceiver 클래스에 다음 using 문을 추가합니다.

    using Gcm.Client;
    using Microsoft.WindowsAzure.MobileServices;
    using Newtonsoft.Json.Linq;
    
  3. using 문과 namespace 선언 사이에 다음 사용 권한 요청을 추가합니다.

    [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")]
    //GET_ACCOUNTS is only needed for android versions 4.0.3 and below
    [assembly: UsesPermission(Name = "android.permission.GET_ACCOUNTS")]
    [assembly: UsesPermission(Name = "android.permission.INTERNET")]
    [assembly: UsesPermission(Name = "android.permission.WAKE_LOCK")]
    
  4. 기존 ToDoBroadcastReceiver 클래스 정의를 다음으로 바꿉니다.

    [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 ToDoBroadcastReceiver : GcmBroadcastReceiverBase<PushHandlerService>
    {
        // Set the Google app ID.
        public static string[] senderIDs = new string[] { "<PROJECT_NUMBER>" };
    }
    

    위의 코드에서 Google 개발자 포털에서 앱을 프로비전할 때 Google에서 할당한 프로젝트 번호로 <PROJECT_NUMBER>을(를) 바꿉니다.

  5. ToDoBroadcastReceiver.cs 프로젝트 파일에서 PushHandlerService 클래스를 정의하는 다음 코드를 추가합니다.

    // The ServiceAttribute must be applied to the class.
    [Service]
    public class PushHandlerService : GcmServiceBase
    {
        public static string RegistrationID { get; private set; }
        public PushHandlerService() : base(ToDoBroadcastReceiver.senderIDs) { }
    }
    

    이 클래스는 GcmServiceBase에서 파생되며 Service 특성이 이 클래스에 적용되어야 합니다.

    참고

    GcmServiceBase 클래스는 OnRegistered(), OnUnRegistered(), OnMessage()OnError() 메서드를 구현합니다. PushHandlerService 클래스에서 이러한 메서드를 재정의해야 합니다.

  6. OnRegistered 이벤트 처리기를 재정의하는 PushHandlerService 클래스에 다음 코드를 추가합니다.

    protected override void OnRegistered(Context context, string registrationId)
    {
        System.Diagnostics.Debug.WriteLine("The device has been registered with GCM.", "Success!");
    
        // Get the MobileServiceClient from the current activity instance.
        MobileServiceClient client = ToDoActivity.CurrentActivity.CurrentClient;
        var push = client.GetPush();
    
        // Define a message body for GCM.
        const string templateBodyGCM = "{\"data\":{\"message\":\"$(messageParam)\"}}";
    
        // Define the template registration as JSON.
        JObject templates = new JObject();
        templates["genericMessage"] = new JObject
        {
            {"body", templateBodyGCM }
        };
    
        try
        {
            // Make sure we run the registration on the same thread as the activity, 
            // to avoid threading errors.
            ToDoActivity.CurrentActivity.RunOnUiThread(
    
                // Register the template with Notification Hubs.
                async () => await push.RegisterAsync(registrationId, templates));
    
            System.Diagnostics.Debug.WriteLine(
                string.Format("Push Installation Id", push.InstallationId.ToString()));
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(
                string.Format("Error with Azure push registration: {0}", ex.Message));
        }
    }
    

    이 메서드는 반환된 GCM 등록 ID를 사용하여 푸시 알림을 위해 Azure에 등록합니다. 생성된 후 등록에 태그만 추가할 수 있습니다. 자세한 내용은 방법: 태그에 푸시를 사용하도록 설정하기 위해 디바이스 설치에 태그 추가를 참조하세요.

  7. PushHandlerServiceOnMessage 메서드를 다음 코드로 재정의합니다.

    protected override void OnMessage(Context context, Intent intent)
    {
        string message = string.Empty;
    
        // Extract the push notification message from the intent.
        if (intent.Extras.ContainsKey("message"))
        {
            message = intent.Extras.Get("message").ToString();
            var title = "New item added:";
    
            // Create a notification manager to send the notification.
            var notificationManager = 
                GetSystemService(Context.NotificationService) as NotificationManager;
    
            // Create a new intent to show the notification in the UI. 
            PendingIntent contentIntent =
                PendingIntent.GetActivity(context, 0,
                new Intent(this, typeof(ToDoActivity)), 0);
    
            // Create the notification using the builder.
            var builder = new Notification.Builder(context);
            builder.SetAutoCancel(true);
            builder.SetContentTitle(title);
            builder.SetContentText(message);
            builder.SetSmallIcon(Resource.Drawable.ic_launcher);
            builder.SetContentIntent(contentIntent);
            var notification = builder.Build();
    
            // Display the notification in the Notifications Area.
            notificationManager.Notify(1, notification);
    
        }
    }
    
  8. 다음 코드를 사용하여 OnUnRegistered()OnError() 메서드를 재정의합니다.

    protected override void OnUnRegistered(Context context, string registrationId)
    {
        throw new NotImplementedException();
    }
    
    protected override void OnError(Context context, string errorId)
    {
        System.Diagnostics.Debug.WriteLine(
            string.Format("Error occurred in the notification: {0}.", errorId));
    }
    

앱에서 푸시 알림 테스트

에뮬레이터에서 가상 디바이스를 사용하여 앱을 테스트할 수 있습니다. 에뮬레이터에서 실행할 때 필요한 추가 구성 단계가 있습니다.

  1. 가상 디바이스는 AVD(Android 가상 디바이스) 관리자에서 Google API를 대상으로 설정해야 합니다.

  2. >설정> 추가 계정을 클릭하여 Android 디바이스에 Google계정을 추가한 다음, 프롬프트를 따릅니다.

  3. 이전처럼 todolist 앱을 실행하고 새 todo 항목을 삽입합니다. 이때 알림 아이콘이 알림 영역에 표시됩니다. 알림 서랍을 열어서 전체 알림 텍스트를 볼 수 있습니다.