Políticas de Privacidade e Porque não a GDPR - Android M-Commerce

Investir em Você é Barra de Ouro a R$ 2,00. Cadastre-se e receba grátis conteúdos Android sem precedentes! Você receberá um email de confirmação. Somente depois de confirma-lo é que eu poderei lhe enviar os conteúdos semanais exclusivos. Os artigos em PDF são entregues somente para os inscritos na lista.

Email inválido.
Blog /Android /Políticas de Privacidade e Porque não a GDPR - Android M-Commerce

Políticas de Privacidade e Porque não a GDPR - Android M-Commerce

Vinícius Thiengo
(3537)
Go-ahead
"O método consciente de tentativa e erro é mais bem-sucedido que o planejamento de um gênio isolado."
Peter Skillman
Prototipagem Android
Capa do curso Prototipagem Profissional de Aplicativos
TítuloAndroid: Prototipagem Profissional de Aplicativos
CategoriasAndroid, Design, Protótipo
AutorVinícius Thiengo
Vídeo aulas186
Tempo15 horas
ExercíciosSim
CertificadoSim
Acessar Curso
Quer aprender a programar para Android? Acesse abaixo o curso gratuito no Blog.
Lendo
TítuloDomain-driven Design Destilado
CategoriaEngenharia de Software
Autor(es)Vaughn Vernon
EditoraAlta Books
Edição1ª
Ano2024
Páginas160
Conteúdo Exclusivo
Investir em Você é Barra de Ouro a R$ 2,00. Cadastre-se e receba gratuitamente conteúdos Android sem precedentes!
Email inválido

Tudo bem?

Neste artigo continuamos com o desenvolvimento do aplicativo BlueShoes, projeto Android de construção de um mobile-commerce.

Aqui iremos adicionar ao aplicativo uma tela importante e necessária, desde 15 de março de 2017, para aqueles apps que utilizam dados sensíveis de seus usuários, a tela de políticas de privacidade.

Animação da tela de Políticas de Privacidade do app Android BlueShoes

Antes de iniciarmos com a codificação, vamos primeiro discutir alguns pontos sobre leis que podem e que não podem afetar o desenvolvimento do aplicativo com o decorrer das aulas.

E... não deixe de se inscrever 📩 na lista de emails do Blog para ter acesso aos conteúdos exclusivos sobre o dev Android e também aos conteúdos do projeto Android BlueShoes.

A seguir os tópicos abordados:

Estou conhecendo o projeto somente agora

Para você que está chagando agora ao projeto Android de mobile-commerce, primeiro é importante que você estude as aulas dos links a seguir, isso na ordem apresentada:

Dados sensíveis

O que são dados sensíveis?

São quaisquer dados que diretamente, indiretamente ou em relação com outras informações permitam a identificação ou identificabilidade de uma pessoa física.

Ou seja, se seu app está obtendo somente as coordenadas atuais do usuário e em algum momento do ciclo de vida dele em seu aplicativo também é obtido qualquer outro dado que permita, junto às coordenadas, a identificação do usuário, então o seu aplicativo está também manipulando dados sensíveis.

Resumo: não é preciso o dado explicito de identificação do usuário, como no caso do e-mail, que sozinho já permiti a identificação dele. Sendo assim é improvável que qualquer aplicativo que tenha um mínimo formulário não precise também de políticas de privacidade.

GDPR - Regulamento Geral sobre a Proteção de Dados

GDPR é a sigla para General Data Protection Regulation, que em português é Regulamento Geral sobre a Proteção de Dados, no caso, dados sensíveis.

GDPR - General Data Protection Regulation

Para a sigla faltou somente o sufixo indicando que é para empresas que atendem a usuários da União Europeia (European Union - EU) ou usuários da Área Econômica da Europa (European Economic Area - EEA).

Sem muitas delongas, o objetivo com este tópico é primeiro informar resumidamente o que é a GDPR, depois informar em qual parte nós desenvolvedores podemos ser afetados e por fim o porquê de a GDPR não ser importante ao aplicativo Android BlueShoes, mesmo sendo um aplicativo de mobile-commerce.

O que é?

Primeiro é importante lembrar que leis que protegem os dados dos usuários residentes na Europa sempre existiram, porém essas não acompanharam, até o momento da vigência da GDPR, a evolução da tecnologia.

A GDPR é basicamente a "aplicação de esteroides" ao que já existia em termos de leis de proteção dos dados pessoais dos residentes em países dos blocos EU ou EEA, adicionando pontos mais genéricos e abrangentes em relação a segurança e privacidade. Entenda:

  • Genéricos: pois o texto da GDPR é escrito de modo a sofrer menos com a evolução tecnológica, evitando assim a necessidade de atualizações anuais, por exemplo;
  • Abrangentes: pois os usuários residentes nos blocos EU ou EEA têm ainda mais controle sobre a compartilhamento dos dados deles. Esses usuários literalmente agora podem decidir quais e se os dados poderão ou não ser utilizados.

E não se engane achando que somente porque a empresa na qual você trabalha não está nos blocos EU ou EEA que ela não deve se preocupar com a GDPR.

Se há usuários de seu aplicativo residentes nos blocos indicados, então sim, a empresa precisa se adequar às normas informadas na GDPR, caso contrário ela é passiva de multa que pode passar dos 20 milhões de euros, isso se 4% do faturamento dela for maior do que este valor informado.

Resumidamente, com a GDPR, os usuários residentes nos blocos EU ou EEA têm de ter autoridade em:

  • Saber quais dados deles estão sendo obtidos pela empresa;
  • Saber para que esses dados estão sendo obtidos;
  • Ter a possiblidade de revogar o uso dos dados deles, incluindo a remoção completa de seus dados presentes nas bases da empresa;
  • Ter a possiblidade de migrar os dados deles para outros serviços.

Como informado anteriormente: o objetivo aqui foi mostrar um resumo da GDPR, com foco em desenvolvedores. Há inúmeros bons conteúdos em português sobre esse novo pacote de regras que entrou em vigor em 25 de Maio de 2018.

Alguns bons estão nos links a seguir:

Impacto em que é desenvolvedor

Para desenvolvedores o impacto acaba sendo "opcional" de acordo com as prioridades do software ou empresa proprietária dele.

Certamente as políticas de privacidade terão de ser atualizadas, deixando claro aos usuários principalmente os direitos que eles têm em relação aos dados sensíveis deles.

Criar uma interface amigável ao usuário para que ele possa revogar acesso aos dados dele é algo que já faz parte do impacto aos programadores.

Exemplo: assuma um cenário onde no aplicativo Android é utilizada uma API de anúncios para a monetização do projeto, algo muito importante para entrar receita na empresa.

Entendido o cenário, vem a reflexão. Nós profissionais de TI sabemos que praticamente todas as APIs de anúncios precisam coletar alguns dados sensíveis dos usuários para apresentar anúncios relevantes a eles.

Essa coleta de dados sensíveis por parte de uma API terceira, mesmo que o aplicativo em sí não exija diretamente nenhum dado do usuário, essa coleta já implica na necessidade de:

  • Área de política de privacidade falando sobre a coleta;
  • Algoritmo para solicitação de consentimento do usuário sobre os dados coletados;
  • E, caso a empresa ou o cliente dono do app queira assim, uma área de administração onde o usuário poderá liberar ou revogar acesso aos dados dele.

