자습서: Azure Notification Hubs 및 Google Cloud Messaging을 사용하여 특정 Android 디바이스에 알림 푸시(더 이상 사용되지 않음)Tutorial: Push notifications to specific Android devices using Azure Notification Hubs and Google Cloud Messaging (deprecated)

경고

2018년 4월 10일 기준으로 Google은 GCM(Google Cloud Messaging)을 더 이상 지원하지 않습니다.As of April 10, 2018, Google has deprecated Google Cloud Messaging (GCM). GCM 서버 및 클라이언트 API는 더 이상 사용되지 않으며 2019년 5월 29일에 제거될 예정입니다.The GCM server and client APIs are deprecated and will be removed as soon as May 29, 2019. 자세한 내용은 GCM 및 FCM 질문과 대답을 참조하세요.For more information, see GCM and FCM Frequently Asked Questions.

개요Overview

이 자습서에서는 Azure Notification Hubs를 사용하여 Android 앱에 속보 알림을 브로드캐스트하는 방법을 보여줍니다.This tutorial shows you how to use Azure Notification Hubs to broadcast breaking news notifications to an Android app. 완료하면, 관심이 있는 속보 범주를 등록하고 해당 범주의 푸시 알림만 받을 수 있습니다.When complete, you will be able to register for breaking news categories you are interested in, and receive only push notifications for those categories. 이 시나리오는 RSS 수집기, 음악 애호가를 위한 앱 등 이전에 관심을 보인 사용자 그룹에 알림을 보내야 하는 많은 앱에 공통된 패턴입니다.This scenario is a common pattern for many apps where notifications have to be sent to groups of users that have previously declared interest in them, for example, RSS reader, apps for music fans, etc.

브로드캐스트 시나리오를 사용하려면 알림 허브에서 등록을 만들 때 하나 이상의 태그를 포함하면 됩니다.Broadcast scenarios are enabled by including one or more tags when creating a registration in the notification hub. 태그에 알림이 전송되면 태그에 대해 등록된 모든 디바이스에서 알림을 받게 됩니다.When notifications are sent to a tag, all devices that have registered for the tag will receive the notification. 태그는 단순히 문자열이므로 사전에 프로비전해야 할 필요가 없습니다.Because tags are simply strings, they do not have to be provisioned in advance. 태그에 대한 자세한 내용은 Notification Hubs 라우팅 및 태그 식을 참조하세요.For more information about tags, see Notification Hubs Routing and Tag Expressions.

이 자습서에서는 다음 작업을 수행합니다.In this tutorial, you do the following actions:

  • 모바일 앱에 범주 선택 추가Add category selection to the mobile app.
  • 태그를 사용하여 알림 등록Registered for notifications with tags.
  • 태그가 지정된 알림 보내기Send tagged notifications.
  • 앱 테스트Test the app

필수 조건Prerequisites

이 자습서는 자습서: Azure Notification Hubs 및 Google Cloud Messaging을 사용하여 Android 디바이스에 알림 푸시에서 만든 알림 허브를 기반으로 합니다.This tutorial builds on the app you created in Tutorial: Push notifications to Android devices by using Azure Notification Hubs and Google Cloud Messaging. 이 자습서를 시작하기 전에 자습서: Azure Notification Hubs 및 Google Cloud Messaging을 사용하여 Android 디바이스에 알림 푸시에서 만든 알림 허브를 기반으로 합니다.Before starting this tutorial, complete the Tutorial: Push notifications to Android devices by using Azure Notification Hubs and Google Cloud Messaging.

앱에 범주 선택 추가Add category selection to the app

