Idioma: HTML | XAML

Guia de início rápido: conectando aplicativos usando toque ou busca (XAML)

Applies to Windows and Windows Phone

Este tópico percorre o código necessário para tornar seu aplicativo capaz de conectar a outra instância de seu aplicativo que está executando em outro dispositivo, usando a Proximidade.

Proximidade é uma ótima maneira de usuários em dois dispositivos compartilharem sua experiência e dados do aplicativo. Os usuários podem iniciar a conexão de aplicativo compartilhado tocando nos dois dispositivos juntos ou descobrindo um aplicativo par no alcance do wireless. Quando a conexão for estabelecida, um soquete transfere os dados entre os aplicativos.

Para iniciar uma conexão entre duas instâncias do aplicativo usando um gesto de tocar, muitos dispositivos precisam ter NFC. Em um computador, esse canal de conexão pode ser feito via Bluetooth, Wi-Fi Direct ou uma rede de infraestrutura. No Windows Phone, a conexão pode ser estabelecida via Bluetooth ou rede de infraestrutura. Wi-Fi Direct não tem suporte no Windows Phone. Isso significa que tocar em conectar funciona entre um Windows Phone e um computador, mas que a comunicação é restrita ao uso de Bluetooth ou uma rede de infraestrutura.

Com o uso do recurso de navegação por Proximidade, um usuário em um dispositivo pode descobrir seu aplicativo em funcionamento nos dispositivos ao redor, sem o toque de ambos juntos. Quando um usuário descobre um aplicativo par em um dispositivo próximo, o usuário pode solicitar uma conexão ao aplicativo par. Em um computador, a navegação usa Wi-Fi Direct. No Windows Phone, a navegação usa Bluetooth. Portanto, um aplicativo que está executando em um computador não pode descobrir um aplicativo par que está executando em um telefone por navegação, e vice-versa.

O exemplo neste tópico mostra como usar a Proximidade e a classe PeerFinder para criar uma conexão de soquete a longo prazo com um aplicativo par em outro dispositivo.

Para as conexões acionadas por um toque, quando o aplicativo não está sendo executado em primeiro plano no dispositivo de destino, a Proximidade convida o usuário para ativar o aplicativo no dispositivo de destino. Se o aplicativo par não estiver instalado no dispositivo de destino, a Proximidade convidará o usuário no dispositivo de destino para instalar o aplicativo a partir da Loja. Para saber mais detalhes sobre como ativar aplicativos com o gesto de tocar, veja "Ativando aplicativos usando Proximidade" em Proximidade e toque.

Objetivo: Crie uma conexão entre dois dispositivos usando toque de Proximidade ou busca por dispositivos sem fio.

Pré-requisitos

Microsoft Visual Studio Express 2012 para Windows 8

Instruções

1. Crie um novo projeto e habilite a Proximidade

  1. Abra o Visual Studio Express 2012 para Windows 8 e selecione Novo Projeto no menu Arquivo. Na seção Visual C# ou Visual Basic, selecione Windows Store e depois Aplicativo em branco (XAML). Digite o nome do aplicativo como ProximityConnect e clique em OK.
  2. Abra o arquivo Package.appxmanifest e selecione a guia Recursos. Selecione o recurso Proximidade para habilitar a Proximidade. Feche e salve o arquivo de manifesto.

2. Adicionar a interface do usuário XAML

Abra o arquivo MainPage.xaml e substitua o elemento de grade padrão pelo XAML a seguir.