Ou seja, certamente os desenvolvedores terão de responder à GDPR com uma interface amigável: mais códigos e lógicas de negócio terão de ser desenvolvidos.

Voltando ao cenário de exemplo, é possível somente fornecer uma tela de contato onde por meio dela o usuário pode requisitar todos os direitos respaldados a ele.

É possível também não fornecer o serviço do aplicativo por completo se o usuário não permitir a coleta de dados essenciais ao bom funcionamento do app, ou seja, se ele permitir a coleta de dados por parte da API de anúncios, a monetização do app (algo extremamente importante ao funcionamento dele - pagar desenvolvedores, por exemplo) continua e assim o serviço prestado também, caso contrário o serviço é bloqueado até o momento do consentimento do uso dos dados do usuário.

Por que não à GDPR no projeto BlueShoes?

Para as políticas de privacidade e algoritmos do aplicativo Android de mobile-commerce que estamos desenvolvendo, não há necessidade de se preocupar com a GDPR, pois o público que está fora do Brasil não é atendido pelo app.

As entregas, por exemplo, serão somente em território brasileiro.

LGPD - Lei Geral de Proteção de Dados

A Lei Geral de Proteção de Dados ou somente LGPD é a versão brasileira da GDPR, mas com menos pontos de rigor.

LGPD - Lei Geral de Proteção de Dados

Como no tópico sobre a GDPR, nosso foco neste tópico é passar para você desenvolvedor o que é relevante a ti, então vamos novamente a um resumo necessário.

Antes de prosseguir, é importante informar que a LGPD provavelmente entrará em vigor em Agosto de 2020, ou seja, ainda tem um bom tempo para atualizar os seus aplicativos.

O que é?

É a regulamentação, com maior rigor em relação às leis já existentes no Brasil, de como os dados sensíveis dos brasileiros são tratados, direta ou indiretamente por empresas e instituições governamentais.

A principio não há no projeto de lei tantos indícios de que se espera uma interface de controle de dados dentro do software, onde o usuário poderia, por exemplo, revogar ou liberar acesso aos dados dele, porém é de extrema importância que ele saiba quais dados dele estarão sendo coletados, o porquê da coleta e se ele permiti isso (tela de consentimento).

Note que como acontece com a GDPR, os textos explicativos do porquê da coleta de dados devem ser de fácil interpretação e em tamanho de fonte aceitável (e ajustável), não podendo ser em letras minúsculas. Incluindo que a área de consentimento não pode já vir com o check marcado no "aceito".

Na LGPD também há multa, aqui podendo até mesmo passar dos 50 milhões de reais.

Impacto em que é desenvolvedor

Como com a GDPR, se solicitado pelos responsáveis do aplicativo, o desenvolvedor terá de desenvolver ainda mais códigos que envolvam: banco de dados, lógica de negócio e código estático (telas).

Isso para que o usuário tenha uma excelente experiência em relação ao controle dos dados dele.

Ressaltando que excelente experiência é também sinônimo de:

Por que não?

A LGPD ainda não entrou em rigor e não deixa de correr o risco de ser adiada. Nosso aplicativo certamente estará finalizado bem antes de Agosto de 2020.

De qualquer forma, caso se mostre algo de extrema importância no decorrer do desenvolvimento do projeto, então, em refatoração, poderemos sim adequar o app à LGPD.

Estratégia para a tela de Políticas de Privacidade

Primeiro, o aplicativo BlueShoes estará sim colhendo inúmeros dados sensíveis dos usuários, dados que permitem a identificação de cada um deles.

Logo, teremos de ter a tela de políticas de privacidade.

Há inúmeras estratégias para a criação de uma tela de políticas de privacidade para aplicativos Android, muitas delas eu discuto em: Construindo a Política de Privacidade de Seu Aplicativo Android [Agora Obrigatório].

Aqui nós manteremos o texto em ambiente local, no app Android, e junto a API Annotation Span apresentaremos o conteúdo com a formatação correta.

A escolha por manter o conteúdo de políticas local no app é principalmente devido a formatação dele exigida em protótipo estático. A opção de uso de WebView exigiria ainda mais trabalho para manter o design informado em protótipo.

Protótipo estático

Abaixo o protótipo estático da tela de políticas de privacidade, com um texto fictício:

Tela de Políticas de Privacidade

Tela de Políticas de Privacidade

Software para geração de políticas

Para este projeto foi utilizado o software Web Iubenda para a geração das políticas de privacidade.

Isso, pois o software tem uma interface simples que nos permiti a escolha do que terá no aplicativo e assim, com texto em português, é gerada toda a política de privacidade sem a necessidade de contratação de um advogado, por exemplo.

Mas nem tudo são flores, o Iubenda é um software pago, a versão gratuita, a principio, não permiti nem mesmo a geração de uma simples versão da política de privacidade construída.

Se você quiser acessar por completo a política de privacidade gerada para o aplicativo BlueShoes, então entre em: Política de Privacidade do BlueShoes.

Não deixe de seguir o texto original apresentado aqui em artigo, pois algumas atualizações foram aplicadas em relação ao que foi gerado pela Iubenda.

Trabalhando o fragmento de políticas

Como ocorreu com o desenvolvimento do fragmento de contato, o fragmento de políticas tende a ser simples de desenvolver devido a série de códigos já encapsulados no projeto.

O roteiro será o a seguir:

  • Primeiro a construção completa do fragmento de políticas. Códigos dinâmicos e estáticos, iniciando pelos estáticos;
  • Depois a atualização dos códigos de fragmentos na atividade principal do projeto, para também trabalhar com o fragmento de políticas.

Saiba que você pode ter acesso ao projeto pelo GitHub dele, em: https://github.com/viniciusthiengo/blueshoes-kotlin-android.

Mesmo com o projeto no GitHub, não deixe de acompanhar e implementar o passo a passo em artigo, pois é aqui que tem as explicações do porquê de cada trecho de código.

Arquivos de Strings

Para o arquivo /res/values/strings.xml adicione a String em destaque:

<resources>
...

<!-- PrivacyPolicyFragment -->
<string name="privacy_policy_frag_title">
Políticas de privacidade
</string>
</resources>

 

Agora, no arquivo /res/values, crie um novo arquivo de Strings que conterá todo o texto de política de privacidade:

  • Clique com o botão direito do mouse em /res/values;
  • Acesse New;
  • Então clique em Values resource file;
  • Como nome do arquivo coloque privacy_policy.xml;
  • Clique em OK.

Criando novo arquivo de Strings

Como conteúdo do novo arquivo coloque:

<resources>
<string name="privacy_policy_content">
<annotation title="main">
Proprietário e Controlador de Dados
</annotation>

\n\nBlueShoes

\n\n<b>E-mail de contato do Proprietário:</b> contato@blueshoes.com.br

\n\n<u><b>Última atualização desta versão em aplicativo:</b></u> 07 de
março de 2019

<annotation title="main">
\n\nTipos de Dados coletados
</annotation>

\n\nEntre os tipos de Dados Pessoais que este Aplicativo coleta, por si
mesmo ou através de terceiros, existem: Dados de uso; nome; posição
geográfica; e-mail; senha; sobrenome; imagem; Cookie; nome de Usuário.