첫 번째 단계는 기존의 기본 활동에 사용자가 등록할 범주를 선택할 수 있도록 하는 UI 요소를 추가하는 것입니다.The first step is to add the UI elements to your existing main activity that enable the user to select categories to register. 사용자가 선택한 범주는 디바이스에 저장됩니다.The categories selected by a user are stored on the device. 앱을 시작하면 디바이스 등록이 선택한 범주와 함께 태그로서 알림 허브에 생성됩니다.When the app starts, a device registration is created in your notification hub with the selected categories as tags.

  1. res/layout/activity_main.xml file을 열고 콘텐츠를 다음으로 바꿉니다.Open the res/layout/activity_main.xml file, and replace the content with the following:

    <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"
        tools:context="com.example.breakingnews.MainActivity"
        android:orientation="vertical">
    
            <CheckBox
                android:id="@+id/worldBox"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/label_world" />
            <CheckBox
                android:id="@+id/politicsBox"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/label_politics" />
            <CheckBox
                android:id="@+id/businessBox"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/label_business" />
            <CheckBox
                android:id="@+id/technologyBox"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/label_technology" />
            <CheckBox
                android:id="@+id/scienceBox"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/label_science" />
            <CheckBox
                android:id="@+id/sportsBox"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/label_sports" />
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="subscribe"
                android:text="@string/button_subscribe" />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Hello World!"
                android:id="@+id/text_hello"
            />
    </LinearLayout>
    
  2. res/values/strings.xml 파일을 열고 다음 줄을 추가합니다.Open the res/values/strings.xml file and add the following lines:

    <string name="button_subscribe">Subscribe</string>
    <string name="label_world">World</string>
    <string name="label_politics">Politics</string>
    <string name="label_business">Business</string>
    <string name="label_technology">Technology</string>
    <string name="label_science">Science</string>
    <string name="label_sports">Sports</string>
    

    main_activity.xml 그래픽 레이아웃은 다음 이미지와 같이 표시되어야 합니다.Your main_activity.xml graphical layout should look like in the following image:

  3. MainActivity 클래스와 동일한 패키지에서 Notifications 클래스를 만듭니다.Create a class Notifications in the same package as your MainActivity class.

    import java.util.HashSet;
    import java.util.Set;
    
    import android.content.Context;
    import android.content.SharedPreferences;
    import android.os.AsyncTask;
    import android.util.Log;
    import android.widget.Toast;
    import android.view.View;
    
    import com.google.android.gms.gcm.GoogleCloudMessaging;
    import com.microsoft.windowsazure.messaging.NotificationHub;
    
    public class Notifications {
        private static final String PREFS_NAME = "BreakingNewsCategories";
        private GoogleCloudMessaging gcm;
        private NotificationHub hub;
        private Context context;
        private String senderId;
    
        public Notifications(Context context, String senderId, String hubName,
                                String listenConnectionString) {
            this.context = context;
            this.senderId = senderId;
    
            gcm = GoogleCloudMessaging.getInstance(context);
            hub = new NotificationHub(hubName, listenConnectionString, context);
        }
    
        public void storeCategoriesAndSubscribe(Set<String> categories)
        {
            SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
            settings.edit().putStringSet("categories", categories).commit();
            subscribeToCategories(categories);
        }
    
        public Set<String> retrieveCategories() {
            SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
            return settings.getStringSet("categories", new HashSet<String>());
        }
    
        public void subscribeToCategories(final Set<String> categories) {
            new AsyncTask<Object, Object, Object>() {
                @Override
                protected Object doInBackground(Object... params) {
                    try {
                        String regid = gcm.register(senderId);
    
                        String templateBodyGCM = "{\"data\":{\"message\":\"$(messageParam)\"}}";
    
                        hub.registerTemplate(regid,"simpleGCMTemplate", templateBodyGCM,
                            categories.toArray(new String[categories.size()]));
                    } catch (Exception e) {
                        Log.e("MainActivity", "Failed to register - " + e.getMessage());
                        return e;
                    }
                    return null;
                }
    
                protected void onPostExecute(Object result) {
                    String message = "Subscribed for categories: "
                            + categories.toString();
                    Toast.makeText(context, message,
                            Toast.LENGTH_LONG).show();
                }
            }.execute(null, null, null);
        }
    
    }
    

    이 클래스는 로컬 스토리지를 사용하여, 이 디바이스에서 받아야 할 뉴스의 범주를 저장합니다.This class uses the local storage to store the categories of news that this device has to receive. 이러한 범주를 등록하기 위한 메서드도 이 클래스에 포함됩니다.It also contains methods to register for these categories.

  4. MainActivity 클래스에서 NotificationHubGoogleCloudMessaging에 대한 프라이빗 필드를 제거하고 Notifications에 대한 필드를 추가합니다.In your MainActivity class remove your private fields for NotificationHub and GoogleCloudMessaging, and add a field for Notifications:

    // private GoogleCloudMessaging gcm;
    // private NotificationHub hub;
    private Notifications notifications;
    
  5. 그런 다음, onCreate 메서드에서 hub 필드 및 registerWithNotificationHubs 메서드의 초기화를 제거합니다.Then, in the onCreate method, remove the initialization of the hub field and the registerWithNotificationHubs method. 그런 다음, Notifications 클래스의 인스턴스를 초기화하는 다음 줄을 추가합니다.Then add the following lines, which initialize an instance of the Notifications class.

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mainActivity = this;
    
        NotificationsManager.handleNotifications(this, NotificationSettings.SenderId,
                MyHandler.class);
    
        notifications = new Notifications(this, NotificationSettings.SenderId, NotificationSettings.HubName, NotificationSettings.HubListenConnectionString);
    
        notifications.subscribeToCategories(notifications.retrieveCategories());
    }
    

    NotificationSettings 클래스에서 허브 이름 및 연결 문자열이 올바르게 설정되어 있는지 확인합니다.Confirm that the hub name and the connection string are set properly in the NotificationSettings class.

    참고

    클라이언트 앱과 함께 배포되는 자격 증명은 일반적으로 안전하지 않기 때문에 클라이언트 앱과 함께 listen access용 키만 배포해야 합니다.Because credentials that are distributed with a client app are not generally secure, you should only distribute the key for listen access with your client app. Listen access를 통해 앱에서 알림을 등록할 수 있지만, 기존 등록을 수정할 수 없으며 알림을 전송할 수도 없습니다.Listen access enables your app to register for notifications, but existing registrations cannot be modified and notifications cannot be sent. 안전한 백 엔드 서비스에서 알림을 보내고 기존 등록을 변경하는 데에는 모든 액세스 키가 사용됩니다.The full access key is used in a secured backend service for sending notifications and changing existing registrations.

  6. 그런 다음, 다음 가져오기를 추가합니다.Then, add the following imports:

    import android.widget.CheckBox;
    import java.util.HashSet;
    import java.util.Set;
    
  7. 다음 subscribe 메서드를 추가하여 구독 단추 클릭 이벤트를 처리합니다.Add the following subscribe method to handle the subscribe button click event:

    public void subscribe(View sender) {
        final Set<String> categories = new HashSet<String>();
    
        CheckBox world = (CheckBox) findViewById(R.id.worldBox);
        if (world.isChecked())
            categories.add("world");
        CheckBox politics = (CheckBox) findViewById(R.id.politicsBox);
        if (politics.isChecked())
            categories.add("politics");
        CheckBox business = (CheckBox) findViewById(R.id.businessBox);
        if (business.isChecked())
            categories.add("business");
        CheckBox technology = (CheckBox) findViewById(R.id.technologyBox);
        if (technology.isChecked())
            categories.add("technology");
        CheckBox science = (CheckBox) findViewById(R.id.scienceBox);
        if (science.isChecked())
            categories.add("science");
        CheckBox sports = (CheckBox) findViewById(R.id.sportsBox);
        if (sports.isChecked())
            categories.add("sports");
    
        notifications.storeCategoriesAndSubscribe(categories);
    }
    

    이 메서드는 범주 목록을 만들고 Notifications 클래스를 사용하여, 로컬 스토리지에 목록을 저장하고 알림 허브에 해당 태그를 등록합니다.This method creates a list of categories and uses the Notifications class to store the list in the local storage and register the corresponding tags with your notification hub. 범주가 변경되면 새 범주로 등록이 다시 생성됩니다.When categories are changed, the registration is recreated with the new categories.