<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel Margin="20">
        <StackPanel Orientation="Horizontal">
            <TextBlock FontSize="16" VerticalAlignment="Center" Margin="0,0,10,0">Display Name</TextBlock>
            <TextBox x:Name="DisplayNameTextBox" Width="300"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <Button x:Name="AdvertiseForPeersButton" Content="Advertise For a Connection" 
                    Click="AdvertiseForPeersButton_Click" />
            <Button x:Name="AcceptConnectionButton" Content="Accept Connection" 
                    Click="AcceptConnectionButton_Click" />
            <Button x:Name="FindPeersButton" Content="Browse for Peers" 
                    Click="FindPeersButton_Click" />
            <Button x:Name="StopFindingPeersButton" Content="Stop Browsing for Peers" 
                    Click="StopFindingPeersButton_Click" />
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBox x:Name="SendMessageTextBox" Width="300" Height="30" />
            <Button x:Name="SendMessageButton" Content="Send Message" 
                    Click="SendMessageButton_Click" />
        </StackPanel>
        <TextBlock x:Name="MessageBlock" Width="600" HorizontalAlignment="Left"/>
    </StackPanel>
</Grid>


3. E clique nos manipuladores de evento

Nesta etapa, você adiciona o código aos eventos de clique dos botões XAML e um método para escrever no thread da interface do usuário. O código no manipulador de eventos para o botão AdvertiseForPeersButton define o nome par do computador local e inicia o PeerFinder. Quando há suporte para conexões disparadas (toque), o código identifica o manipulador de eventos do evento TriggeredConnectionStateChanged. No manipulador de eventos do TriggeredConnectionStateChanged, o código abre um soquete de fluxo para enviar mensagens de texto entre os aplicativos pares.

O código no manipulador de eventos do botão FindPeersButton chama o método FindAllPeersAsync para procurar dispositivos dentro do alcance da rede sem fio. Quando um ou mais pares são encontrados, o exemplo chama o método ConnectAsync para se conectar ao primeiro par encontrado. Este é apenas um exemplo. Você deve apresentar ao usuário uma lista dos possíveis pares disponíveis e conectar-se ao par que o usuário escolher.

O código inclui um manipulador de eventos referente ao evento ConnectionRequested que ocorre quando um par abre uma conexão com você chamando o método ConnectAsync. Você pode clicar no botão Aceitar Conexão para aceitar a conexão.

O código no manipulador de evento para o botão StopFindingPeersButton chama o método de parada para parar a propaganda e a busca por pares, não importando se dentro do alcance sem fio ou se de um gesto de tocar.

No arquivo MainPage.xaml.cs ou MainPage.xaml.vb, substitua o manipulador de eventos padrão OnNavigatedTo na classe MainPage pelo código a seguir.


protected override void OnNavigatedTo(NavigationEventArgs e)
{
    DisplayNameTextBox.Text = Windows.Networking.Proximity.PeerFinder.DisplayName;
    Windows.Networking.Proximity.PeerFinder.ConnectionRequested += ConnectionRequested;

    // If activated from launch or from the background, create a peer connection.
    var args = e.Parameter as Windows.ApplicationModel.Activation.LaunchActivatedEventArgs;
    if (args != null && args.Kind == Windows.ApplicationModel.Activation.ActivationKind.Launch)
    {
        if (args.Arguments == "Windows.Networking.Proximity.PeerFinder:StreamSocket")
        {
            AdvertiseForPeersButton_Click(null, null);
        }
    }
}

protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
    if (_started)
    {
        // Detach the callback handler (there can only be one PeerConnectProgress handler).
        Windows.Networking.Proximity.PeerFinder.TriggeredConnectionStateChanged -= TriggeredConnectionStateChanged;
        // Detach the incoming connection request event handler.
        Windows.Networking.Proximity.PeerFinder.ConnectionRequested -= ConnectionRequested;
        Windows.Networking.Proximity.PeerFinder.Stop();
        CloseSocket();
        _started = false;
    }
}

// Write a message to MessageBlock on the UI thread.
private Windows.UI.Core.CoreDispatcher messageDispatcher = Window.Current.CoreWindow.Dispatcher;

async private void WriteMessageText(string message, bool overwrite = false)
{
    await messageDispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
        () =>
        {
            if (overwrite)
                MessageBlock.Text = message;
            else
                MessageBlock.Text += message;
        });
}