\n\nDetalhes completos sobre cada tipo de Dados Pessoais coletados são
fornecidos nas seções dedicadas desta política de privacidade ou por
textos explicativos específicos exibidos antes da coleta de Dados.
Os Dados Pessoais poderão ser fornecidos livremente pelo Usuário, ou,
no caso dos Dados de Utilização, coletados automaticamente ao se
utilizar este Aplicativo.

\n\nA menos que especificado diferentemente todos os Dados solicitados por
este Aplicativo são obrigatórios e a falta de fornecimento destes Dados
poderá impossibilitar este Aplicativo de fornecer os seus Serviços.
Nos casos em que este Aplicativo afirmar especificamente que alguns
Dados não forem obrigatórios, os Usuários ficam livres para deixarem
de comunicar estes Dados sem nenhuma consequência para a disponibilidade
ou o funcionamento do Serviço.

\n\nOs Usuários que tiverem dúvidas a respeito de quais Dados Pessoais são
obrigatórios estão convidados a entrar em contato com o Proprietário.

\n\nQuaisquer usos de cookies – ou de outras ferramentas de rastreamento –
por este Aplicativo ou pelos proprietários de serviços terceiros
utilizados por este Aplicativo serão para a finalidade de fornecer os
Serviços solicitados pelo Usuário, além das demais finalidades descritas
no presente documento e na Política de Cookies, se estiver disponível.

\n\nOs Usuários ficam responsáveis por quaisquer Dados Pessoais de terceiros
que forem obtidos, publicados ou compartilhados através deste Serviço
(este Aplicativo) e confirmam que possuem a autorização dos terceiros
para fornecerem os Dados para o Proprietário.

<annotation title="main">
\n\nModo e local de processamento dos Dados
</annotation>

<annotation title="sub">
\n\nMétodo de processamento
</annotation>

\n\nO Proprietário tomará as medidas de segurança adequadas para impedir o
acesso não autorizado, divulgação, alteração ou destruição não autorizada
dos Dados.

\n\nO processamento dos Dados é realizado utilizando computadores e /ou
ferramentas de TI habilitadas, seguindo procedimentos organizacionais e
meios estritamente relacionados com os fins indicados. Além do Proprietário,
em alguns casos, os Dados podem ser acessados por certos tipos de pessoas
encarregadas, envolvidas com a operação deste Serviço (este Aplicativo)
(administração, vendas, marketing, administração legal do sistema) ou
pessoas externas (como fornecedores terceirizados de serviços técnicos,
carteiros, provedores de hospedagem, empresas de TI, agências de
comunicação) nomeadas, quando necessário, como Processadores de Dados por
parte do Proprietário. A lista atualizada destas partes pode ser
solicitada ao Proprietário a qualquer momento.

<annotation title="sub">
\n\nBase jurídica para o processamento
</annotation>

\n\nO Proprietário poderá processar os Dados Pessoais relacionados ao Usuário
se uma das hipóteses a seguir se aplicar:

\n\n&#8226; Os Usuários tenham dado a sua anuência para uma ou mais finalidades
específicas; Observação: De acordo com algumas legislações o
Proprietário poderá ter a permissão para processar os Dados Pessoais
ATÉ QUE O Usuário faça objeção a isto (“opt-out”), sem ter que se
basear em anuência ou em quaisquer outras bases jurídicas a seguir.
Isto contudo não se aplica sempre que o processamento de Dados
Pessoais estiver sujeito à legislação europeia de proteção de dados;

\n\n&#8226; o fornecimento dos Dados for necessário para o cumprimento de um
contrato com o Usuário e/ou quaisquer obrigações pré-contratuais
do mesmo;

\n\n&#8226; o processamento for necessário para o cumprimento de uma obrigação
jurídica à qual o Proprietário estiver sujeito;

\n\n&#8226; o processamento estiver relacionado a uma tarefa que for executada
no interesse público ou no exercício de uma autorização oficial na
qual o Proprietário estiver investido;

\n\n&#8226; o processamento for necessário para a finalidade de interesses
legítimos perseguidos pelo Proprietário ou por um terceiro.

\n\nEm qualquer caso, o Proprietário colaborará de bom grado para esclarecer
qual a base jurídica que se aplica ao processamento, e em especial se o
fornecimento de Dados for um requisito obrigatório por força de lei ou
contratual, ou uma exigência necessária para celebrar um contrato.


<annotation title="sub">
\n\nLugar
</annotation>

\n\nOs dados são processados ​​nas sedes de operação dos Proprietários, e em
quaisquer outros lugares onde as partes envolvidas com o processamento
estiverem localizadas.

\n\nDependendo da localização do Usuário as transferências de dados poderão
envolver a transferência dos Dados do Usuário para outro país que não seja
o seu. Para descobrirem mais sobre o local de processamento de tais Dados
transferidos os Usuários poderão verificar a seção contendo os detalhes
sobre o processamento de Dados Pessoais.

\n\nOs Usuários também possuem o direito de serem informados sobre a base
jurídica das transferências de Dados para países de fora da União Europeia
ou para quaisquer organizações internacionais regidas pelo direito
internacional público ou formadas por dois ou mais países, tal como a ONU,
e sobre as medidas de segurança tomadas pelo Proprietário para proteger os
seus Dados.

\n\nSe ocorrerem quaisquer tais transferências os Usuários poderão descobrir
mais a respeito verificando as seções pertinentes deste documento ou
perguntando ao Proprietário utilizando as informações fornecidas na seção
de contatos.

<annotation title="sub">
\n\nPeríodo de conservação
</annotation>

\n\nOs Dados Pessoais serão processados e armazenados pelo tempo que for
necessário para as finalidades para as quais forem coletados.

\n\nPortanto:

\n\n&#8226; Os Dados Pessoais coletados para as finalidades relacionadas
com a execução de um contrato entre o Proprietário e o Usuário serão
conservados até que tal contrato tenha sido completamente cumprido;

\n\n&#8226; Os Dados Pessoais coletados para as finalidades relacionadas
com os legítimos interesses do Proprietário serão conservados pelo tempo
que for necessário para cumprir tais finalidades. Os Usuários poderão
obter informações específicas sobre os interesses legítimos perseguidos
pelo Proprietário dentro das seções pertinentes deste documento ou
entrando em contato com o Proprietário.

\n\nO Proprietário poderá ter a permissão de conservar os Dados Pessoais por
um prazo maior sempre que o Usuário tiver dado a sua autorização para tal
processamento, enquanto tal autorização não tiver sido retirada. Além disso,
o Proprietário poderá ficar obrigado a conservar os Dados Pessoais por um
prazo maior em todas as ocasiões em que estiver obrigado a fazê-lo para o
cumprimento de uma obrigação jurídica ou em cumprimento de um mandado de uma
autoridade.

\n\nAssim que o prazo de conservação vencer os Dados Pessoais serão apagados.
Desta forma o direito de acessar, o direito de apagar, o direito de corrigir
e o direito à portabilidade dos dados não poderão ter o seu cumprimento
exigido após o vencimento do prazo de conservação.


<annotation title="main">
\n\nAs finalidades do processamento
</annotation>