이제 사용자가 범주 선택을 변경할 때마다 앱은 범주 집합을 디바이스의 로컬 스토리지에 저장하고 알림 허브에 등록할 수 있습니다.Your app is now able to store a set of categories in local storage on the device and register with the notification hub whenever the user changes the selection of categories.

알림 등록Register for notifications

다음 단계에서는 로컬 스토리지에 저장된 범주를 사용하여 시작 시 알림 허브에 등록합니다.These steps register with the notification hub on startup using the categories that have been stored in local storage.

참고

GCM(Google Cloud Messaging)에서 할당하는 registrationId는 언제든지 변경될 수 있으므로 알림 실패를 피하려면 알림을 자주 등록해야 합니다.Because the registrationId assigned by Google Cloud Messaging (GCM) can change at any time, you should register for notifications frequently to avoid notification failures. 이 예제에서는 앱이 시작될 때마다 알림을 등록합니다.This example registers for notification every time that the app starts. 자주(하루 두 번 이상) 실행되는 앱에서는 이전 등록 이후 만 하루가 지나지 않은 경우 대역폭 유지를 위한 등록을 건너뛸 수 있습니다.For apps that are run frequently, more than once a day, you can probably skip registration to preserve bandwidth if less than a day has passed since the previous registration.

  1. MainActivity 클래스의 onCreate 메서드 끝에 다음 코드를 추가합니다.Add the following code at the end of the onCreate method in the MainActivity class:

    notifications.subscribeToCategories(notifications.retrieveCategories());
    

    이 코드를 통해 앱이 시작될 때마다 로컬 스토리지에서 범주를 검색하고, 이러한 범주에 대한 등록을 요청하게 됩니다.This code makes sure that every time the app starts it retrieves the categories from local storage and requests a registration for these categories.

  2. 그런 후 다음과 같이 MainActivity 클래스의 onStart() 메서드를 업데이트합니다.Then update the onStart() method of the MainActivity class as follows:

    @Override
    protected void onStart() {
    
        super.onStart();
        isVisible = true;
    
        Set<String> categories = notifications.retrieveCategories();
    
        CheckBox world = (CheckBox) findViewById(R.id.worldBox);
        world.setChecked(categories.contains("world"));
        CheckBox politics = (CheckBox) findViewById(R.id.politicsBox);
        politics.setChecked(categories.contains("politics"));
        CheckBox business = (CheckBox) findViewById(R.id.businessBox);
        business.setChecked(categories.contains("business"));
        CheckBox technology = (CheckBox) findViewById(R.id.technologyBox);
        technology.setChecked(categories.contains("technology"));
        CheckBox science = (CheckBox) findViewById(R.id.scienceBox);
        science.setChecked(categories.contains("science"));
        CheckBox sports = (CheckBox) findViewById(R.id.sportsBox);
        sports.setChecked(categories.contains("sports"));
    }
    

    이 코드는 이전에 저장한 범주의 상태를 기반으로 기본 활동을 업데이트합니다.This code updates the main activity based on the status of previously saved categories.

