Pessoas no Windows

O Windows é uma plataforma ideal para aplicações de terceiros integrarem os seus principais contactos pessoais. Esta integração permite que os utilizadores interajam com as personas para experiências diversas de pessoas. O Windows agora fornece APIs a aplicações WinUI de terceiros e outras aplicações com identidade de pacote para armazenar todos os seus contactos.

Depois que seus aplicativos armazenarem seus contatos no Windows, os usuários poderão ver essas sugestões de contato no painel Compartilhar no Windows para compartilhar diretamente com seus principais contatos. Consulte Como partilhar ficheiros no Explorador de Ficheiros no Windows para obter mais informações sobre o painel Partilhar .

Criar um UserDataAccount para o Contrato de Pessoas

Comece criando uma conta de dados do usuário. Aplicações de terceiros são necessárias para criar uma UserDataAccount com UserDisplayName como "com.microsoft.peoplecontract".

UserDataAccountStore udas =
    await UserDataAccountManager.RequestStoreAsync(UserDataAccountStoreAccessType.AppAccountsReadWrite);
UserDataAccount uda = await udas.CreateAccountAsync("com.microsoft.peoplecontract");

Em seguida, adicione "com.microsoft.windows.system" à lista de ExplictReadAccessPackageFamilyNames para a conta. Isso fornecerá acesso restrito de contatos de terceiros a experiências do Windows.

uda.ExplictReadAccessPackageFamilyNames.Add("com.microsoft.windows.system");
await uda.SaveAsync();

Armazenando contatos

O primeiro passo para armazenar contatos é criar uma lista de contatos. Para fazer isso, os aplicativos de terceiros devem criar a nova lista de contatos para um UserDataAccount na Loja de Contatos do Windows. Os aplicativos podem optar por manter o tipo de acesso padrão OtherAppReadAccess para a lista de contatos, enquanto configurá-lo para None impedirá que outros aplicativos tenham acesso a esses contatos. Consulte o enum ContactListOtherAppReadAccess para obter a lista completa dos tipos de acesso disponíveis.

ContactStore store = await ContactManager.RequestStoreAsync(ContactStoreAccessType.AppContactsReadWrite);
this.contactList = await store.CreateContactListAsync(contactListsName, uda.Id);
contactList.OtherAppReadAccess = ContactListOtherAppReadAccess.None;
await contactList.SaveAsync();

Ao armazenar um contato, os aplicativos de terceiros devem incluir todas as informações relevantes necessárias para que as experiências do Windows alimentem um Contato.

Os seguintes campos são obrigatórios ao armazenar um contato:

  • FirstName
  • RemoteId
  • DisplayPicture

Os seguintes campos são opcionais:

  • LastName
  • Phones
  • Emails

Este trecho de código demonstra como armazenar um contato:

foreach (var appContact in AppContacts)
{
  var cont = new Contact
  {
    FirstName = appContact.FirstName,
    LastName = appContact.LastName,
    RemoteId = appContact.Id,
    SourceDisplayPicture = RandomAccessStreamReference.CreateFromUri(new Uri(appContact.ProfilePicPath)),
    Phones = { new ContactPhone { Number = appContact.Phone } }
  };

  await this.contactList.SaveContactAsync(cont);
}

Observação

O DisplayName para o contato é construído usando FirstName e LastName. Se o sobrenome não for fornecido, DisplayName será idêntico à cadeia de caracteres fornecida para o nome.

Armazenando classificações para contactos

Você pode criar uma lista de anotações para o UserDataAccount para armazenar classificações para os seus contactos. Os aplicativos podem armazenar classificações para seus principais contatos adicionando anotações aos contatos. Essas anotações são armazenadas como parte de uma lista de anotações no repositório de contatos.

ContactAnnotationStore annotationStore = await
    ContactManager.RequestAnnotationStoreAsync(ContactAnnotationStoreAccessType.AppAnnotationsReadWrite);
this.contactAnnotationList = await annotationStore.CreateAnnotationListAsync(uda.Id);

Você pode armazenar classificações para seus principais contatos usando as anotações nos contatos. As classificações são armazenadas como parte de ProviderProperties em uma anotação de contato. Junto com a classificação, os aplicativos devem definir SupportedOperations em uma anotação de contato como Share.

foreach (var appContact in topAppContacts)
{
  Contact contact = await list.GetContactFromRemoteIdAsync(topAppContact.RemoteID);
  var annotation = new ContactAnnotation
  {
    ContactId = contact.Id,
    SupportedOperations = ContactAnnotationOperations.Share
  };
  annotation.ProviderProperties.Add("Rank", rank);
  await annotationsLst.TrySaveAnnotationAsync(annotation);
}

Atualizando as classificações de contatos

Fica a critério dos aplicativos quando atualizar as fileiras dos contatos armazenados no Windows. O Windows recomenda que as listas classificadas sejam atualizadas regularmente para fornecer a melhor experiência ao usuário. Sempre que precisar de atualizar uma lista classificada, terá de seguir vários passos.

  1. Exclua a ContactAnnotationList.

    Uma vez que o aplicativo tenha uma lista atualizada dos principais contatos, a lista de anotações pode ser excluída e uma nova lista de anotações com anotações atualizadas para seus principais contatos pode ser criada.

    await this.contactAnnotationList.DeleteAsync();
    
  2. Crie um novo ContactAnnotationList. Siga as etapas na seção Armazenando classificações para contatos para criar uma nova lista de anotações e armazenar classificações para seus principais contatos.

Boas práticas para a classificação

Para maximizar a relevância dos contactos da sua aplicação na linha de sugestões da Folha de Partilha, siga estes princípios de classificação:

Ordenar por recência e frequência

Calcule a classificação como uma combinação de:

  • Recência: Quando o utilizador interagiu pela última vez com cada contacto
  • Frequência: Com que frequência o utilizador interage com cada contacto

Por exemplo, um contacto que o utilizador enviou ontem pode ter o rank 95, enquanto um contacto enviado há 2 semanas pode ter o rank 60.

// lastInteraction and interactionCount come from your app's own interaction
// telemetry. The Windows Contact class does not expose interaction history.
private int CalculateRank(DateTime lastInteraction, int interactionCount)
{
    TimeSpan daysSinceLastInteraction = DateTime.Now - lastInteraction;
    int frequencyScore = interactionCount * 10; // Max ~100
    int recencyScore = Math.Max(0, 100 - (daysSinceLastInteraction.Days * 3));

    return (recencyScore + frequencyScore) / 2;
}

Eliminar contactos desatualizados

Contactos com os quais o utilizador não interage há 30+ dias devem ser removidos ou classificados significativamente para baixo. Isto mantém as sugestões frescas e relevantes:

private async Task PruneStaleContactsAsync()
{
    var now = DateTime.Now;
    var staleCutoff = now.AddDays(-30);
    
    foreach (var contact in this.AllTrackedContacts)
    {
        if (contact.LastInteractionDate < staleCutoff)
        {
            // Remove the annotation or set rank to 0
            var annotation = await GetAnnotationForContactAsync(contact);
            if (annotation != null)
            {
                annotation.ProviderProperties["Rank"] = 0;
                await this.contactAnnotationList.TrySaveAnnotationAsync(annotation);
            }
        }
    }
}

Atualiza as classificações regularmente

Agende atualizações de classificação numa cadência que faça sentido para a sua aplicação – diariamente para aplicações de mensagens, semanalmente para email, ou mensalmente para aplicações de calendário. Use tarefas em segundo plano, se necessário:

// Example: Update ranks when the app comes to foreground or on a timer
private async void UpdateRanksOnAppActivated()
{
    var topContacts = GetTopContactsByRecentActivity(50);
    await UpdateAnnotationRanksAsync(topContacts);
}

Contribua apenas com contactos explícitos

A sua aplicação deve contribuir apenas com os contactos que o utilizador adicionou ou autorizou explicitamente. Nunca:

  • Carregue toda a lista de endereços
  • Sincronização automática dos contactos sem consentimento do utilizador
  • Partilhe contactos de diretórios corporativos sem permissão explícita

Peça permissão antes de armazenar contactos no sistema de Pessoas:

private async Task<bool> RequestContactStoreAccessAsync()
{
    // Requesting a writable ContactStore prompts the user for consent.
    // Your app must declare the contacts capability in its manifest.
    ContactStore store = await ContactManager.RequestStoreAsync(
        ContactStoreAccessType.AppContactsReadWrite);
    return store != null;
}

Respeitar as definições de privacidade do utilizador

Permitir que os utilizadores:

  • Escolha quais os contactos a partilhar com o Windows
  • Optar por não participar na integração das pessoas
  • Apague os contactos deles do Windows a qualquer momento
// Provide a setting to disable sync
if (this.ShouldSyncContactsWithWindows)
{
    await SyncContactsAsync();
}
else
{
    // Clear contacts if the user disables sync
    await ClearWindowsContactsAsync();
}

Integração com a Folha de Partilha

Ao classificar e manter os seus contactos com as orientações acima, os utilizadores verão os principais contactos da sua aplicação na linha de sugestões da Folha de Partilha do Windows. Este caminho suporta atualmente contactos de Pessoas.

Para garantir que os seus contactos aparecem:

  1. Crie um UserDataAccount com DisplayName = "com.microsoft.peoplecontract"
  2. Armazenar contactos com campos obrigatórios (FirstName, RemoteId, DisplayPicture)
  3. Crie um ContactAnnotationList com classificações
  4. Defina SupportedOperations = Share em cada anotação
  5. Atualize as classificações regularmente com base na atualidade e frequência
  6. Remova contactos antigos após mais de 30 dias

Consulte Partilhar conteúdo da sua aplicação e Receber conteúdo na sua aplicação para obter o guia completo de integração da folha de partilha.