\n\nOs Dados relativos ao Usuário são coletados para permitir que o
Proprietário forneça os seus Serviços, bem como para os seguintes
propósitos: Visualizar conteúdo de plataformas externas, Comentário de
conteúdo, Interações baseadas na localização, Processamento de pagamentos,
Hospedagem e infraestrutura de backend e Registro e autenticação.

\n\nOs Usuários poderão obter informações adicionais detalhadas sobre tais
finalidades do processamento e sobre os Dados Pessoais específicos utilizados
para cada finalidade nas seções respectivas deste documento.


<annotation title="main">
\n\nInformações detalhadas sobre o processamento de Dados Pessoais
</annotation>

\n\nOs Dados Pessoais são recolhidos para os seguintes fins e utilizando
os seguintes serviços:

<annotation title="sub">
\n\nComentário de conteúdo
</annotation>

\n\nOs serviços de comentário de conteúdo permitem Usuários a criar e publicar
comentários sobre o conteúdo deste serviço (este Aplicativo).

\n\nDependendo das configurações escolhidas pelo Proprietário, os Usuários
podem também deixar comentários anônimos. Se houver um endereço de e-mail
entre os Dados Pessoais fornecidos pelo Usuário, poderá ser usado para
enviar notificações de comentários sobre o mesmo conteúdo. Os Usuários
são responsáveis pelo conteúdo de seus comentários.

\n\nSe um serviço de comentário de conteúdo prestado por terceiros esteja
instalado, este ainda poderá coletar dados de tráfego da web para as
páginas onde o serviço de comentário esteja instalado, mesmo quando os
usuários não usam o serviço de conteúdo de comentário.

<annotation title="sub_sub">
\n\nSistema de Comentário gerido diretamente (este Aplicativo)
</annotation>

\n\nEste Aplicativo tem seu próprio sistema de comentários de conteúdo
interno.

\n\nDados Pessoais coletados: nome.

<annotation title="sub">
\n\nHospedagem e infraestrutura de backend
</annotation>

\n\nEstes tipos de serviços têm a finalidade de hospedagem de Dados e
arquivos que permitem que este Aplicativo seja executado e distribuído,
bem com para fornecer infraestrutura para executar recursos ou partes
deste serviço (este Aplicativo).

\n\nAlguns desses serviços funcionam através de servidores distribuídos
geograficamente, o que torna difícil determinar a localização real onde
os Dados Pessoais estão armazenados.

<annotation title="sub_sub">
\n\nHeroku (Salesforce.com, inc.)
</annotation>

\n\nHeroku é um serviço de hospedagem fornecido pela Salesforce.com, inc.

\n\nDados Pessoais coletados: vários tipos de Dados como especificados na
política de privacidade do serviço.

\n\nLugar de processamento: EUA –
<annotation link="https://www.salesforce.com/company/privacy/full_privacy.jsp">
Política de Privacidade.
</annotation>

<annotation title="sub">
\n\nInterações baseadas na localização
</annotation>

<annotation title="sub_sub">
\n\nLocalização geográfica discontínua (este Aplicativo)
</annotation>

\n\nEste Aplicativo pode coletar, usar e compartilhar a localização de dados
do Usuário a fim de fornecer serviços baseados em localização.

\n\nA maioria dos navegadores e dispositivos fornecem ferramentas para optar
o não uso este recurso de padrão. Se a autorização explícita foi
fornecida, os dados de localização do Usuário podem serem rastreado por
este Aplicativo.

\n\nA localização geográfica do Usuário è determinada de uma maneira que
não è contínua, quando de pedido especifico do usuário ou quando o
Usuário não fornece sua localização atual no campo apropriado e permite
que a aplicação a detectar a posição automaticamente.

\n\nDados Pessoais coletados: posição geográfica.

<annotation title="sub">
\n\nProcessamento de pagamentos
</annotation>

\n\nServiços de processamento de pagamento permitem a este Aplicativo
processar pagamentos por cartão de crédito, transferência bancária ou
por outros meios. Para garantir maior segurança, este Aplicativo fornece
somente as informações necessárias para executar a transação com os
intermediários financeiros que operam a transação.

\n\nAlguns desses servicos podem tambem habilitar o envio de mensagens com
tempo programado ao Usuário de este Aplicativo tais como faturas
baseadas em email e outras notificações.

<annotation title="sub_sub">
\n\nStripe (Stripe Inc)
</annotation>

\n\nStripe é um serviço de pagamento fornecido pelo Stripe Inc.

\n\nDados Pessoais coletados: vários tipos de Dados como especificados na
política de privacidade do serviço.

\n\nLugar de processamento: EUA –
<annotation link="https://stripe.com/us/privacy">
Política de Privacidade.
</annotation>
Participante do Privacy Shield.

<annotation title="sub">
\n\nRegistro e autenticação
</annotation>

\n\nAo se registrar ou autenticar, os Usuários permitem a este serviço
(este Aplicativo) identificá-los e dar-lhes o acesso a serviços
dedicados. Dependendo do que estiver descrito abaixo, os serviços de
registro e autenticação podem ser fornecidos por terceiros. Neste
caso, este Aplicativo poderá acessar alguns Dados armazenados por
estes serviços de terceiros para fins de registro ou identificação.

<annotation title="sub_sub">
\n\nRegistro direto (este Aplicativo)
</annotation>

\n\nO Usuário se registra ao preencher o formulário de inscrição e
fornecer os Dados Pessoais diretamente para este Aplicativo.

\n\nDados Pessoais coletados: nome de Usuário; senha.

<annotation title="sub">
\n\nVisualizar conteúdo de plataformas externas
</annotation>

\n\nEstes tipos de serviços permitem que você visualize e interaja com
o conteúdo hospedado em plataformas externas diretamente a partir
das páginas deste serviço (este Aplicativo) e interaja com estes.

\n\nEste tipo de serviço poderá ainda coletar dados de tráfego da web
para as páginas onde o serviço estiver instalado, mesmo quando os
usuários não os estiverem utilizando.


<annotation title="main">
\n\nInformações adicionais sobre os Dados Pessoais
</annotation>

<annotation title="sub">
\n\nNotificações push
</annotation>

\n\nEste Aplicativo pode enviar notificações push para o Usuário.

<annotation title="sub">
\n\nVenda de produtos e serviços online
</annotation>

\n\nOs dados pessoais recolhidos são usados para fornecer ao Usuário
serviços ou para vender produtos, incluindo o pagamento e possível
entrega.

\n\nOs Dados Pessoais recolhidos para completar o pagamento podem estar
relacionados com o cartão de crédito, a conta bancária utilizada
para a transferência, ou quaisquer outros meios de pagamento
previstos. O tipo de Dados coletados dependem do sistema de pagamento
utilizado.

<annotation title="sub">
\n\nO Serviço não é direcionado para crianças menores de 13 anos.
</annotation>

\n\nOs usuários declaram que são maiores de idade de acordo com a legislação
aplicável. Os menores podem usar este Aplicativo apenas com a assistência
de um dos pais ou responsável. Sob nenhuma circunstância as pessoas com
menos de 13 anos podem utilizar este Aplicativo.


<annotation title="main">
\n\nOs direitos dos Usuários
</annotation>

\n\nOs Usuários poderão exercer determinados direitos a respeito dos seus
Dados processados pelo Proprietário.

\n\nEm especial, os Usuários possuem os direitos a fazer o seguinte:

\n\n&#8226; <b>Retirar a sua anuência a qualquer momento.</b> Os Usuários
possuem o direito de retirar a sua anuência nos casos em que tenham
dado a sua anuência anteriormente para o processamento dos seus Dados
Pessoais;

\n\n&#8226; <b>Objetar o processamento dos seus Dados.</b> Os Usuários
possuem o direito de objetar o processamento dos seus Dados se o
processamento for executado sobre outra base jurídica que não a
anuência. São fornecidos detalhes adicionais na seção específica
abaixo;

\n\n&#8226; <b>Acessar os seus Dados.</b> Os Usuários possuem o direito
de saber se os seus Dados estão sendo processados pelo Proprietário,
obter revelações sobre determinados aspectos do processamento e
conseguir uma cópia dos Dados que estiverem sendo processados;

\n\n&#8226; <b>Verificar e pedir retificação.</b> Os Usuários possuem o
direito de verificar a exatidão dos seus Dados e de pedir que os
mesmos sejam atualizados ou corrigidos;

\n\n&#8226; <b>Restringir o processamento dos seus Dados.</b> Os Usuários
possuem o direito de, sob determinadas circunstâncias, restringir o
processamento dos seus Dados para qualquer outra finalidade que não
seja o armazenamento dos mesmos;

\n\n&#8226; <b>Ter os seus Dados Pessoais apagados ou retirados de outra
maneira.</b> Os Usuários possuem o direito de, sob determinadas
circunstâncias, obter a eliminação dos seus Dados do Proprietário;

\n\n&#8226; <b>Receber os seus Dados e ter os mesmos transferidos para
outro controlador.</b> Os Usuários possuem o direito de receber os
seus Dados em um formato estruturado, utilizado comumente e apto a
ser lido por máquinas e, se for viável tecnicamente, fazer com que
os mesmos sejam transmitidos para outro controlador sem nenhum
empecilho. Esta determinação se aplica condicionada a que os Dados
sejam processados por meios automatizados e que o processamento
esteja baseado na anuência do Usuário, em um contrato do qual o
Usuário seja uma das partes ou por obrigações pré-contratuais do
mesmo;

\n\n&#8226; <b>Registrar uma reclamação.</b> Os Usuários possuem o
direito de apresentar reclamação perante a sua autoridade de proteção
de dados competente.

<annotation title="sub">
\n\nDetalhes sobre o direito de objetar ao processamento
</annotation>

\n\nNos casos em que os Dados Pessoais forem processados por um interesse
público, no exercício de uma autorização oficial na qual o Proprietário
estiver investido ou para finalidades dos interesses legítimos
perseguidos pelo Proprietário, os Usuários poderão objetar tal
processamento através do fornecimento de um motivo relacionado com a
sua situação em especial para justificar a objeção.

\n\nOs Usuários devem saber, entretanto, que caso os seus Dados Pessoais
sejam processados para finalidades de marketing direto eles podem
objetar tal processamento a qualquer momento sem fornecer nenhuma
justificativa. Os Usuários podem consultar as seções respectivas deste
documento.

<annotation title="sub">
\n\nComo exercer estes direitos
</annotation>

\n\nQuaisquer pedidos para exercer os direitos dos Usuários podem ser
direcionados ao Proprietário através dos dados para contato fornecidos
neste documento. Estes pedidos podem ser exercidos sem nenhum custo e
serão atendidos pelo Proprietário com a maior brevidade possível e em
todos os casos em prazo inferior a um mês.


<annotation title="main">
\n\nInformações adicionais sobre a coleta e processamento de Dados
</annotation>

<annotation title="sub">
\n\nAção jurídica
</annotation>

\n\nOs Dados Pessoais dos Usuários podem ser utilizados para fins jurídicos
pelo Proprietário em juízo ou nas etapas conducentes à possível ação
jurídica decorrente de uso indevido deste Serviço (este Aplicativo) ou
dos Serviços relacionados.

\n\nO Usuário declara estar ciente de que o Proprietário poderá ser obrigado
a revelar os Dados Pessoais mediante solicitação das autoridades
governamentais.

<annotation title="sub">
\n\nInformações adicionais sobre os Dados Pessoais do Usuário
</annotation>

\n\nAlém das informações contidas nesta política de privacidade, este
Aplicativo poderá fornecer ao Usuário informações adicionais e
contextuais sobre os serviços específicos ou a coleta e processamento
de Dados Pessoais mediante solicitação.

<annotation title="sub">
\n\nLogs do sistema e manutenção
</annotation>

\n\nPara fins de operação e manutenção, este Aplicativo e quaisquer
serviços de terceiros poderão coletar arquivos que gravam a interação
com este Aplicativo (logs do sistema) ou usar outros Dados Pessoais
(tais como endereço IP) para esta finalidade.

<annotation title="sub">
\n\nAs informações não contidas nesta política
</annotation>

\n\nMais detalhes sobre a coleta ou processamento de Dados Pessoais podem
ser solicitados ao Proprietário, a qualquer momento. Favor ver as
informações de contato no início deste documento.

<annotation title="sub">
\n\nComo são tratados os pedidos de “Não me Rastreie”
</annotation>

\n\nEste Aplicativo não suporta pedidos de “Não Me Rastreie”.

\n\nPara determinar se qualquer um dos serviços de terceiros que utiliza
honram solicitações de “Não Me Rastreie”, por favor leia as políticas
de privacidade.

<annotation title="sub">
\n\nMudanças nesta política de privacidade
</annotation>

\n\nO Proprietário se reserva o direito de fazer alterações nesta política
de privacidade a qualquer momento, mediante comunicação aos seus Usuários
nesta página e possivelmente dentro deste Serviço este Aplicativo e/ou
– na medida em que for viável tecnicamente e juridicamente – enviando
um aviso para os Usuários através de quaisquer informações de contato
disponíveis para o Proprietário. É altamente recomendável que esta
página seja consultada várias vezes em relação à última modificação
descrita na parte inferior.

\n\nCaso as mudanças afetem as atividades de processamento realizadas com
base na anuência do Usuário, o Proprietário coletará nova anuência do
Usuário, onde for exigida.


<annotation title="main">
\n\nDefinições e referências jurídicas
</annotation>

<annotation title="sub">
\n\nDados Pessoais (ou Dados)
</annotation>

\n\nQuaisquer informações que diretamente, indiretamente ou em relação com
outras informações – incluindo um número de identificação pessoal –
permitam a identificação ou identificabilidade de uma pessoa física.

<annotation title="sub">
\n\nDados de Uso
</annotation>

\n\nAs informações coletadas automaticamente através deste este Aplicativo
(ou serviços de terceiros contratados neste Serviço (este Aplicativo)),
que podem incluir: os endereços IP ou nomes de domínio dos computadores
utilizados pelos Usuários que utilizam este Aplicativo, os endereços
URI (Identificador Uniforme de Recurso), a data e hora do pedido, o
método utilizado para submeter o pedido ao servidor, o tamanho do
arquivo recebido em resposta, o código numérico que indica o status do
servidor de resposta (resultado positivo, erro , etc.), o país de
origem, as características do navegador e do sistema operacional
utilizado pelo Usuário, os vários detalhes de tempo por visita (por
exemplo, o tempo gasto em cada página dentro do aplicativo) e os
detalhes sobre o caminho seguido dentro da aplicação, com especial
referência à sequência de páginas visitadas e outros parâmetros sobre
o sistema operacional do dispositivo e/ou ambiente de TI do Usuário.

<annotation title="sub">
\n\nUsuário
</annotation>

\n\nA pessoa que usa este Aplicativo que, a menos que especificado
diferentemente, coincida com o Titular dos Dados.

<annotation title="sub">
\n\nTitular dos Dados
</annotation>

\n\nA pessoa física a quem os Dados Pessoais se referem.

<annotation title="sub">
\n\nProcessador de Dados (ou supervisor de Dados)
</annotation>

\n\nA pessoa física ou jurídica, administração pública, agência ou outro
órgão que processe os Dados Pessoais em nome do Controlador conforme
descrito nesta política de privacidade.

<annotation title="sub">
\n\nControlador de Dados (ou Proprietário)
</annotation>

\n\nA pessoa física ou jurídica, administração pública, agência ou outro
órgão que, isoladamente ou em conjunto com outros determinar as
finalidades e os meios de processamento dos Dados Pessoais, incluindo
medidas de segurança relativas ao funcionamento e ao uso deste Serviço
(este Aplicativo). O Controlador de Dados, a menos que seja especificado
de outra forma, é o Proprietário deste Serviço (este Aplicativo).

<annotation title="sub">
\n\nEste Aplicativo
</annotation>

\n\nO meio pelo qual os Dados Pessoais do Usuário são coletados e processados.

<annotation title="sub">
\n\nServiço
</annotation>

\n\nO serviço fornecido por este Aplicativo conforme descrito nos termos
relativos (se disponíveis) e neste site/aplicativo.

<annotation title="sub">
\n\nUnião Europeia (ou UE)
</annotation>

\n\nA menos que especificado diferentemente, todas as referências feitas
neste documento à União Europeia incluem todos os atuais estados membros
da União Europeia e do Espaço Econômico Europeu.

<annotation title="sub">
\n\nCookie
</annotation>

\n\nPequenas unidades de dados armazenados no dispositivo do Usuário.

<annotation title="sub">
\n\nInformação jurídica
</annotation>

\n\nEsta declaração de privacidade foi preparada com base em determinações
demúltiplas legislações, inclusive os Arts. 13/14 do Regulamento (EU)
2016/679 (GDPR - Regulamento Geral de Proteção de Dados).

\n\nEsta política de privacidade se refere somente a este Aplicativo, se
não afirmado diferentemente neste documento.
</string>
</resources>

 

Essa separação de códigos estáticos de String foi necessária para não "embolarmos" todo o texto já existente em /res/values/strings.xml.

Thiengo, o que são essas tags <annotation> junto a tags HTML e a caracteres de quebra de linha (\n)?

As tags <annotation> vão nos permitir construir uma formatação adequada ao texto de políticas de privacidade utilizando somente um TextView.

Tenho um artigo completo sobre as tags <annotation>, não deixe de estuda-lo assim que terminar este conteúdo: Annotation Span Para Estilização de Texto no Android.

As tags HTML são uma maneira simples de trabalharmos formatação em texto no XML Android. Infelizmente somente algumas tags são aceitas.

Sobre os caracteres de nova linha, \n, essa estratégia estudaremos melhor em seção posterior, pois ainda é preciso o trabalho em código dinâmico para entender o porquê desta estratégia com este caractere.

Ok, mas o que significa o uso de &#8226;?

O código &#8226; é para que possamos colocar com maior facilidade em texto um ícone circular de marcação de item de lista, para obter o resultado como a seguir:

Itens de lista em políticas de privacidade

Heroku e Stripe, estas serão as empresas?

Se você leu as políticas de privacidade gerada para o nosso aplicativo Android de mobile-commerce, deve ter notado dois trechos específicos sobre as empresas Heroku e Stripe.

Na verdade esses trechos foram adicionados já visando a modificação futura deles, ao menos dos nomes dessas empresas. Isso, pois ainda escolheremos as instituições necessárias no decorrer do desenvolvimento do projeto. Instituições respectivamente de:

Ou seja, antes do final do projeto, ao menos os blocos sobre as empresas Heroku e Stripe serão atualizados no texto de políticas e privacidade.

Criando o PrivacyPolicyFragment

No pacote /view do projeto, siga:

  • Clique com o botão direito do mouse;
  • Acesse New;
  • Então acesse Fragment;
  • Clique em Fragment (Blank);
  • Na caixa de diálogo aberta:
    • Em Fragment Name coloque PrivacyPolicyFragment;
    • Em Fragment Layout Name continue com fragment_privacy_policy;
    • Desmarque a opção Include fragment factory method?;
    • Desmarque a opção Include callbacks?;
    • Em Source Language permaneça com Kotlin;
    • Por fim clique em Finish.

Criando o fragmento PrivacyPolicyFragment

Ao final da criação de PrivacyPolicyFragment, deixe o código inicial dele como abaixo:

class PrivacyPolicyFragment : Fragment() {

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {

return inflater
.inflate(
R.layout.fragment_policy_privacy,
container,
false
)
}
}

Layout mínimo

O "mínimo" é devido ao tamanho deste novo layout em relação aos layouts de fragmentos já apresentados. Em /res/layout/fragment_privacy_policy.xml coloque o código XML a seguir:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
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"
android:scrollbars="vertical"
tools:context=".view.PrivacyPolicyFragment">

<TextView
android:id="@+id/tv_privacy_policy_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:bufferType="spannable"
android:textColor="@color/colorText"/>
</android.support.v4.widget.NestedScrollView>

 

A seguir o diagrama do layout anterior:

Diagrama do layout fragment_privacy_policy.xml

Você provavelmente deve estar se perguntando: Por que não utilizar somente um TextView ao invés de também um ViewGroup de scroll?

Isso, pois o TextView tem um scroll menos eficiente do que qualquer outro ViewGroup de scroll. Ele fica "agarrando", não rola de acordo com o acionamento do usuário.

Método para processamento das anotações

As anotações presentes no texto de políticas de privacidade devem ser acompanhadas de algoritmos dinâmicos que apliquem as devidas formatações em texto.

Logo, vamos adicionar em PrivacyPolicyFragment dois métodos:

  • Um responsável por conter todo o algoritmo de processamento de anotações;
  • Outro responsável por invocar o método criado no item anterior. Esse deve ser um método do ciclo de vida do fragmento e que seja invocado depois do método onCreateActivity(), isso, para que o acesso ao TextView de ID tv_privacy_policy_content seja por meio da sintaxe do kotlin-android-extensions.

No novo fragmento, adicione os códigos em destaque:

class PrivacyPolicyFragment : Fragment() {
...

override fun onActivityCreated( savedInstanceState: Bundle? ) {
super.onActivityCreated( savedInstanceState )

/*
* Vamos manter a invocação do método privacyPolicyLoad()
* em um método que vem depois do método onCreateActivity()
* para assim podermos manter a sintaxe
* kotlin-android-extensions de acesso às Views do layout
* do fragmento.
* */
privacyPolicyLoad()
}

private fun privacyPolicyLoad(){

/*
* Aplicando o casting de CharSequence para SpannedString
* para que seja possível acessar as Spans presentes no
* texto.
*
* É preciso utilizar getText(), que retorna um CharSequence.
* getString() retorna uma String e Strings não contém Spans.
* */
val text = getText( R.string.privacy_policy_content ) as SpannedString

/*
* Obtendo todas as Annotation Span do texto.
* */
val annotations = text.getSpans(
0, /* Posição inicial do texto. */
text.length, /* Posição final do texto. */
Annotation::class.java /* Classe Span (ParcelableSpan) para recolher objetos do tipo. */
)

/*
* Criando uma cópia do texto, com SpannableString,
* para que seja possível adicionar ou remover Span além
* de também ser possível adicionar ou remover caracteres.
* */
val spannedText = SpannableString( text )

/*
* Iterando sobre todas as annotations encontradas.
* */
for( annotation in annotations ){

/* TODO */
}

/*
* Colocando o texto estilizado no TextView de
* Políticas de Privacidade.
*
* A invocação do método trimStart() a seguir se
* faz necessária como uma estratégia para remover
* o espaço em branco do início do texto de
* Políticas de Privacidade no arquivo XML.
* */
tv_privacy_policy_content.text = spannedText.trimStart()
}
}

 

Agora nosso foco é principalmente nos códigos que entrarão no loop for() de privacyPolicyLoad().

Antes de continuar, para saber mais o potencial de estilização de textos no Android utilizando SpannedString, acesse o artigo a seguir: Como Utilizar Spannable no Android Para Customizar Strings.

O boilerplate de CustomTypefaceSpan

Antes de já partirmos para as codificações no novo método privacyPolicyLoad(), vamos primeiro adicionar ao pacote /util do projeto uma classe, com código boilerplate, que permitirá o uso de família de fonte personalizada por meio de objetos Span.

No pacote /util crie a classe CustomTypefaceSpan como a seguir:

class CustomTypefaceSpan( typeFace: Typeface ) :
TypefaceSpan( "" ) {

val newTypeFace = typeFace

override fun updateDrawState( paint: TextPaint ) {
applyCustomTypeFace( paint, newTypeFace )
}

override fun updateMeasureState( paint: TextPaint ) {
applyCustomTypeFace( paint, newTypeFace )
}

private fun applyCustomTypeFace(
paint: Paint,
typeface: Typeface
) {

val styleAnterior: Int
val typefaceAnterior = paint.getTypeface()

if( typefaceAnterior == null ){
styleAnterior = 0
}
else {
styleAnterior = typefaceAnterior.getStyle()
}

/*
* Para verificar a compatibilidade de estilos.
* */
val fake = styleAnterior and typeface.style.inv()

/*
* Verifica se a fonte mais atual já está de acordo
* com a anterior em termos de "texto em negrito",
* caso não, atualiza.
* */
if( fake and Typeface.BOLD != 0 ) {
paint.setFakeBoldText( true )
}

/*
* Verifica se a fonte mais atual já está de acordo
* com a anterior em termos de "texto em itálico",
* caso não, atualiza.
* */
if( fake and Typeface.ITALIC != 0 ){
paint.setTextSkewX( -0.25f )
}

/*
* Aplica a fonte.
* */
paint.setTypeface( typeface )
}
}

Estilizando anotações de títulos

Há três tipos de título no texto de políticas de privacidade:

  • Título principal de bloco - <annotation title="main">;

Título principal de bloco

  • Subtítulo de bloco - <annotation title="sub">;

Subtítulo de bloco

  • Sub-subtítulo de bloco - <annotation title="sub_sub">.

Sub-subtítulo de bloco

Todos basicamente com a mesma formatação:

  • Família de fonte: Pathway Gothic One (já presente no folder /res/font do projeto);
  • Estilo: negrito.

Eles se diferenciam somente em tamanho de fonte.

Dentro do loop for() de privacyPolicyLoad() em PrivacyPolicyFragment adicione os códigos em destaque:

...
private fun privacyPolicyLoad(){
...

for( annotation in annotations ){

val textStartPos = text.getSpanStart( annotation )
val textEndPos = text.getSpanEnd( annotation )
val spanFlag = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE

if( annotation.key.equals("title") ){ /* Títulos. */
/*
* Todos os títulos têm uma fonte customizada
* aplicada a eles, mais precisamente a fonte
* Pathway Gothic One.
* */
val typeFace = ResourcesCompat
.getFont(
activity!!,
R.font.pathway_gothic_one_regular
)
spannedText.setSpan(
CustomTypefaceSpan( typeFace!! ),
textStartPos,
textEndPos,
spanFlag
)

/*
* Todos os títulos têm o estilo negrito aplicado a
* eles.
* */
spannedText.setSpan(
StyleSpan( Typeface.BOLD ),
textStartPos,
textEndPos,
spanFlag
)

/*
* Obtendo o tamanho correto do texto de acordo com a
* Annotation Span de título presente nele.
* */
val textSizeSpan = when( annotation.value ){
"main" -> RelativeSizeSpan( 1.5F )
"sub" -> RelativeSizeSpan( 1.3F )
else -> RelativeSizeSpan( 1.1F ) /* "sub_sub" */
}
spannedText.setSpan(
textSizeSpan,
textStartPos,
textEndPos,
spanFlag
)
}
}
...
}
...

 

Com o código anterior adicionado já conseguimos as formatações exigidas para os tipos de título presentes em texto.

Interpretando links em texto estático

Parte de nossa política de privacidade é apontar para a política de privacidade de APIs de terceiros que estão sendo utilizadas.

Com isso temos de interpretar anotações de links presentes no texto de políticas, porém com a estilização real de um link:

  • Cor: azul link (já presente em /res/values/colors.xml como colorLink);
  • Estilo: sublinhado (adicionado por padrão quando colocando link via objeto Span).

Dentro do método privacyPolicyLoad() do fragmento de políticas, adicione os códigos em destaque para interpretar <annotation link="...">:

...
private fun privacyPolicyLoad(){
...

for( annotation in annotations ){
...

if( annotation.key.equals("title") ){ /* Títulos. */
...
}
else if( annotation.key.equals("link") ){ /* Links. */

/*
* Os "+ 1" e "- 1" sendo utilizados é
* para evitar que trechos que não fazem
* parte do texto de link sejam
* adicionados ao link.
* */
spannedText.setSpan(
URLSpan( annotation.value ),
textStartPos + 1,
textEndPos - 1,
spanFlag
)

/*
* Colocando a cor de link utilizado
* neste projeto Android, pois este é
* um trecho de âncora dentro das
* políticas de privacidade.
* */
spannedText.setSpan(
ForegroundColorSpan(
ContextCompat
.getColor(
activity!!,
R.color.colorLink
)
),
textStartPos + 1,
textEndPos - 1,
spanFlag
)
}
}

/*
* Para que o trecho de texto com Span de link externo
* possa ser clicável. É preciso configurar um
* LinkMovementMethod.
* */
tv_privacy_policy_content.movementMethod = LinkMovementMethod.getInstance()

...
}
...

 

Com o código de link anterior conseguimos o seguinte resultado em tela:

Link via Annotation Span e SpannedString

Título do fragmento

Como também utilizado nos fragmentos já criados, ainda falta aqui o código no onResume() que coloque como título em barra de topo o rótulo do fragmento de políticas.