이제 앱이 완료되며, 사용자가 범주 선택을 변경할 때마다 알림 허브 등록에 사용된 디바이스의 로컬 스토리지에 범주 집합을 저장할 수 있습니다.The app is now complete and can store a set of categories in the device local storage used to register with the notification hub whenever the user changes the selection of categories. 다음에는 범주 알림을 이 앱에 보낼 수 있는 백 엔드를 정의합니다.Next, define a backend that can send category notifications to this app.

태그가 지정된 알림 보내기Send tagged notifications

이 섹션에서는 .NET 콘솔 앱에서 태그가 지정된 템플릿 알림으로 속보를 보냅니다.In this section, you send breaking news as tagged template notifications from a .NET console app.

  1. Visual Studio에서 다음과 같이 새로운 Visual C# 콘솔 애플리케이션을 만듭니다.In Visual Studio, create a new Visual C# console application:

    1. 메뉴에서 파일 > 새로 만들기 > 프로젝트를 선택합니다.On the menu, select File > New > Project.
    2. 새 프로젝트 만들기의 템플릿 목록에서 C#용 콘솔 앱(.NET Framework) 을 선택하고 다음을 선택합니다.In Create a new project, select Console App (.NET Framework) for C# in the list of templates, and select Next.
    3. 앱의 이름을 입력합니다.Enter a name for the app.
    4. 솔루션의 경우 솔루션에 추가를 선택하고 만들기를 선택하여 프로젝트를 만듭니다.For Solution, choose Add to solution, and select Create to create the project.
  2. 도구 > NuGet 패키지 관리자 > 패키지 관리자 콘솔을 선택한 다음, 콘솔 창에서 다음 명령을 실행합니다.Select Tools > NuGet Package Manager > Package Manager Console and then, in the console window, run the following command:

    Install-Package Microsoft.Azure.NotificationHubs
    

    이 작업은 Microsoft.Azure.NotificationHubs 패키지를 사용하여 Azure Notification Hubs SDK에 대한 참조를 추가합니다.This action adds a reference to the Azure Notification Hubs SDK by using the Microsoft.Azure.NotificationHubs package.

  3. Program.cs 파일을 열고 다음 using 문을 추가합니다.Open the Program.cs file, and add the following using statement:

    using Microsoft.Azure.NotificationHubs;
    
  4. Program 클래스에서 다음 메서드를 추가하거나 이미 있으면 바꿉니다.In the Program class, add the following method, or replace it if it already exists:

    private static async void SendTemplateNotificationAsync()
    {
        // Define the notification hub.
        NotificationHubClient hub = NotificationHubClient.CreateClientFromConnectionString("<connection string with full access>", "<hub name>");
    
        // Apple requires the apns-push-type header for all requests
        var headers = new Dictionary<string, string> {{"apns-push-type", "alert"}};
    
        // Create an array of breaking news categories.
        var categories = new string[] { "World", "Politics", "Business", "Technology", "Science", "Sports"};
    
        // Send the notification as a template notification. All template registrations that contain
        // "messageParam" and the proper tags will receive the notifications.
        // This includes APNS, GCM/FCM, WNS, and MPNS template registrations.
    
        Dictionary<string, string> templateParams = new Dictionary<string, string>();
    
        foreach (var category in categories)
        {
            templateParams["messageParam"] = "Breaking " + category + " News!";
            await hub.SendTemplateNotificationAsync(templateParams, category);
        }
    }
    

    이 코드는 문자열 배열에 있는 6개의 각 태그에 대한 템플릿 알림을 보냅니다.This code sends a template notification for each of the six tags in the string array. 태그를 사용하면 등록된 범주의 알림만 디바이스에서 받습니다.The use of tags ensures that devices receive notifications only for the registered categories.

  5. 위의 코드에서 <hub name><connection string with full access> 자리 표시자를 알림 허브 이름과 알림 허브의 대시보드에서 얻은 DefaultFullSharedAccessSignature의 연결 문자열로 바꿔야 합니다.In the preceding code, replace the <hub name> and <connection string with full access> placeholders with your notification hub name and the connection string for DefaultFullSharedAccessSignature from the dashboard of your notification hub.

  6. Main() 메서드에 다음 줄을 추가합니다.In the Main() method, add the following lines:

     SendTemplateNotificationAsync();
     Console.ReadLine();
    
  7. 콘솔 앱을 시작합니다.Build the console app.