bool _started = false;

// Click event handler for "Advertise" button.
private void AdvertiseForPeersButton_Click(object sender, RoutedEventArgs e)
{
    if (_started) 
    {
        WriteMessageText("You are already advertising for a connection.\n");
        return; 
    }

    Windows.Networking.Proximity.PeerFinder.DisplayName = DisplayNameTextBox.Text;

    if ((Windows.Networking.Proximity.PeerFinder.SupportedDiscoveryTypes &
         Windows.Networking.Proximity.PeerDiscoveryTypes.Triggered) ==
         Windows.Networking.Proximity.PeerDiscoveryTypes.Triggered)
    {
        Windows.Networking.Proximity.PeerFinder.TriggeredConnectionStateChanged +=
            TriggeredConnectionStateChanged;

        WriteMessageText("You can tap to connect a peer device that is " +
                         "also advertising for a connection.\n");
    }
    else
    {
        WriteMessageText("Tap to connect is not supported.\n");
    }

    if ((Windows.Networking.Proximity.PeerFinder.SupportedDiscoveryTypes &
         Windows.Networking.Proximity.PeerDiscoveryTypes.Browse) !=
         Windows.Networking.Proximity.PeerDiscoveryTypes.Browse)
    {
        WriteMessageText("Peer discovery using Wi-Fi Direct is not supported.\n");
    }

   Windows.Networking.Proximity.PeerFinder.Start();
   _started = true;
}

private void TriggeredConnectionStateChanged(
    object sender,
    Windows.Networking.Proximity.TriggeredConnectionStateChangedEventArgs e)
{
    if (e.State == Windows.Networking.Proximity.TriggeredConnectState.PeerFound)
    {
        WriteMessageText("Peer found. You may now pull your devices out of proximity.\n");
    }
    if (e.State == Windows.Networking.Proximity.TriggeredConnectState.Completed)
    {
        WriteMessageText("Connected. You may now send a message.\n");
        SendMessage(e.Socket);
    }
}

// Click event handler for "Browse" button.
async private void FindPeersButton_Click(object sender, RoutedEventArgs e)
{
    if ((Windows.Networking.Proximity.PeerFinder.SupportedDiscoveryTypes &
         Windows.Networking.Proximity.PeerDiscoveryTypes.Browse) !=
         Windows.Networking.Proximity.PeerDiscoveryTypes.Browse)
    {
        WriteMessageText("Peer discovery using Wi-Fi Direct is not supported.\n");
        return;
    }

    try
    {
        var peerInfoCollection = await Windows.Networking.Proximity.PeerFinder.FindAllPeersAsync();
        if (peerInfoCollection.Count > 0)
        {
            // Connect to first peer found - example only.
            // In your app, provide the user with a list of available peers.
            ConnectToPeer(peerInfoCollection[0]);
        }
    }
    catch (Exception err)
    {
        WriteMessageText("Error finding peers: " + err.Message + "\n");
    }
}

async private void ConnectToPeer(Windows.Networking.Proximity.PeerInformation peerInfo)
{
    WriteMessageText("Peer found. Connecting to " + peerInfo.DisplayName + "\n");
    try
    {
        Windows.Networking.Sockets.StreamSocket socket =
            await Windows.Networking.Proximity.PeerFinder.ConnectAsync(peerInfo);

        WriteMessageText("Connection successful. You may now send messages.\n");
        SendMessage(socket);
    }
    catch (Exception err)
    {
        WriteMessageText("Connection failed: " + err.Message + "\n");
    }

    requestingPeer = null;
}

// Click event handler for "Stop" button.
private void StopFindingPeersButton_Click(object sender, RoutedEventArgs e)
{
    _started = false;
    Windows.Networking.Proximity.PeerFinder.Stop();
    if (proximitySocket != null) { CloseSocket(); }
}

// Handle external connection requests.
Windows.Networking.Proximity.PeerInformation requestingPeer;

private void ConnectionRequested(object sender,
    Windows.Networking.Proximity.ConnectionRequestedEventArgs e)
{
    requestingPeer = e.PeerInformation;
    WriteMessageText("Connection requested by " + requestingPeer.DisplayName + ". " +
        "Click 'Accept Connection' to connect.");
}

private void AcceptConnectionButton_Click(object sender, RoutedEventArgs e)
{
    if (requestingPeer == null)
    {
        WriteMessageText("No peer connection has been requested.");
        return;
    }

    ConnectToPeer(requestingPeer);
}


4. Adicionar o código para enviar e receber mensagens usando StreamSocket fornecido

Quando uma conexão é bem-sucedida, o código envia o objeto StreamSocket que foi criado pela conexão para a função SendMessage. A função SendMessage abre uma conexão de rede com o dispositivo próximo, que permite a troca de mensagens. Não deixe de chamar sempre o método close do objeto StreamSocket quando tiver concluído com ele.

No arquivo MainPage.xaml.cs ou MainPage.xaml.vb, adicione o seguinte código após o método SendMessageButton_Click.


private void SendMessageButton_Click(object sender, RoutedEventArgs e)
{
     if (proximitySocket != null)
    {
        SendMessageText();
    }
    else
    {
        WriteMessageText("You must enter proximity to send a message.\n");
    }
}

Windows.Networking.Sockets.StreamSocket proximitySocket;
Windows.Storage.Streams.DataWriter dataWriter;

// Reference socket streams for writing and reading messages.
private void SendMessage(Windows.Networking.Sockets.StreamSocket socket)
{
    // PeerFinder has not been started.
    if (!_started)
    {
        CloseSocket();
        return;
    }

    // Get the network socket from the proximity connection.
    proximitySocket = socket;

    // Create DataWriter for writing messages to peers.
    dataWriter = new Windows.Storage.Streams.DataWriter(proximitySocket.OutputStream);

    // Listen for messages from peers.
    Windows.Storage.Streams.DataReader dataReader =
            new Windows.Storage.Streams.DataReader(proximitySocket.InputStream);
    StartReader(proximitySocket, dataReader);
}


// Send a message to the socket.
private async void SendMessageText()
{
    string msg = SendMessageTextBox.Text;

    if (msg.Length > 0)
    {
        var msgLength = dataWriter.MeasureString(msg);
        dataWriter.WriteInt32(msg.Length);
        dataWriter.WriteString(msg);
        try
        {
            await dataWriter.StoreAsync();
            WriteMessageText("Message sent: " + msg + "\n");
        }
        catch (Exception e)
        {
            WriteMessageText("Send error: " + e.Message + "\n");
            CloseSocket();
        }
    }
}

// Read out and print the message received from the socket.
private async void StartReader(Windows.Networking.Sockets.StreamSocket socket,
   Windows.Storage.Streams.DataReader reader)
{
    try
    {
        uint bytesRead = await reader.LoadAsync(sizeof(uint));
        if (bytesRead > 0)
        {
            uint strLength = (uint)reader.ReadUInt32();
            bytesRead = await reader.LoadAsync(strLength);
            if (bytesRead > 0)
            {
                String message = reader.ReadString(strLength);
                WriteMessageText("Received message: " + message + "\n");
                StartReader(socket, reader); // Start another reader
            }
            else
            {
                WriteMessageText("The peer app closed the socket\n");
                reader.Dispose();
                CloseSocket();
            }
        }
        else
        {
            WriteMessageText("The peer app closed the socket\n");
            reader.Dispose();
            CloseSocket();
        }
    }
    catch 
    {
        WriteMessageText("The peer app closed the socket\n");
        reader.Dispose();
        CloseSocket();
    }
}

private void CloseSocket()
{
    if (proximitySocket != null)
    {
        proximitySocket.Dispose();
        proximitySocket = null;
    }

    if (dataWriter != null)
    {
        dataWriter.Dispose();
        dataWriter = null;
    }
}

public void Dispose()
{
    CloseSocket();
}


5. Adicione o código para ativar o aplicativo em um par a partir de um toque

No código adicionado anteriormente para configurar os métodos de conexão e os manipuladores de evento, você incluiu código no manipulador de eventos OnNavigatedTo para concluir uma conexão de soquete caso o aplicativo seja ativado por um toque. Para que esse código funcione corretamente, os argumentos do evento de início devem ser passados para a página principal quando ela for navegada. Isso é feito no manipulador de eventos OnLaunched, que é executado quando o aplicativo é ativado.

Abra o arquivo App.xaml.cs ou App.xaml.vb e substitua o método padrão OnLaunched pelo seguinte.


protected override void OnLaunched(LaunchActivatedEventArgs args)
{
    if (Window.Current.Content == null)
    {
        var rootFrame = new Frame();
        rootFrame.Navigate(typeof(MainPage), args);
        Window.Current.Content = rootFrame;
    }
    else
    {
        var rootFrame = Window.Current.Content as Frame;
        rootFrame.Navigate(typeof(MainPage), args);
    }

    // Ensure the current window is active
    Window.Current.Activate();
}


6. Executar o aplicativo

Para ver o aplicativo em ação, execute-o em dois dispositivos com Proximidade habilitada. Clique no botão Anuncie por uma Conexão nos dois aplicativos e faça o toque conectando os dois dispositivos. Se você tiver dois dispositivos Windows com Wi-Fi Direct ativado nos dois dispositivos, você pode clicar no botão Procurar Pares em um dispositivo para criar a conexão. Se você tiver dois telefones e o Bluetooth estiver ativado nos dois dispositivos, também poderá tocar em Procurar Pares em um telefone para criar a conexão.

Importante  

Este guia de início rápido deve ser executado em dois dispositivos. Para cenários que usam gesto de tocar, cada dispositivo deve ter um dispositivo de Proximidade, como um rádio NFC, instalado. Para cenários que usam navegação sem fio, é necessário que os dois computadores estejam com Wi-Fi Direct ativado, ou os dois Windows Phones com o Bluetooth ativado. Se você não tiver um hardware com suporte para toque de Proximidade, como rádio NFC, poderá usar o driver de Proximidade de exemplo incluído no WDK (Kit de Driver do Windows). Esse driver de exemplo pode ser usado para simular um gesto de tocar através de uma conexão de rede entre dois dispositivos Windows. Para saber como baixar o WDK, veja WDK (Kit de Driver do Windows). Depois que instalar o WDK e os exemplos, você poderá encontrar o driver de Proximidade de exemplo no diretório src\nfp, no local em que os exemplos do WDK foram instalados. Para obter instruções sobre como criar e executar o simulador, veja o arquivo NetNfpProvider.html no diretório src\nfp\net. Depois que você iniciar o simulador, ele será executado em tela de fundo enquanto seu aplicativo de Proximidade é executado em primeiro plano. O aplicativo deve estar em primeiro plano para que a simulação de toque funcione.

Resumo e próximas etapas

Neste tutorial, você criou um aplicativo que usa um gesto de tocar ou busca por dispositivos sem fio para conectar dispositivos.

Você também pode usar gestos de toque para publicar e assinar para receber mensagens. Para um exemplo, consulte Início rápido: publicando e assinando a mensagens usando Toque.

Tópicos relacionados

Visão geral de proximidade e toque
Guia de início rápido: publicando e assinando mensagens com toque
Guidelines for Proximity
Testando e solucionando problemas de proximidade em aplicativos
Windows.Networking.Proximity namespace
Exemplos
Amostra de proximidade

 

 

Mostrar:
© 2014 Microsoft