Em PrivacyPolicyFragment adicione:

...
override fun onResume() {
super.onResume()

(activity as MainActivity)
.updateToolbarTitleInFragment( R.string.privacy_policy_frag_title )
}
...

Por que "\n\n" e trimStart()?

Com os códigos dinâmicos do novo fragmento já apresentados, podemos melhor discutir o porquê dos "\n\n" e trimStart().

O método trimStart() está sendo invocado para remover o seguinte espaço em branco no primeiro título do texto de políticas:

Título sem trimStart()

Isso ocorre devido a quebras de linha no código estático de políticas:

<resources>
<string name="privacy_policy_content">
<annotation title="main">
Proprietário e Controlador de Dados
</annotation>
...

 

O uso de "\n\n" no início de cada título e parágrafo do texto de política é para evitar que o conteúdo seja apresentado sempre com a formatação contendo um espaço em brando na frente de títulos e parágrafos como na imagem a seguir:

Títulos e parágrafos sem \n\n

Ok Thiengo, mas não seria melhor, no caso do "\n\n", utilizar um algoritmo para adicionar estes caracteres de nova linha ou até mesmo um algoritmo que removesse os espaços em branco com um melhor posicionamento dos caracteres "\n\n"?

Na verdade, não. Utilizei alguns algoritmos antes de tomar a decisão de colocar, "na unha", os "\n\n" no texto de políticas. Algoritmos como o a seguir:

...
/*
* Removendo todos os espaços em branco que são
* acrescentados logo após às quebras de linhas
* "\n\n".
*
* O padrão a ser encontrado é "\n " (caractere de
* nova linha e então um espaço em branco). Depois
* acessamos somente a posição do espaço em branco,
* pois é ele que irá ser removido, caso contrário
* fica um espaço em branco no início de cada
* título ou parágrafo do texto de políticas de
* privacidade.
* */
while( spannedText.indexOf("\n ") > -1){
spannedText = spannedText.replace(
spannedText.indexOf("\n ") + 1,
spannedText.indexOf("\n ") + 2,
""
)
}
...

 

Porém, devido a quantidade de padrões de caracteres encontrados, o código fica lento e é perceptível ao usuário, atrapalhando em muito a boa experiência dele no app. O menu gaveta, por exemplo, chega a travar por alguns instantes.

Sendo assim, mesmo que não seja agradável, adicionar na mão os "\n\n" no início dos títulos e parágrafos, isso fez com que o problema dos espaços em branco fosse resolvido sem que algum novo problema fosse criado à experiência do usuário.

Vale ressaltar que as políticas de privacidade tendem a passar por poucas ou nenhuma atualização no ano. Se as atualizações fossem mensais, por exemplo, então seria melhor "quebrarmos a cabeça" para buscar uma solução mais automatizada.

Atualização na atividade principal

Aqui vamos:

  • Adicionar ao método getFragment() o trecho de seleção de PrivacyPolicyFragment.

Atualizando getFragment()

No método getFragment() da MainActivity adicione o código em destaque:

...
private fun getFragment( fragId: Long ): Fragment{

return when( fragId ){
R.id.item_about.toLong() -> AboutFragment()
R.id.item_contact.toLong() -> ContactFragment()
R.id.item_privacy_policy.toLong() -> PrivacyPolicyFragment()
else -> AboutFragment()
}
}
...

 

Assim podemos partir para os testes e resultados.

Testes e resultados

Abra o Android Studio, no menu de topo dele siga para "Build", então clique em "Rebuid project". Ao final do rebuild execute o aplicativo em seu aparelho ou emulador Android de testes.

Tendo em teste o usuário com o status "conectado", objeto presente na MainActivity:

...
val user = User(
"Thiengo Vinícius",
R.drawable.user,
true
)
...

 

Temos:

Acessando as políticas de privacidade do app Android BlueShoes

Acionando um link externo, temos:

Animação do link externo abrindo da políticas de privacidade do app Android BlueShoes

Assim finalizamos a quinta parte do projeto Android de mobile-commerce.

Não deixe de se inscrever na 📩 lista de emails do Blog para continuar acompanhando todo o projeto e também para receber dicas sobre desenvolvimento Android.

Se inscreva também no canal do Blog em: YouTube Thiengo.

Vídeos

A seguir os vídeos com o passo a passo do desenvolvimento do PrivacyPolicyFragment do Android BlueShoes.

O projeto também pode ser acessado pelo GitHub dele em: https://github.com/viniciusthiengo/blueshoes-kotlin-android.

Conclusão

Diferente do que alguns desenvolvedores podem ter pensado, não foi necessário inúmeros TextViews para conseguir a formatação necessária em texto de políticas de privacidade.

É em situações assim que o conhecimento mais apurado de APIs Android lhe ajuda no desenvolvimento, isso, pois o trabalho com Strings Spanned e com Annotation Span é algo pouco utilizado e divulgado no mundo de desenvolvimento Android.

Vale ressaltar que as políticas de privacidade certamente passarão por atualização até o fim do projeto para ao menos colocarmos as empresas corretas de hospedagem e pagamentos.

Caso você tenha dúvidas ou dicas para este projeto, deixe logo abaixo nos comentários.

Curtiu o conteúdo? Não esqueça de compartilha-lo. E, por fim, não deixe de se inscrever na 📩 lista de emails, respondo às suas dúvidas também por lá.

Abraço.

Fontes 

General Data Protection Regulation

O que é GDPR e que diferença isso faz para quem é brasileiro

O que é o GDPR e como isso pode afetar o marketing de sua empresa

GDPR - Parlamento Europeu e do Conselho

O que é GDPR?

GDPR: SEUS IMPACTOS NO BRASIL E NO MUNDO - Dra. Patricia Peck Pinheiro

Lei Geral de Proteção de Dados (LGPD): por onde começar?

Conheça a LGPD - Lei Geral de Proteção de Dados a GDPR do Brasil | Digitalizando News #6

Different font size of strings in the same TextView - Resposta de Raghunandan e Nilesh Rathod

Android Kotlin .replaceRange does not replace text in SpannableString - Resposta de guenhter

String Resource new line /n not possible? - Resposta de Peter

Kotlin count occurance of charArray in String - Resposta de Kamran

HTML punctuation - Bullet

Investir em Você é Barra de Ouro a R$ 2,00. Cadastre-se e receba grátis conteúdos Android sem precedentes!
Email inválido

Relacionado

Android Mobile-Commerce, Apresentação e Protótipo do ProjetoAndroid Mobile-Commerce, Apresentação e Protótipo do ProjetoAndroid
Início de Projeto e Menu Gaveta Customizado - Android M-CommerceInício de Projeto e Menu Gaveta Customizado - Android M-CommerceAndroid
Fragmento da Tela Sobre e Links Sociais - Android M-CommerceFragmento da Tela Sobre e Links Sociais - Android M-CommerceAndroid
Localização com Rota GPS, E-mail e Telefones - Android M-CommerceLocalização com Rota GPS, E-mail e Telefones - Android M-CommerceAndroid

Compartilhar

Comentários Facebook

Comentários Blog

Para código / script, coloque entre [code] e [/code] para receber marcação especifica.
Forneça seu nome válido.
Forneça seu email válido.
Forneça o comentário.
Enviando, aguarde...