앱 테스트Test the app

  1. Android Studio의 Android 디바이스 또는 에뮬레이터에서 앱을 실행합니다.In Android Studio, run the app on your Android device or emulator. 앱 UI는 구독할 범주를 선택하도록 하는 토글 집합을 제공합니다.The app UI provides a set of toggles that lets you choose the categories to subscribe to.

  2. 하나 이상의 범주 토글을 사용하도록 설정한 후 구독을 클릭합니다.Enable one or more categories toggles, then click Subscribe. 앱은 선택한 범주를 태그로 변환하고 알림 허브에서 선택한 태그에 대한 새로운 디바이스 등록을 요청합니다.The app converts the selected categories into tags and requests a new device registration for the selected tags from the notification hub. 등록된 범주가 반환되어 알림 메시지에 표시됩니다.The registered categories are returned and displayed in a toast notification.

    범주에 대한 구독

  3. 각 범주에 대한 알림을 전송하는 .NET 콘솔 앱을 실행합니다.Run the .NET console app, which sends notifications for each category. 선택한 범주에 대한 알림이 알림 메시지로 나타납니다.Notifications for the selected categories appear as toast notifications.

    기술 뉴스 알림

다음 단계Next steps

이 자습서에서는 범주에 등록한 특정 Android 디바이스에 브로드캐스트 알림을 보냈습니다.In this tutorial, you sent broadcast notifications to specific Android devices that have registered for the categories. 특정 사용자에게 알림을 푸시하는 방법을 알아보려면 다음 자습서를 계속 진행합니다.To learn how to push notifications to specific users, advance to the following tutorial: