Tutorial: Enviar notificações por push baseadas em localização com os Hubs de Notificação e o Bing Spatial Data
Neste tutorial, você aprenderá a entregar notificações por push baseadas na localização com os Hubs de Notificação do Azure e o Bing Spatial Data.
Neste tutorial, você deve executar as seguintes etapas:
- Configurar a fonte de dados
- Configurar o aplicativo UWP
- Configurar o back-end
- Enviar notificações por push de teste no aplicativo da UWP (Plataforma Universal do Windows)
Pré-requisitos
- Assinatura do Azure. Caso você não tenha uma assinatura do Azure, crie uma conta gratuita do Azure antes de começar.
- Visual Studio 2015 Atualização 1 ou posterior (Community Edition).
- Versão mais recente do SDK do Azure.
- Conta do Centro de Desenvolvimento do Bing Mapas (você pode criá-la gratuitamente e associá-la à sua conta da Microsoft).
Configurar a fonte de dados
Faça logon no Centro de Desenvolvimento do Bing Mapas.
Na barra de navegação superior, selecione Fontes de dados e selecione Gerenciar Fontes de Dados.
Se você não tiver uma fonte de dados, você verá um link para criar uma fonte de dados. Selecione Carregar os dados como uma fonte de dados. Você também pode usar o menu Fontes de dados>Carregar dados.
Crie um arquivo
NotificationHubsGeofence.pipe
no disco rígido com o seguinte conteúdo: Neste tutorial, use um arquivo de exemplo baseado em pipe que enquadra uma área da orla marítima de São Francisco:Bing Spatial Data Services, 1.0, TestBoundaries EntityID(Edm.String,primaryKey)|Name(Edm.String)|Longitude(Edm.Double)|Latitude(Edm.Double)|Boundary(Edm.Geography) 1|SanFranciscoPier|||POLYGON ((-122.389825 37.776598,-122.389438 37.773087,-122.381885 37.771849,-122.382186 37.777022,-122.389825 37.776598))
O arquivo de pipe representa esta entidade:
Na página Carregar uma fonte de dados, execute as seguintes ações:
Selecione pipe para Formato de dados.
Procure e selecione o arquivo
NotificationHubGeofence.pipe
que você criou na etapa anterior.Selecione o botão Carregar.
Observação
Poderá ser solicitada uma nova chave para a Chave Mestra, que é diferente da Chave de Consulta. Basta criar uma nova chave por meio do painel e atualizar a página de carregamento da fonte de dados.
Depois que você carregar o arquivo de dados, você deve certificar-se de que publicou a fonte de dados. Selecione Fontes de dados ->Gerenciar Fontes de Dados como você fez antes.
Selecione a fonte de dados na lista e escolha Publicar na coluna Ações.
Altere para a guia Fontes de Dados Publicadas e confirme se você vê sua fonte de dados na lista.
Selecione Editar. Você vê (em um relance) locais que você introduziu nos dados.
Neste ponto, o portal não mostrará os limites geográficos que criamos. Tudo o que você precisa é de uma confirmação de que o local especificado está na vizinhança certa.
Agora você tem todos os requisitos da fonte de dados. Para obter os detalhes na URL de solicitação para a chamada à API, no Centro de Desenvolvimento do Bing Mapas, escolha Fontes de dados e selecione Informações da Fonte de Dados.
A URL de consulta é o ponto de extremidade no qual você pode executar consultas para verificar se o dispositivo ainda está dentro dos limites de um local ou não. Para realizar essa verificação, simplesmente execute uma chamada GET na URL de consulta, com os seguintes parâmetros anexados:
?spatialFilter=intersects(%27POINT%20LONGITUDE%20LATITUDE)%27)&$format=json&key=QUERY_KEY
O Bing Mapas executa automaticamente os cálculos para ver se o dispositivo está dentro do geofence. Depois de executar a solicitação por meio de um navegador (ou cURL), você obterá uma resposta JSON padrão:
Essa resposta só acontece quando o ponto está realmente dentro dos limites designados. Caso contrário, você obterá um bucket vazio de resultados:
Configurar o aplicativo UWP
No Visual Studio, inicie um novo projeto do tipo Aplicativo em Branco (Universal do Windows) .
Uma vez concluída a criação do projeto, você deverá ter o agente para o próprio aplicativo. Agora vamos configurar tudo para a infraestrutura de isolamento geográfico. Como você vai usar os serviços do Bing para essa solução, há um ponto de extremidade de API REST público que permite consultar quadros de local específico:
http://spatial.virtualearth.net/REST/v1/data/
Especifique os parâmetros a seguir para fazer isso funcionar:
ID da Fonte de Dados e Nome da Fonte de Dados – na API do Bing Mapas, as fontes de dados contêm diversos metadados classificados, como locais e horas comerciais de operação.
Nome da Entidade – a entidade que você deseja usar como um ponto de referência para a notificação.
Chave de API do Bing Mapas – a chave que você obteve anteriormente quando criou a conta do Centro de Desenvolvimento do Bing.
Agora que a fonte de dados está pronta, você pode começar a trabalhar no aplicativo UWP.
Habilite serviços de localização para o seu aplicativo. Abra o arquivo
Package.appxmanifest
no Gerenciador de Soluções.Na guia de propriedades do pacote que acabou de abrir, alterne para a guia Recursos e selecione Local.
Crie uma nova pasta na solução denominada
Core
e adicione um novo arquivo a ela, chamadoLocationHelper.cs
:A classe
LocationHelper
tem um código para obter o local do usuário por meio da API do sistema:using System; using System.Threading.Tasks; using Windows.Devices.Geolocation; namespace NotificationHubs.Geofence.Core { public class LocationHelper { private static readonly uint AppDesiredAccuracyInMeters = 10; public async static Task<Geoposition> GetCurrentLocation() { var accessStatus = await Geolocator.RequestAccessAsync(); switch (accessStatus) { case GeolocationAccessStatus.Allowed: { Geolocator geolocator = new Geolocator { DesiredAccuracyInMeters = AppDesiredAccuracyInMeters }; return await geolocator.GetGeopositionAsync(); } default: { return null; } } } } }
Para saber mais sobre como obter o local do usuário em aplicativos UWP, confira Obter a localização do usuário.
Para verificar se a aquisição da localização está funcionando, abra o lado do código da página principal (
MainPage.xaml.cs
). Criar um novo manipulador de eventos para o eventoLoaded
no construtorMainPage
.public MainPage() { this.InitializeComponent(); this.Loaded += MainPage_Loaded; }
A implementação do manipulador de eventos é a seguinte:
private async void MainPage_Loaded(object sender, RoutedEventArgs e) { var location = await LocationHelper.GetCurrentLocation(); if (location != null) { Debug.WriteLine(string.Concat(location.Coordinate.Longitude, " ", location.Coordinate.Latitude)); } }
Executar o aplicativo e permitir que ele acesse seu local.
Assim que o aplicativo for iniciado, você deverá ser capaz de ver as coordenadas na janela Saída :
Agora você sabe que a aquisição de localização funciona, você pode remover o manipulador de eventos carregado se desejar, porque você não o usará mais.
A próxima etapa é capturar as alterações de localização. Na classe
LocationHelper
, adicione o manipulador de eventos paraPositionChanged
:geolocator.PositionChanged += Geolocator_PositionChanged;
A implementação mostra as coordenadas de localização na janela Saída:
private static async void Geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args) { await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { Debug.WriteLine(string.Concat(args.Position.Coordinate.Longitude, " ", args.Position.Coordinate.Latitude)); }); }
Configurar o back-end
Baixe o exemplo de back-end .NET do GitHub.
Quando o download for concluído, abra a pasta
NotifyUsers
e depois o arquivoNotifyUsers.sln
no Visual Studio.Defina o projeto
AppBackend
como o Projeto de Inicialização e inicie-o.O projeto já está configurado para enviar notificações por push para dispositivos de destino e, portanto, você precisa fazer somente duas coisas – especificar a cadeia de conexão correta para o hub de notificação e adicionar identificação de limite para enviar a notificação somente quando o usuário estiver dentro do limite geográfico.
Para configurar a cadeia de conexão, abra
Notifications.cs
na pastaModels
. A funçãoNotificationHubClient.CreateClientFromConnectionString
deve conter as informações sobre o hub de notificação que você pode obter no portal do Azure (examine a página Políticas de Acesso em Configurações). Salve o arquivo de configuração atualizado.Crie um modelo para o resultado da API do Bing Mapas. A maneira mais fácil de fazer isso é abrir a pasta
Models
e escolher Adicionar>Classe. Nomeie-oGeofenceBoundary.cs
. Depois, copie o JSON da resposta de API que você obteve na primeira seção. No Visual Studio, use Editar>Colar especial>Colar JSON como Classes.Dessa forma, você garante que o objeto será desserializado exatamente como foi pretendido. O conjunto de classes resultante deve ter a seguinte aparência:
namespace AppBackend.Models { public class Rootobject { public D d { get; set; } } public class D { public string __copyright { get; set; } public Result[] results { get; set; } } public class Result { public __Metadata __metadata { get; set; } public string EntityID { get; set; } public string Name { get; set; } public float Longitude { get; set; } public float Latitude { get; set; } public string Boundary { get; set; } public string Confidence { get; set; } public string Locality { get; set; } public string AddressLine { get; set; } public string AdminDistrict { get; set; } public string CountryRegion { get; set; } public string PostalCode { get; set; } } public class __Metadata { public string uri { get; set; } } }
Em seguida, abra
Controllers
>NotificationsController.cs
. Atualize a chamada Post para levar em consideração a latitude e a longitude do destino. Para isso, adicione duas cadeias de caracteres à assinatura da função –latitude
elongitude
.public async Task<HttpResponseMessage> Post(string pns, [FromBody]string message, string to_tag, string latitude, string longitude)
Crie uma nova classe no projeto chamado
ApiHelper.cs
– você a usa para a conexão com o Bing para criarmos pontos de verificação em interseções de limite. Implemente uma funçãoIsPointWithinBounds
conforme mostrado no código a seguir:public class ApiHelper { public static readonly string ApiEndpoint = "{YOUR_QUERY_ENDPOINT}?spatialFilter=intersects(%27POINT%20({0}%20{1})%27)&$format=json&key={2}"; public static readonly string ApiKey = "{YOUR_API_KEY}"; public static bool IsPointWithinBounds(string longitude,string latitude) { var json = new WebClient().DownloadString(string.Format(ApiEndpoint, longitude, latitude, ApiKey)); var result = JsonConvert.DeserializeObject<Rootobject>(json); if (result.d.results != null && result.d.results.Count() > 0) { return true; } else { return false; } } }
Importante
Substitua o ponto de extremidade de API pela URL de consulta obtida anteriormente do Centro de Desenvolvimento do Bing (o mesmo se aplica à chave de API).
Se houver resultados para a consulta, isso significa que o ponto especificado está nos limites da delimitação geográfica e, portanto, a função retorna
true
. Se não houver nenhum resultado, o Bing está dizendo que o ponto está fora do quadro de pesquisa e, portanto, a função retornafalse
.Em
NotificationsController.cs
, crie uma verificação logo antes da instrução switch:if (ApiHelper.IsPointWithinBounds(longitude, latitude)) { switch (pns.ToLower()) { case "wns": //// Windows 8.1 / Windows Phone 8.1 var toast = @"<toast><visual><binding template=""ToastText01""><text id=""1"">" + "From " + user + ": " + message + "</text></binding></visual></toast>"; outcome = await Notifications.Instance.Hub.SendWindowsNativeNotificationAsync(toast, userTag); // Windows 10 specific Action Center support toast = @"<toast><visual><binding template=""ToastGeneric""><text id=""1"">" + "From " + user + ": " + message + "</text></binding></visual></toast>"; outcome = await Notifications.Instance.Hub.SendWindowsNativeNotificationAsync(toast, userTag); break; } }
Teste de notificações por push no aplicativo UWP
No aplicativo UWP, agora você deve conseguir testar as notificações. Na classe
LocationHelper
, crie uma nova função –SendLocationToBackend
:public static async Task SendLocationToBackend(string pns, string userTag, string message, string latitude, string longitude) { var POST_URL = "http://localhost:8741/api/notifications?pns=" + pns + "&to_tag=" + userTag + "&latitude=" + latitude + "&longitude=" + longitude; using (var httpClient = new HttpClient()) { try { await httpClient.PostAsync(POST_URL, new StringContent("\"" + message + "\"", System.Text.Encoding.UTF8, "application/json")); } catch (Exception ex) { Debug.WriteLine(ex.Message); } } }
Observação
Defina o
POST_URL
para o local do seu aplicativo web implantado. Por enquanto, é possível executá-lo localmente, mas à medida que você trabalhar na implantação de uma versão pública, precisará hospedá-lo em um provedor externo.Registre o aplicativo UWP para notificações por push. No Visual Studio, escolha Projeto>Loja>Associar aplicativo à loja.
Depois que você entrar em sua conta de desenvolvedor, selecione um aplicativo existente ou crie um novo e associe o pacote a ele.
Vá para o Centro de Desenvolvimento e abra o aplicativo que você criou. Escolha Serviços>Notificações por Push>Site do Live Services.
No site, anote o Segredo do Aplicativo e o SID do Pacote. Você precisa deles no portal do Azure – abra seu hub de notificação, escolha Configurações>Serviços de Notificação>Windows (WNS) e insira as informações nos campos obrigatórios.
Escolha Salvar.
Abra Referências no Gerenciador de Soluções e selecione Gerenciar Pacotes NuGet. Adicione uma referência à biblioteca gerenciada do Barramento de Serviço do Microsoft Azure – basta procurar
WindowsAzure.Messaging.Managed
e adicioná-lo ao seu projeto.Para fins de teste, crie o manipulador de eventos
MainPage_Loaded
novamente e adicionar este snippet de código a ele:var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync(); var hub = new NotificationHub("HUB_NAME", "HUB_LISTEN_CONNECTION_STRING"); var result = await hub.RegisterNativeAsync(channel.Uri); // Displays the registration ID so you know it was successful if (result.RegistrationId != null) { Debug.WriteLine("Reg successful."); }
O código registra o aplicativo no hub de notificação. Você está pronto!
Em
LocationHelper
, no manipuladorGeolocator_PositionChanged
, você pode adicionar uma parte do código de teste que impõe a colocação da localização dentro do limite geográfico:await LocationHelper.SendLocationToBackend("wns", "TEST_USER", "TEST", "37.7746", "-122.3858");
Como você não está passando as coordenadas reais (que podem não estar nos limites no momento) e como estamos usando valores predefinidos de teste, você verá uma notificação sobre atualização:
Próximas etapas
Existem algumas etapas que talvez você precise seguir para que a solução esteja pronta para produção.
- Primeiro, você precisa garantir que os limites geográficos sejam dinâmicos. Isso requer algum trabalho extra com a API do Bing para poder carregar novos limites na fonte de dados existente. Para obter mais informações, consulte Documentação da API de Serviços de Dados Espaciais do Bing.
- Segundo, como você está trabalhando para garantir que a entrega seja feita aos participantes certos, talvez você queira usar a marcaçãopara tê-los como destino.
A solução mostrada neste tutorial descreve um cenário em que você pode ter uma ampla variedade de plataformas de destino e, portanto, não limita a delimitação geográfica a recursos específicos do sistema. Dito isso, a Plataforma Universal do Windows oferece recursos para detectar delimitações geográficas prontas.