0% acharam este documento útil (0 voto)
22 visualizações372 páginas

Aplicativo para Gerenciamento de Energia

O documento apresenta um trabalho de conclusão de curso sobre o desenvolvimento de um aplicativo para gerenciamento de consumo de energia elétrica, visando conscientizar os usuários sobre a importância da redução de gastos energéticos. O projeto busca oferecer ferramentas que ajudem a monitorar e controlar o consumo, reduzindo custos e impactos ambientais. A proposta é que o uso do aplicativo possa resultar em uma diminuição de 10% na conta de energia dos usuários em três meses.
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato DOCX, PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
22 visualizações372 páginas

Aplicativo para Gerenciamento de Energia

O documento apresenta um trabalho de conclusão de curso sobre o desenvolvimento de um aplicativo para gerenciamento de consumo de energia elétrica, visando conscientizar os usuários sobre a importância da redução de gastos energéticos. O projeto busca oferecer ferramentas que ajudem a monitorar e controlar o consumo, reduzindo custos e impactos ambientais. A proposta é que o uso do aplicativo possa resultar em uma diminuição de 10% na conta de energia dos usuários em três meses.
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato DOCX, PDF, TXT ou leia on-line no Scribd

______________________________________________________________

222 - Etec de Cotia

ETEC COTIA
CURSO TÉCNICO EM DESENVOLVIMENTO DE SISTEMAS

ARTHUR PERES CREPALDI


KAROLAYNE LOPES DOS SANTOS
KAROLYNE LOPES DOS SANTOS
MANUELLA DOS REIS BAPTISTA
MARIA CLARA FERREIRA MENDES

DESENVOLVIMENTO DE APLICAÇÃO PARA GERENCIAMENTO


DE CONSUMO DE ENERGIA

COTIA
2024
ARTHUR PERES CREPALDI
KAROLAYNE LOPES DOS SANTOS
KAROLYNE LOPES DOS SANTOS
MANUELLA DOS REIS BAPTISTA
MARIA CLARA FERREIRA NUNES

DESENVOLVIMENTO DE APLICAÇÃO PARA GERENCIAMENTO


DE CONSUMO DE ENERGIA

Trabalho de Conclusão de Curso


apresentado à Etec Cotia, do Centro
Estadual de Educação Tecnológica Paula
Souza, como requisito para a obtenção do
diploma de Técnico de Nível Médio em
Desenvolvimento de Sistemas sob a
orientação do Professor Especialista
Samuel Henrique da Rocha

COTIA
2024
ARTHUR PERES CREPALDI
KAROLAYNE LOPES DOS SANTOS
KAROLYNE LOPES DOS SANTOS
MANUELLA DOS REIS BAPTISTA
MARIA CLARA FERREIRA NUNES

DESENVOLVIMENTO DE APLICAÇÃO PARA GERENCIAMENTO


DE CONSUMO DE ENERGIA

Aprovada em : ______ / _______ / _________

Conceito: ______________________________

Banca de Validação:

_________________________________ - Presidente da Banca


Professor...............................................................

Orientador
___________________________________
Professor ............................................................

____________________________________
Professor ............................................................

COTIA
2024
DEDICATÓRIA

Espaço para que o(s) autor(es) preste(m) homenagem a alguém.


AGRADECIMENTOS

O(s) autor(es) pode(m) redigir um texto agradecendo àqueles que


contribuíram na elaboração do trabalho.
“Há uma força motriz mais poderosa que o vapor, a
eletricidade e a energia atômica: a vontade.”

CENTRO PAULA SOUZA


RESUMO
ABSTRACT
LISTA DE ILUSTRAÇÕES

Gráficos
Figura 1 - Consumo de energia elétrica no Brasil.............................................8

Figura 2 - Composição da matriz energética brasileira 9

Figura 3 - Países com maiores custos 10

Figura 4 - Desperdício X produção de energia 11

Diagramas
Figura 5 - Diagrama de Ishikawa....................................................................13

Figura 6 - Metodologia 5w2h 13

Discussão dos resultados


Figura 7 - Discussão dos resultados 1............................................................22

Figura 8 - Discussão dos resultados 2 23

Figura 9 - Discussão dos resultados 3 23

Figura 10 - Discussão dos resultados 4 24

Figura 11 - Discussão dos resultados 5 24

Figura 12 - Discussão dos resultados 6 25

Figura 13 - Discussão dos resultados 7 25

Figura 14 - Discussão dos resultados 8 26


Figura 15 - Discussão dos resultados 9..........................................................26
Figura 16 - Discussão dos resultados 10........................................................27

Fluxogramas
Figura 17 - Fluxograma completo...................................................................32

Figura 18 - Fluxograma parte 1 33

Figura 19 - Fluxograma parte 2 34

Capturas de tela
Figura 20 - Tela de Splash............................................................................217

Figura 21 - Tela de Login 218

Figura 22 - Tela de cadastro 218

Figura 23 - Tela de termos 219

Figura 24 - Tela inicial 219

Figura 25 - Menu Lateral 219


Figura 26 - Tela de dados pessoais..............................................................220
Figura 27 - Tela de alteração de e-mail........................................................220
Figura 28 - Tela de alteração de senha........................................................221
Figura 29 - Tela de gastos............................................................................221
Figura 30 - Tela de dispositivo......................................................................222
Figura 31 - Tela de atualização de dispositivo..............................................222
Figura 32 - Tela de adição do dispositivo......................................................223
Figura 33 - Dispositivos pré-definidos...........................................................223

Diagramas de caso de uso


Figura 34 - Diagrama de caso de uso da tela de adição de dispositivo........224
Figura 35 - Diagrama de caso de uso da tela de alteração do endereço de e-
mail ........................................................................................................................ 224
Figura 36 - Diagrama de caso de uso da tela de alteração de senha...........225
Figura 37 - Diagrama de caso de uso da tela de atualização do dispositivo 225
Figura 38 - Diagrama de caso de uso da tela de cadastro............................226
Figura 39 - Diagrama de caso de uso da tela de dados pessoais ...............227
Figura 40 - Diagrama de caso de uso da tela de dispositivo.........................228
Figura 41 - Diagrama de caso de uso da tela de gastos...............................229
Figura 42 - Diagrama de caso de uso da tela de inicio.................................230
Figura 43 - Diagrama de caso de uso da tela de login..................................231
Figura 44 - Diagrama de caso de uso da tela de termos..............................231

Diagramas de classes UML


Figura 45 - Diagrama UML Adicionando_dispositivos.java...........................232
Figura 46 - Diagrama UML Alterando_email.java.........................................233
Figura 47 - Diagrama UML Alterando_senha.java........................................233
Figura 48 - Diagrama UML Atualizar_dispositivo.java...................................234
Figura 49 - Diagrama UML [Link].....................................................235
Figura 50 - Diagrama UML [Link].........................................................236
Figura 51 - Diagrama UML [Link]........................................................237
Figura 52 - Diagrama UML [Link]..................................................238
Figura 53 - Diagrama UML [Link]........................................................239
Figura 54 - Diagrama UML [Link]...........................................................240
Figura 55 - Diagrama UML [Link]..........................................................241
Figura 56 - Diagrama UML [Link]........................................................241
Figura 57 - Diagrama UML [Link].......................................................241

Modelagem Banco de Dados


Figura 58 - Modelo lógico do banco de dados..............................................242
Figura 59 - Modelo conceitual do banco de dados........................................243
LISTA DE TABELAS

Elaborada de acordo com a ordem apresentada no texto. Cada item deve ser
designado por seu nome específico, título e respectivo número da folha ou página
LISTAS DE ABREVIATUAS E SIGLAS

Lista em ordem alfabética das abreviaturas e siglas utilizadas no texto,


seguidas das palavras ou expressões correspondentes grafadas por extenso
LISTAS DE SIMBOLOS

Elaborada de acordo com a ordem apresentada no texto, seguidas do seu


significado.
SUMÁRIO
SUMÁRIO

1. INTRODUÇÃO..............................................................................................................
2. FUNDAMENTAÇÃO TEÓRICA....................................................................................
1.1.1 Tema geral.......................................................................................................................
2.1.1 Tema específico...............................................................................................................
3. METODOLOGIA...........................................................................................................
4. DISCUSSÃO DOS RESULTADOS...............................................................................
Detalhes dos Instrumentos.........................................................................................................
Análise dos Dados......................................................................................................................
5. DOCUMENTAÇÃO DO SOFTWARE...........................................................................
3.1.1 Regras de Negócio...........................................................................................................
4.1.1 Requisitos Funcionais......................................................................................................
5.1.1 Requisitos Não Funcionais...............................................................................................
6.1.1 Requisitos Minimos..........................................................................................................
7.1.1 Fluxograma.......................................................................................................................
8.1.1 Algoritmo e/ou scripts comentado....................................................................................
9.1.1 Capturas de Telas..........................................................................................................
10.1.1 Diagrama de Caso de Uso..........................................................................................
11.1.1 Diagrama UML............................................................................................................
12.1.1 Modelo Lógico do Banco de Dados............................................................................
13.1.1 Modelo Conceitual do Banco de Dados......................................................................
14.1.1 Modelo Físico do Banco de Dados.............................................................................
15.1.1 Manuais do Programa.................................................................................................
16.1.1 Ciclo de Vida do Programa.........................................................................................
6. CONSIDERAÇÕES FINAIS........................................................................................
REFERÊNCIAS........................................................................................................................
GLOSSÁRIO............................................................................................................................
APÊNDICE(S)..........................................................................................................................
ANEXO(S)................................................................................................................................
8

1. INTRODUÇÃO

A eletricidade é um bem fundamental para a sociedade e para a economia


sendo utilizada em praticamente todos os aspectos da vida diária, desde iluminação
interna, aquecimento, refrigeração, operação de equipamentos eletrônicos,
transporte, indústria e infraestrutura crítica, como hospitais. Além disso, ela
desempenha também um papel fundamental na melhoria da qualidade de vida das
pessoas, permitindo a refrigeração de vacinas, medicamentos e alimentos, utilização
de computadores e ventiladores e bombeamento de água potável. O Brasil é o
quarto maior produtor de energia elétrica da América Latina e seu fornecimento é
universal, atingindo mais de 99% da população. A matriz energética brasileira é
considerada uma das mais limpas do mundo, devido à grande parte de recursos
renováveis em sua composição, como energia eólica, biomassa e energia solar. O
consumo de energia elétrica no Brasil é muito elevado e em 2021 atingiu 571 TWh.
Os principais consumidores são a habitação urbana, seguida das empresas e
atividades e da habitação localizada em zonas rurais.

Figura 1: Consumo de energia elétrica no Brasil


9

Fonte: EIA
Atualmente, o Brasil enfrenta grandes desafios no setor energético, com
destaque no alto consumo e desperdício de energia. O consumo inconsciente de
energia é uma preocupação devido à crescente demanda por eletricidade e à
necessidade de proteger o meio ambiente. A energia elétrica é um dos insumos
mais caros da indústria e a alta demanda, devido ao desperdício, a torna ainda mais
cara. Em um levantamento da Associação Brasileira de Empresas de Conservação
de Energia (ABESCO), é indicado que entre 2015 e 2017 o Brasil sofreu perdas
energéticas de aproximadamente 61,7 bilhões de reais, valor que seria suficiente
para construir 240 hospitais.

Figura 2: Composição da Matriz Energética Brasileira

Fonte: GOV

Como visto no gráfico, as hidrelétricas representam 60% da matriz energética


brasileira e este não é um cenário totalmente positivo, pois, além de deixarem o país
10

vulnerável, também causam inúmeros impactos ambientais, embora atue como um


recurso renovável. A construção de uma hidrelétrica provoca o represamento de
grande quantidade de água, inunda muitas áreas, desloca populações nativas e
locais, afeta a flora e a fauna, altera o nível e a vazão natural do rio represado e
provoca as mudanças climáticas. Além disso, as usinas hidrelétricas são altamente
dependentes das condições climáticas. A seca de 2021 quase mergulhou o Brasil
em um colapso energético, pois o governo teve que ativar fontes não renováveis
para abastecer o país, aumentando assim as taxas de produção de energia. Itaipu,
maior fábrica do país, registrou faturamento abaixo da média de 82%, marca
histórica.
Dados da Agência Internacional de Energia (AIE) mostram que a demanda
por energia elétrica deverá crescer em média 2,5% ao ano no período de 2024 a
2026, contra 2,2% de 2018 a 2023. Em paralelo, informam estatísticas da ABRACE
(Associação Brasileira de Grandes Consumidores de Energia Industrial e
Consumidores Livres) que o custo da energia elétrica aumentou 47% entre 2017 e
2022, com o Brasil em segundo lugar na lista das tarifas mais altas do mundo. Isto
se deve principalmente ao consumo de energia.

Figura 3: Países com maiores custos (custo de 200kWh ajustado pela


renda per capta de cada país)
11

Fonte: ABRACE

Segundo o diretor de P&D e Inovação da Celesc (CENTRAIS ELÉTRICAS DE


SANTA CATARINA), o desperdício elétrico do país, estimado em 43 terawatts-hora
(TWh) por ano, equivale ao consumo de 20 milhões de residências. Esse
desperdício equivale à produção de energia elétrica da terceira maior usina do país
(Usina Belo Monte, Pará) apenas para cobrir esse valor perdido.

Figura 4: Desperdício X Produção de energia

Fonte:
FIESC & Consórcio
Norte Energia

Considerando o
cenário de desafios
enfrentados pelo
Sistema Interligado
Nacional (SIN), como
a dependência de
hidrelétricas e a
vulnerabilidade a
crises de
abastecimento, é
essencial adotar medidas que previnam crises e sobrecargas energéticas. É
importante que as pessoas entendam que o consumo elevado exige impostos mais
elevados, pode provocar sobrecargas na matriz energética brasileira e deixar o país
propício a uma crise. O desenvolvimento de um aplicativo que ajude o usuário a
monitorar o consumo de energia elétrica de forma sustentável e organizada
simplifica a administração e permite escolhas mais seguras, reduzindo a demanda
excessiva, os riscos de colapso do sistema em períodos críticos e contribuindo para
a preservação dos recursos naturais.
12

O objetivo desse projeto é desenvolver um aplicativo eficiente para controle


de energia, visando entregar aos usuários ferramentas que os ajudem a monitorar,
controlar e reduzir o consumo de eletricidade.

De forma a atingir o objetivo geral, serão realizados os seguintes objetivos


específicos: conscientizar as pessoas sobre a importância da redução dos seus
gastos de energia; ajudar na redução de gastos (tanto financeiro quanto elétrico);
alcançar um público-alvo grande; dar dicas sobre como reduzir o consumo excessivo
de energia; ajudar a reduzir os impactos ambientais que o uso sem controle de
energia causa ao meio-ambiente.

Acreditamos que o uso do aplicativo reduzirá em 10% a conta de energia dos


usuários em um período de três meses, impulsionadas pela inclusão de dicas diárias
de economia de energia que aumentarão a aprovação dos usuários ao uso do
aplicativo. Além disso, a funcionalidade de alerta para aparelhos que consomem
energia além do limite estabelecido pelos usuários reduzirá o tempo de uso desses
aparelhos. ajudando ainda mais para a diminuição dos gastos de energia.
13

Figura 5: Diagrama de Ishikawa

Fonte: do próprio autor.

Figura 6: Metodologia 5w2h

Fonte: do próprio autor.


14

2. FUNDAMENTAÇÃO TEÓRICA

A base teórica deste estudo visa estabelecer um fundamento consistente para


a criação de um aplicativo que calcula os gastos de energia elétrica dos usuários,
convertendo os em valores em reais. Os usuários podem inserir os dados dos seus
aparelhos eletrônicos e elétricos, como o tempo de uso, volts e watts. Com essas
informações, o app realiza os cálculos necessários para apresentar uma estimativa
precisa do consumo de energia e seu custo, ajudando não só o usuário a ter um
controle dos seus gastos, mas também o meio ambiente que é prejudicado com o
uso exagerado de energia elétrica.

Eficiência Energética: Análise dos princípios e práticas de eficiência


energética, destacando a importância de reduzir o consumo de energia e otimizar o
uso dos aparelhos elétricos; Medição de Consumo de Energia: Exploração dos
modelos e métodos utilizados para medir o consumo de energia em aparelhos
elétricos e eletrônicos, como as tecnologias que são usadas para essa medição;
Comportamento do Consumidor: Investigação dos fatores que influenciam o
comportamento dos consumidores em relação ao uso de energia, incluindo a
conscientização sobre o consumo e as práticas de economia de energia; Design de
Interfaces: Discussão sobre os princípios de design de interfaces e a importância de
uma experiência de usuário intuitiva e agradável do aplicativo.

Identificação das Principais Teorias – Eficiência energética

Eficiência significa fazer mais (ou, pelo menos, a mesma coisa) com menos,
mantendo o conforto e a qualidade. Quando se discute energia e eficiência
energética, trata-se de gerar a mesma quantidade de energia com menos recursos
naturais ou obter o mesmo serviço com menos energia. O objetivo central é utilizar a
energia elétrica de maneira eficaz, reduzindo desperdícios e otimizando o consumo.

Para promover a utilização eficaz da energia elétrica, foi instituído o Programa


Brasileiro de Etiquetagem (PBE), sob coordenação do Instituto Nacional de
Metrologia, Normalização e Qualidade Industrial (Inmetro). O propósito do PBE é
15

disponibilizar dados referentes à eficiência energética dos dispositivos, possibilitando


aos consumidores a escolha do equipamento mais eficiente no momento da compra.
Além disso, a etiqueta do Inmetro incentiva a produção de produtos
com maior eficiência energética, motivando os fabricantes a desenvolverem itens
cada vez mais eficientes.

Especificamente para a eletricidade, existe o Programa Nacional de


Conservação de Energia Elétrica (Procel), coordenado pelo Ministério de Minas e
Energia (MME) e executado pela Empresa Brasileira de Participações em Energia
Nuclear e Binacional (ENBPar) desde julho de 2023, após a transição da Eletrobras.
Criado em 30 de dezembro de 1985 pela Portaria Interministerial n° 1.877, a missão
do Procel é fomentar o uso eficiente da energia elétrica e combater o desperdício.

Desde então, as ações do Procel têm impulsionado a eficiência de produtos e


serviços, além de promover a conscientização e o conhecimento sobre o consumo
eficiente de energia.

O principal símbolo do Procel é o Selo Procel, que indica aos consumidores


quais produtos apresentam os melhores níveis de eficiência energética dentro de
suas categorias, como ventiladores de teto e geladeiras. Por exemplo, ao
escolher um eletrodoméstico com o Selo Procel, o consumidor sabe que esse
produto consome menos energia em comparação com outro equivalente sem o selo,
resultando em economia na conta de eletricidade e menores impactos ambientais.

Fabricantes de produtos como lâmpadas, TVs e aparelhos de ar-


condicionado, buscam continuamente melhorar a eficiência de seus produtos para
receberem o Selo Procel, beneficiando toda a sociedade. Enquanto a etiqueta do
Inmetro classifica os produtos em termos de eficiência, o Selo Procel destaca
aqueles que se sobressaem.

Além de buscar equipamentos mais eficientes, os cidadãos podem contribuir


para o meio ambiente utilizando a energia de forma consciente e evitando
desperdícios. A melhoria na eficiência energética e a adoção de práticas de uso
16

consciente de energia permitem reduzir a necessidade de recursos naturais na


produção de energia, minimizando os impactos ambientais negativos.

Medição de consumo de energia

Os modelos de medição de consumo de energia são cruciais para o


desenvolvimento do aplicativo. São utilizados diversos tipos de equipamentos para
medir a geração ou o consumo de energia elétrica. Os medidores de energia
registram o consumo ou a geração em kWh (quilowatt-hora). Os medidores podem
ser eletromecânicos ou eletrônicos.

Os medidores eletromecânicos são compostos por um disco metálico que gira


quando passa uma corrente elétrica pelas suas bobinas e funciona através da
indução eletromagnética, como um motor elétrico. A velocidade de rotação do disco
é diretamente proporcional à corrente elétrica que circula. Quanto maior a corrente,
mais rápido será a velocidade do disco e maior o consumo de energia. Quando há
consumo de energia, o disco movimenta um conjunto de engrenagens que registra a
energia consumida ou gerada.

Embora o aplicativo desenvolvido neste estudo não utilize equipamentos


físicos para medir a energia, ele se baseia em conceitos de eficiência energética
para fornecer aos usuários uma maneira prática e eficaz de monitorar e reduzir seu
consumo. O aplicativo permitirá que os usuários insiram dados sobre o uso de
energia elétrica de seus aparelhos e calculem os custos associados, promovendo
práticas mais sustentáveis e ajudando a economizar e reduzir impactos ambientais
de uma maneira muito mais fácil. A compreensão da teoria da eficiência energética é
crucial para justificar a relevância e o impacto potencial do aplicativo. Através de um
design bem fundamentado, o aplicativo visa promover o uso consciente da energia e
a redução do desperdício, alinhando-se com os princípios da eficiência energética.

Teoria do Comportamento do Consumidor


17

Compreender o comportamento do consumidor é importante para o sucesso


do aplicativo. Teorias como a Teoria do Comportamento Planejado (AJZEN, 1985),
explicam que o comportamento humano individual é uma função da intenção de
comportamento. Esta intenção, no entanto, depende de outros três quesitos: da
combinação das atitudes e a influência que as crenças comportamentais exercem
sobre elas, das normas subjetivas e da percepção individual sobre o comportamento
percebido, ou seja, essas três questões influenciam as intenções e ações dos
consumidores. Esta teoria é relevante para este estudo porque ajuda a entender
como os usuários podem ser incentivados a adotar práticas de consumo de energia
mais conscientes e eficientes através do uso do aplicativo, como controle
comportamental percebido, este aspecto trata da percepção que o usuário tem sobre
a facilidade ou dificuldade em adotar o comportamento desejado. O aplicativo pode
ajudar a aumentar o controle comportamental percebido oferecendo orientações
claras sobre como monitorar e gerenciar o consumo de energia, além de fornecer
suporte e facilitar a entrada de dados, podendo melhorar a percepção dos usuários
sobre sua capacidade de controlar e reduzir o consumo de energia.

Design de Interfaces

O design de interfaces de usuário (UI) e a experiência do usuário (UX) são


essenciais para garantir a praticidade e a adesão ao aplicativo. Donald Norman,
criador do Nielsen Norman Group junto com Jacob Nielsen, diz em seu livro The
Design of Everyday Things: “Design é realmente um ato de comunicação, o que
significa ter um profundo entendimento de quem é a pessoa com quem o designer
está se comunicando.” Esse entendimento é crucial para garantir que o aplicativo
seja fácil de usar e eficaz na comunicação das informações sobre o consumo de
energia aos usuários.
Norman enfatiza que a experiência do usuário não se restringe apenas ao
aplicativo, plataforma ou serviço. Ela é mais abrangente, envolvendo a conexão com
o usuário desde o primeiro contato com a plataforma. Portanto, é vital considerar
toda a jornada do usuário para proporcionar uma experiência completa e satisfatória.

Conexões Entre Teorias e Conceitos


18

A integração da eficiência energética e a teoria do comportamento do


consumidor é essencial para o desenvolvimento de um aplicativo eficaz. A Eficiência
Energética, ao destacar a importância de produtos e práticas que consomem menos
energia, fornece o contexto para a necessidade de um aplicativo que ajude a
monitorar e reduzir o consumo. Por outro lado, a Teoria do Comportamento
Planejado explica como a adoção de comportamentos mais eficientes pode ser
facilitada através de mudanças nas intenções e atitudes dos usuários.

Crítica das fontes

1. Relevância:
As fontes utilizadas, são altamente relevantes, pois fornecem uma base sólida
para compreender a eficiência energética e o comportamento do consumidor.

2. Credibilidade:
As fontes acadêmicas e estudos revisados foram selecionados para garantir a
credibilidade. Foram priorizados artigos e sites confiáveis para garantir a qualidade
da informação.

Identificação de Lacunas

Após pesquisas sobre monitoramento de energia e eficiência energética,


observou-se que a maioria dos estudos se concentra em métodos baseados em
hardware, como medidores de energia e sensores. Contudo, há uma lacuna
significativa na pesquisa sobre soluções baseadas em software que calculam o
consumo de energia utilizando dados fornecidos manualmente pelos usuários.

1.1.1 Tema geral

Este tópico em questão discute a crescente importância de implementar


práticas de economia de energia elétrica nos lares, examinando os motivos
19

econômicos e ambientais que justificam essa transformação. A proposta é investigar


de que maneira o uso responsável da energia pode trazer benefícios ao meio
ambiente, diminuir despesas para os consumidores e favorecer a sustentabilidade
em nível global. Por meio de alteração nos hábitos de consumo e o emprego de
tecnologias de monitoramento, a pesquisa visa destacar a relevância da economia
de energia no contexto atual.

2.1.1 Tema específico

Este tópico foca no desenvolvimento de uma solução tecnológica, na forma


de um aplicativo, que visa auxiliar os usuários a entenderem e controlarem o
consumo de energia elétrica em suas residências, detalhando o processo de criação
do aplicativo, incluindo os algoritmos usados para calcular o consumo com base em
dados como volts, watts e tempo de uso dos aparelhos. Além disso, a pesquisa
avaliará como o aplicativo pode servir como uma ferramenta educacional,
incentivando práticas de consumo consciente e ajudando a reduzir os custos na
conta de luz.
20

3. METODOLOGIA

Esta pesquisa foi conduzida utilizando um método que se baseia em dados


numéricos, sendo essa escolha justificada por sua eficácia em lidar com problemas
práticos de forma precisa e estruturada. A opção por dados numéricos se justifica
pela capacidade de facilitar o cálculo e o monitoramento do consumo de energia
elétrica nas residências, proporcionando uma análise detalhada e objetiva.

Para alcançar os objetivos da pesquisa, foram utilizadas diversas fontes


confiáveis. Entre essas fontes, destacam-se sites especializados em energia elétrica
e artigos acadêmicos relevantes, os quais foram acessados através do Google
Acadêmico.

Além disso, foram aplicados questionários a moradores de diferentes


localidades, o que permitiu coletar dados diretamente de um público diversificado.
Os questionários foram elaborados para capturar uma ampla gama de informações
sobre os hábitos de consumo de energia e as características das residências. Essa
abordagem garantiu que a pesquisa não só abrangesse diversas perspectivas, mas
também possibilitou uma análise mais rica e extensiva dos dados coletados. A
análise dos dados numéricos permitiu a identificação de padrões e tendências no
consumo de energia, facilitando a avaliação dos objetivos da pesquisa.

Materias utilizados

Questionários: Foram elaborados questionários para a coleta de dados, com


perguntas de múltipla escolha para obter uma visão abrangente sobre os hábitos de
consumo de energia elétrica.

Fontes de Pesquisa: A pesquisa foi baseada em fontes como artigos


acadêmicos e sites especializados. As fontes foram selecionadas por meio de uma
busca criteriosa no Google Acadêmico e sites confiáveis.
21

Equipamentos Empregados

Computadores e Softwares: Foram utilizados computadores para a


elaboração e análise dos questionários, e o software utilizado para a criação dele foi
o Microsoft Forms , que foi empregado para organizar e analisar as informações
coletadas. Esses softwares permitiram a realização de dados estatísticos e a
visualização de gráficos.

Definição da População Alvo

A população alvo da pesquisa compreendeu alguns dos moradores de Cotia,


com foco em residências que utilizam energia elétrica como principal fonte de
energia.

Método de Amostragem

Critérios de Seleção: Os critérios de seleção para os participantes incluíram


idade mínima de 16 anos. Esses critérios foram definidos para assegurar a
relevância dos dados coletados e a uniformidade dos grupos de análise.

Dados Coletados

Número de Participantes: Os dados coletados foram compostos por 120


pessoas, selecionados de acordo com os critérios estabelecidos.
Percentual em Relação à População: O percentual da amostra em relação à
população total da cidade foi calculado utilizando a fórmula:

Percentual da Amostra = (120/30.637) × 100 ≈ 0,39%


22

Embora o tamanho da amostra seja modesto em comparação com a


população total, os dados coletados fornecem uma perspectiva sobre consumo de
energia elétrica.

Procedimento de Coleta

Distribuição e Recrutamento: Os participantes foram recrutados pelo envio do


link do formulário via WhatsApp e contato direto com residentes.

Detalhes dos Instrumentos

O questionário foi elaborado com 10 perguntas, abordando principalmente os


padrões de consumo de energia dos participantes. As perguntas foram projetadas
como alternativas múltiplas, permitindo a coleta de dados quantitativos e qualitativos.

Análise dos Dados

Distribuição de Frequências: Foram criados gráficos para mostrar a


distribuição das respostas para cada pergunta do questionário, permitindo uma
visualização clara das tendências e padrões de resposta, e para ilustrar os dados e
facilitar a interpretação dos resultados.

Gráficos
Figura 7: gráfico 1
23

Descrição: O Gráfico 1 mostra o costume do usuário em desligar os


aparelhos eletrônicos quando não estão em uso. Fonte: do próprio autor.
24

Figura 8: gráfico 2

Descrição: O Gráfico 2 mostra qual aparelho eletrônico o usuário mais utiliza


em casa. Fonte: do próprio autor.

Figura 9: gráfico 3

Descrição: ?. Fonte: do próprio autor.


25

Figura 10: gráfico 4

Descrição: O Gráfico 4 mostra se o usuário sabe quantos watts esse


aparelho consome. Fonte: do próprio autor.

Figura 11: gráfico 5

Descrição: O Gráfico 5 mostra se o usuário sabe quanto esse aparelho


impacta na sua conta de energia. Fonte: do próprio autor.
26

Figura 12: gráfico 6

Descrição: O Gráfico 6 mostra se o usuário toma medidas para reduzir o


consumo de energia em casa. Fonte: do próprio autor.

Figura 13: gráfico 7

O Descrição: O Gráfico 7 mostra se o usuário verifica a potência antes de


comprá-los. Fonte: do próprio autor.
27

Figura 14: gráfico 8

Descrição: O Gráfico 8 mostra se o usuário estaria disposto a ajustar o uso


desses aparelhos se tivesse acesso a dados sobre o consumo. Fonte: do próprio
autor.

Figura 15: gráfico 9

Descrição: O Gráfico 9 mostra quais fatores influenciam na decisão para a


compra de um novo aparelho. Fonte: do próprio autor.
28

Figura 16: gráfico 10

Descrição: O Gráfico 10 mostra qual a principal motivação do usuário para


economizar energia. Fonte: do próprio autor.
29

4. DISCUSSÃO DOS RESULTADOS

Detalhes dos Instrumentos

O questionário foi elaborado com 10 perguntas, abordando principalmente os


padrões de consumo de energia dos participantes. As perguntas foram projetadas
como alternativas múltiplas, permitindo a coleta de dados quantitativos e qualitativos.

Análise dos Dados

Distribuição de Frequências: Foram criados gráficos para mostrar a


distribuição das respostas para cada pergunta do questionário, permitindo uma
visualização clara das tendências e padrões de resposta, e para ilustrar os dados e
facilitar a interpretação dos resultados.

Conexão entre Dados e Problema de Pesquisa

A questão principal desta pesquisa foi entender de que maneira o


desenvolvimento de um software para calcular o consumo de energia elétrica
poderia ajudar os usuários no monitoramento e na redução de suas contas de
energia. O questionário indicou que 82% dos participantes acreditam que, se
tivessem informações detalhadas e atualizadas sobre seu consumo de energia,
poderiam reduzir os gastos mensais com eletricidade. Os resultados obtidos
destacam a relevância do assunto abordado e mostram a necessidade de soluções
tecnológicas que auxiliem no controle do uso de energia. Essa falta de compreensão
é um fator fundamental que justifica a criação de um recurso, como o software
proposto, com o objetivo de fornecer aos usuários dados precisos e de fácil acesso
sobre seu consumo de energia.

Conexão entre Dados e Embasamento Teórico


30

A revisão da literatura propõe que a conscientização sobre o uso de energia é


um componente essencial para incentivar práticas mais sustentáveis. As
informações coletadas fortalecem essas conclusões, demonstrando que a falta de
informações iniciais sobre o consumo energético representa uma barreira
considerável à eficiência energética.
As pesquisas em artigos reforçam os resultados obtidos por meio do
questionário, apontando que a falta de conhecimento acerca do consumo de energia
é uma questão comum entre os consumidores. Estudo de fontes confiáveis indica
que a maior parte das pessoas costuma ignorar o consumo de dispositivos elétricos
em modo stand-by. Além disso, dados disponíveis em sites especializados indicam
que a utilização de aplicações para o acompanhamento do consumo energético
pode ter um impacto considerável na diminuição do consumo. As informações
apresentadas correspondem ao interesse manifestado pelos participantes em utilizar
um software que forneça estes dados, o que destaca a relevância da criação de uma
ferramenta como a proposta neste estudo.

Implicações Práticas e Teóricas

Os resultados deste estudo trazem implicações práticas relevantes. Em


primeiro lugar, demonstram que dispositivos de monitorização de energia, como o
software desenvolvido, podem ter um papel crucial na promoção da eficiência
energética nas residências. Em segundo lugar, os dados indicam que o software
deve concentrar-se em oferecer informações claras e acessíveis relacionadas ao
consumo de energia, auxiliando os utilizadores na identificação de práticas que
possam contribuir para a redução do consumo, de acordo com o seu perfil.
No âmbito prático, as nossas conclusões sublinham a relevância de instruir os
consumidores sobre os seus hábitos de consumo energético, ressaltando a
necessidade de explorar diversos métodos, que incentivem mudanças de
comportamento que favoreçam a eficiência energética.

Divisão dos resultados por tópicos


31

 Perfil dos usuários participantes

Este estudo envolveu 120 indivíduos. A maioria dos participantes vive em


residências comuns e constitui um grupo diverso em termos de idade e experiência
tecnológica. Apesar de não ser uma amostra representativa da população em geral,
essa variedade é importante para investigar como diferentes pessoas, com diversos
níveis de conhecimento sobre o consumo de energia e as tecnologias de
monitorização, percebem e utilizam essas ferramentas no seu cotidiano.

 Conhecimento e práticas atuais de consumo de energia

Os resultados mostraram que 59% dos participantes não têm conhecimento


sobre o consumo próprio dos seus aparelhos elétricos. No entanto, 82%
apresentaram interesse em obter mais informações sobre o uso de energia e formas
de diminuir as suas despesas. Apenas 71% dos entrevistados fazem uso de
estratégias como desligar os dispositivos da tomada quando não estão a ser
utilizados, o que sugere um grande potencial para a realização de práticas de
consumo mais eficientes.

 Interesse e percepção sobre o uso de tecnologia para monitoramento de


energia

Quando questionados acerca do interesse em empregar um software para


acompanhar o consumo de energia, 59% dos participantes manifestaram uma
reação positiva, destacando seu interesse por ferramentas que forneçam
informações detalhadas e em tempo real sobre o uso energético. Esses dados
revelam uma disposição considerável para adotar novas tecnologias com o objetivo
de melhorar a eficiência energética.
32

 Comparação com estudos precedentes sobre comportamento de


consumo de energia

Os resultados alcançados demonstram a tendência de diminuição da


conscientização acerca do consumo de energia entre os consumidores domésticos,
mas também mostra um maior interesse para a adoção de novas tecnologias de
monitoramento de energia. Isto pode sinalizar uma alteração nas atitudes, motivada
pela crescente disponibilidade de tecnologia nos últimos anos.

 Implicações para o desenvolvimento do software e sugestões para


pesquisas futuras

Os dados indicam uma necessidade considerável por ferramentas que


facilitem o acompanhamento do consumo de energia e promovam a instrução dos
utilizadores em práticas mais eficientes. Para a criação do software, é fundamental
dar prioridade a uma interface intuitiva e à adição de recursos educativos pode
melhorar a eficácia do software, como sugestões personalizadas. Investigações
futuras poderiam analisar os efeitos da utilização destas ferramentas em grupos
específicos, como idosos ou famílias de baixa renda, para compreender melhor as
dificuldades e oportunidades em diversos contextos socioeconômicos.
33

5. DOCUMENTAÇÃO DO SOFTWARE

3.1.1 Regras de Negócio

Minimo 3

4.1.1 Requisitos Funcionais

Minimo 5

5.1.1 Requisitos Não Funcionais

Minimo 10

6.1.1 Requisitos Minimos


Inserir

7.1.1 Fluxograma
Figura 17: fluxograma completo
34

Fonte: do próprio autor.

Figura 18: fluxograma parte 1


35

Fonte: do próprio autor.


36

Figura 19: fluxograma parte 2

Fonte: do próprio autor.

8.1.1 Algoritmo e/ou scripts comentado

Adicionando_dispositivos.java:

package [Link];

import [Link];
37

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];
38

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

public class Adicionando_dispositivos extends AppCompatActivity {

// Constantes para cálculo de custo

private static final double TARIFA = 0.636240; // Tarifa de custo por unidade

private static final int MAX_HORAS = 24; // Máximo de horas permitido

private static final int MAX_MINUTOS = 1440; // Máximo de minutos


permitido (24 horas)

// Referências aos componentes da interface

private EditText nomeEditText;

private EditText potenciaEditText;

private EditText tempoEditText;


39

private TextView custoEditText;

private Spinner tempoUsoSpinner;

private ImageButton nomeSpinner;

private TextView quantidadeTextView;

private EditText quantidadeEditText;

private TextView gastoKWhEditText;

private TextView custoDiarioEditText;

private TextView gastoDiarioKWhEditText;

// Referências aos serviços do Firebase

private FirebaseAuth auth;

private FirebaseFirestore firestore;

@Override

protected void onCreate(Bundle savedInstanceState) {

[Link](savedInstanceState);

setContentView([Link].activity_adicionando_dispositivos);

// Inicializa as instâncias do Firebase

auth = [Link]();

firestore = [Link]();

// Associa os componentes da interface com seus IDs no layout

nomeEditText = findViewById([Link]);
40

potenciaEditText = findViewById([Link]);

tempoEditText = findViewById([Link]);

custoEditText = findViewById([Link]);

tempoUsoSpinner = findViewById([Link]);

nomeSpinner = findViewById([Link]);

quantidadeEditText = findViewById([Link]);

gastoKWhEditText = findViewById([Link]);

custoDiarioEditText = findViewById([Link]);

gastoDiarioKWhEditText = findViewById([Link]);

// Configura o adapter para o Spinner de tempo de uso

ArrayAdapter<CharSequence> adapter =
[Link](this,

[Link].tempo_uso_opcoes, [Link].simple_spinner_item);

[Link]([Link].simple_spinner_dr
opdown_item);

[Link](adapter);

// Configura o listener para o Spinner de tempo de uso

[Link](new
[Link]() {

@Override

public void onItemSelected(AdapterView<?> parent, View view, int


position, long id) {

validateAndCalculateCost(); // Valida e calcula o custo quando uma


opção é selecionada
41

@Override

public void onNothingSelected(AdapterView<?> parent) {

// Nenhuma ação necessária quando nada é selecionado

});

// Configura o listener para o botão de menu suspenso (ImageButton)

[Link](this::showPopupMenu);

// Configura o listener para o botão de ajuda

ImageButton helpButton = findViewById([Link]);

[Link](v -> showHelpDialog());

// Adiciona TextWatcher aos campos EditText para validação e cálculo


automático

[Link](new DeviceInfoTextWatcher());

[Link](new
DeviceInfoTextWatcher());

[Link](new DeviceInfoTextWatcher());

[Link](new
DeviceInfoTextWatcher());

// Configura o listener para o botão de salvar


42

findViewById([Link]).setOnClickListener(v -> saveDevice());

// Configura o listener para o botão de voltar

ImageButton voltarButton = findViewById([Link]);

[Link](v -> finish()); // Fecha a activity quando o


botão de voltar é clicado

private void showPopupMenu(View v) {

// Cria uma instância do PopupMenu, associado ao botão (v) clicado

PopupMenu popupMenu = new PopupMenu(this, v);

// Referências aos componentes de UI

ImageButton imageButtonNome = findViewById([Link]);

ProgressBar progressBarNome = findViewById([Link]);

// Oculta o botão e exibe a barra de progresso enquanto os dados são


carregados

[Link]([Link]);

[Link]([Link]);

// Após um atraso de 100 milissegundos, oculta a barra de progresso e


exibe o botão novamente

new Handler().postDelayed(() -> {

[Link]([Link]);
43

[Link]([Link]);

}, 100);

// Obtém a coleção "dispositivos" do Firestore

[Link]("dispositivos").get().addOnCompleteListener(task -> {

if ([Link]()) {

// Se a tarefa for bem-sucedida, cria uma lista de dispositivos para o


menu

List<SpinnerItem> dispositivos = new ArrayList<>();

for (QueryDocumentSnapshot document : [Link]()) {

// Extrai os dados de cada documento

String nome = [Link]("Nome");

Double potencia = [Link]("Potência");

Object imagemObj = [Link]("Imagem");

String imagemUrl = null;

if (imagemObj != null) {

if (imagemObj instanceof String) {

imagemUrl = (String) imagemObj; // Se a imagem for uma URL,


atribui-a à variável

} else {

Log.w("Adicionando_dispositivos", "Campo 'Imagem' não é


uma String.");

}
44

// Adiciona o dispositivo à lista de itens do Spinner

[Link](new SpinnerItem(nome, potencia, imagemUrl));

// Limpa o menu atual e adiciona novos itens baseados na lista de


dispositivos

[Link]().clear();

for (int i = 0; i < [Link](); i++) {

[Link]().add(0, i, 0, [Link](i).getName());

// Configura o listener para os itens do menu

[Link](item -> {

[Link]([Link]);

[Link]([Link]);

// Verifica se o item selecionado é válido

if ([Link]() >= 0 && [Link]() < [Link]()) {

SpinnerItem selectedItem = [Link]([Link]());

[Link]([Link]());

[Link]([Link]([Link]
()));
45

loadImage([Link]()); // Carrega a imagem


associada ao dispositivo

return true;

} else {

// Exibe uma mensagem de erro se o item selecionado for


inválido

[Link](this, "Item selecionado inválido.",


Toast.LENGTH_SHORT).show();

return false;

});

// Configura o listener para quando o menu é fechado

[Link](menu -> {

[Link]([Link]);

[Link]([Link]);

});

// Exibe o menu

[Link]();

} else {

// Se ocorrer um erro ao carregar os dispositivos, exibe uma


mensagem de erro

[Link](this, "Erro ao carregar dispositivos.",


Toast.LENGTH_SHORT).show();
46

[Link]([Link]);

[Link]([Link]);

});

private void showHelpDialog() {

// Cria um [Link] para construir o diálogo de ajuda

[Link] builder = new [Link](this);

// Infla o layout do diálogo a partir do XML

LayoutInflater inflater = getLayoutInflater();

View dialogView = [Link]([Link].dialog_help, null);

// Define o layout do diálogo e o botão positivo (OK)

[Link](dialogView);

[Link]("OK", null);

// Cria e exibe o diálogo

AlertDialog dialog = [Link]();

[Link]();

private class DeviceInfoTextWatcher implements TextWatcher {


47

@Override

public void beforeTextChanged(CharSequence s, int start, int count, int


after) {

// Não faz nada antes do texto mudar

@Override

public void onTextChanged(CharSequence s, int start, int before, int count)


{

// Valida e calcula o custo quando o texto muda

validateAndCalculateCost();

@Override

public void afterTextChanged(Editable s) {

// Não faz nada após o texto mudar

private void validateAndCalculateCost() {

// Obtém os valores dos campos de entrada

String potenciaString = [Link]().toString();

String tempoString = [Link]().toString();

String quantidadeString = [Link]().toString();


48

// Verifica se algum campo está vazio e define valores padrão se


necessário

if ([Link]() || [Link]() ||
[Link]()) {

[Link]("R$ 00,00");

[Link]("0 KWh");

[Link]("R$ 00,00");

[Link]("0 KWh");

return;

double potencia;

double tempo;

int quantidade;

// Tenta converter as entradas para tipos numéricos e trata exceções se


necessário

try {

potencia = [Link](potenciaString);

} catch (NumberFormatException e) {

[Link](this, "Potência inválida.",


Toast.LENGTH_SHORT).show();

return;

try {
49

tempo = [Link](tempoString);

} catch (NumberFormatException e) {

[Link](this, "Tempo inválido.",


Toast.LENGTH_SHORT).show();

return;

try {

quantidade = [Link](quantidadeString);

} catch (NumberFormatException e) {

[Link](this, "Quantidade inválida.",


Toast.LENGTH_SHORT).show();

return;

// Obtém a unidade de tempo selecionada no Spinner

String unidadeTempo = [Link]().toString();

if ([Link]("minutos/dia")) {

// Valida o tempo se for em minutos e converte para horas

if (tempo > MAX_MINUTOS) {

[Link](this, "O máximo permitido é 1440 minutos.",


Toast.LENGTH_SHORT).show();

return;

tempo = tempo / 60.0;


50

} else if ([Link]("horas/dia")) {

// Valida o tempo se for em horas

if (tempo > MAX_HORAS) {

[Link](this, "O máximo permitido é 24 horas.",


Toast.LENGTH_SHORT).show();

return;

} else {

// Exibe mensagem de erro se a unidade de tempo for inválida

[Link](this, "Unidade de tempo inválida.",


Toast.LENGTH_SHORT).show();

return;

// Calcula o consumo e o custo com base nos valores fornecidos

double consumoDiario = (potencia / 1000.0) * tempo;

double custoDiario = consumoDiario * TARIFA * quantidade;

double custoMensal = custoDiario * 30;

double gastoMensalKWh = consumoDiario * 30;

double gastoDiarioKWh = consumoDiario;

// Arredonda os valores para inteiros

int gastoMensalKWhInt = (int) [Link](gastoMensalKWh);

int gastoDiarioKWhInt = (int) [Link](gastoDiarioKWh);


51

// Atualiza os campos de texto com os resultados calculados

[Link]("R$ " + [Link]("%.2f", custoMensal));

[Link](gastoMensalKWhInt + " KWh");

[Link]("R$ " + [Link]("%.2f", custoDiario));

[Link](gastoDiarioKWhInt + " KWh");

private boolean isSaving = false; // Variável para verificar se um salvamento


está em andamento

private void saveDevice() {

// Verifica se um salvamento está em andamento

if (isSaving) {

[Link](this, "Salvamento em andamento, por favor aguarde...",


Toast.LENGTH_SHORT).show();

return;

// Define a variável isSaving como verdadeira para indicar que o


salvamento está em andamento

isSaving = true;

// Desativa o botão de salvar enquanto o processo está em andamento

TextView saveTextView = findViewById([Link]);

[Link](false);
52

// Obtém os valores dos campos de entrada

String nome = [Link]().toString();

String potenciaString = [Link]().toString();

String tempoString = [Link]().toString();

String quantidadeString = [Link]().toString();

// Obtém a URL da imagem associada ao dispositivo

ImageView imageView = findViewById([Link]);

String imagemUrl = null;

Object tag = [Link]();

if (tag != null) {

imagemUrl = [Link]();

// Verifica se algum campo está vazio e exibe uma mensagem de erro se


necessário

if ([Link]() || [Link]() || [Link]() ||


[Link]()) {

[Link](this, "Preencha todos os campos.",


Toast.LENGTH_SHORT).show();

isSaving = false;

[Link](true);

return;

}
53

double potencia;

double tempo;

int quantidade;

// Tenta converter os valores de potência, tempo e quantidade para os tipos


apropriados

try {

potencia = [Link](potenciaString);

} catch (NumberFormatException e) {

[Link](this, "Potência inválida.",


Toast.LENGTH_SHORT).show();

isSaving = false;

[Link](true);

return;

try {

tempo = [Link](tempoString);

} catch (NumberFormatException e) {

[Link](this, "Tempo inválido.",


Toast.LENGTH_SHORT).show();

isSaving = false;

[Link](true);

return;
54

try {

quantidade = [Link](quantidadeString);

} catch (NumberFormatException e) {

[Link](this, "Quantidade inválida.",


Toast.LENGTH_SHORT).show();

isSaving = false;

[Link](true);

return;

// Obtém a unidade de tempo selecionada no Spinner e valida

String unidadeTempo = [Link]().toString();

if ([Link]("horas/dia")) {

if (tempo > MAX_HORAS) {

[Link](this, "O máximo permitido é 24 horas.",


Toast.LENGTH_SHORT).show();

isSaving = false;

[Link](true);

return;

} else if ([Link]("minutos/dia")) {

if (tempo > MAX_MINUTOS) {


55

[Link](this, "O máximo permitido é 1440 minutos.",


Toast.LENGTH_SHORT).show();

isSaving = false;

[Link](true);

return;

} else {

[Link](this, "Unidade de tempo inválida.",


Toast.LENGTH_SHORT).show();

isSaving = false;

[Link](true);

return;

// Converte o tempo para horas se necessário

double tempoEmHoras = [Link]("minutos/dia") ? tempo /


60.0 : tempo;

// Calcula o consumo e custo diário e mensal

double gastoDiarioKWh = (potencia / 1000.0) * tempoEmHoras;

double gastoMensalKWh = gastoDiarioKWh * 30 * quantidade;

double custoDiario = (potencia / 1000.0) * tempoEmHoras * TARIFA *


quantidade;

double custoMensal = custoDiario * 30;

// Obtém o mês e ano atuais para identificar o documento no Firestore


56

Calendar calendar = [Link]();

SimpleDateFormat sdf = new SimpleDateFormat("MM-yyyy",


[Link]());

String mesAno = [Link]([Link]());

// Arredonda os valores para inteiros

int gastoMensalKWhInt = (int) [Link](gastoMensalKWh);

int gastoDiarioKWhInt = (int) [Link](gastoDiarioKWh);

// Cria um mapa para armazenar os dados do dispositivo

Map<String, Object> deviceData = new HashMap<>();

[Link]("Nome", nome);

[Link]("Potência", potencia);

[Link]("Tempo", tempo);

[Link]("Quantidade", quantidade);

[Link]("CustoDiario", custoDiario);

[Link]("GastoDiarioKwh", gastoDiarioKWhInt);

[Link]("CustoMensal", custoMensal);

[Link]("GastoMensalKwh", gastoMensalKWhInt);

[Link]("ImagemUrl", imagemUrl);

[Link]("UnidadeTempo", unidadeTempo);

// Obtém o ID do usuário atual e cria uma referência para o documento no


Firestore

String userId = [Link]().getUid();


57

DocumentReference dispositivoRef =
[Link]("usuarios").document(userId)

.collection("dispositivos").document(mesAno)

.collection("dispositivos").document();

// Salva os dados no Firestore e adiciona ouvintes para sucesso e falha

[Link](deviceData).addOnSuccessListener(aVoid -> {

updateMonthlyDeviceData(userId, mesAno, tempo, quantidade);

updateMonthlyTotal(userId, mesAno, custoMensal);

[Link](this, "Dispositivo salvo com sucesso!",


Toast.LENGTH_SHORT).show();

finish(); // Fecha a atividade após o sucesso

}).addOnFailureListener(e -> {

[Link](this, "Erro ao salvar dispositivo. Tente novamente.",


Toast.LENGTH_SHORT).show();

}).addOnCompleteListener(task -> {

// Define isSaving como falso e reativa o botão de salvar após o término

isSaving = false;

[Link](true);

});

private void updateMonthlyDeviceData(String userId, String mesAno, double


tempo, int quantidade) {

// Referência para o documento que contém os dados mensais do usuário

DocumentReference monthRef =
[Link]("usuarios").document(userId)
58

.collection("dados_mensais").document(mesAno);

// Obtém os dados do documento do Firestore

[Link]().addOnCompleteListener(task -> {

if ([Link]()) {

double totalTempo = 0;

int totalQuantidade = 0;

// Se o documento existe, obtém os dados existentes

if ([Link]().exists()) {

Map<String, Object> data = [Link]().getData();

if (data != null) {

if ([Link]("Tempo")) {

totalTempo = ((Number) [Link]("Tempo")).doubleValue();

if ([Link]("Quantidade")) {

totalQuantidade = ((Number)
[Link]("Quantidade")).intValue();

// Atualiza os valores totais com os novos dados

totalTempo += tempo;

totalQuantidade += quantidade;
59

// Cria um mapa com os dados atualizados

Map<String, Object> monthlyData = new HashMap<>();

[Link]("Tempo", totalTempo);

[Link]("Quantidade", totalQuantidade);

// Define ou atualiza o documento com os dados mensais

[Link](monthlyData,
[Link]()).addOnCompleteListener(task1 -> {

if ([Link]()) {

[Link](Adicionando_dispositivos.this, "Dados mensais


atualizados com sucesso.", Toast.LENGTH_SHORT).show();

} else {

[Link](Adicionando_dispositivos.this, "Erro ao atualizar


dados mensais.", Toast.LENGTH_SHORT).show();

});

} else {

[Link](Adicionando_dispositivos.this, "Erro ao obter dados


mensais.", Toast.LENGTH_SHORT).show();

});

private void updateMonthlyTotal(String userId, String mesAno, double


custoMensal) {

// Referência para o documento que contém o total de gastos do usuário


60

DocumentReference totalRef =
[Link]("usuarios").document(userId)

.collection("gastos").document(mesAno);

// Obtém os dados do documento do Firestore

[Link]().addOnCompleteListener(task -> {

if ([Link]()) {

double total = 0;

// Se o documento existe, obtém o valor total existente

if ([Link]().exists()) {

Map<String, Object> data = [Link]().getData();

if (data != null && [Link]("Total")) {

total = ((Number) [Link]("Total")).doubleValue();

// Atualiza o valor total com o novo custo mensal

total += custoMensal;

// Cria um mapa com o valor total atualizado

Map<String, Object> totalData = new HashMap<>();

[Link]("Total", total);

// Define ou atualiza o documento com o total de gastos


61

[Link](totalData,
[Link]()).addOnCompleteListener(totalTask -> {

if ([Link]()) {

[Link](Adicionando_dispositivos.this, "Total atualizado


com sucesso.", Toast.LENGTH_SHORT).show();

} else {

[Link](Adicionando_dispositivos.this, "Erro ao atualizar


total.", Toast.LENGTH_SHORT).show();

});

} else {

[Link](Adicionando_dispositivos.this, "Erro ao obter total


mensal.", Toast.LENGTH_SHORT).show();

});

// Método para carregar uma imagem de uma URL e exibi-la em um


ImageView

private void loadImage(String imageUrl) {

// Obtém a referência do ImageView onde a imagem será carregada

ImageView imageView = findViewById([Link]);

// Log da URL da imagem para fins de depuração

Log.d("Adicionando_dispositivos", "URL da imagem: " + imageUrl);


62

try {

// Usa a biblioteca Glide para carregar a imagem

[Link](this)

.load(imageUrl) // Define a URL da imagem

.placeholder([Link]) // Imagem exibida enquanto a


imagem real está carregando

.error([Link]) // Imagem exibida se ocorrer um erro no


carregamento

.into(imageView); // Define o ImageView como destino da imagem


carregada

// Define a URL da imagem como a tag do ImageView para referência


futura

[Link](imageUrl);

} catch (Exception e) {

// Em caso de erro no carregamento da imagem, imprime o stack trace e


exibe um Toast

[Link]();

Log.e("Adicionando_dispositivos", "Erro ao carregar a imagem", e);

[Link](this, "Erro ao carregar a imagem.",


Toast.LENGTH_SHORT).show();

// Método para mostrar uma sobreposição de carregamento


63

private void showLoadingOverlay() {

Log.d("LoadingOverlay", "Mostrando sobreposição de carregamento");

// Obtém a referência da sobreposição de carregamento

RelativeLayout loadingOverlay = findViewById([Link]);

// Define a visibilidade da sobreposição para visível

[Link]([Link]);

// Método para esconder a sobreposição de carregamento

private void hideLoadingOverlay() {

Log.d("LoadingOverlay", "Escondendo sobreposição de carregamento");

// Obtém a referência da sobreposição de carregamento

RelativeLayout loadingOverlay = findViewById([Link]);

// Define a visibilidade da sobreposição para invisível

[Link]([Link]);

// Método para testar a sobreposição de carregamento com uma simulação de


progresso

private void testProgressBar() {

// Mostra a sobreposição de carregamento

RelativeLayout loadingOverlay = findViewById([Link]);

[Link]([Link]);

// Usa um Handler para atrasar a execução do código


64

new Handler().postDelayed(() -> {

// Esconde a sobreposição de carregamento após 3 segundos

[Link]([Link]);

}, 3000);

Alterando_email.java:

package [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];
65

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

public class Alterando_email extends AppCompatActivity {

private EditText editTextEmail;

private EditText editTextPassword;

private Button buttonConfirmar;

private ProgressBar progressBar;

private TextView textViewEmailAtual;

private TextView textViewVerificar;

private RelativeLayout loadingOverlay;

private FirebaseAuth mAuth;

private FirebaseFirestore firestore;

private boolean isPasswordVerified = false;

@Override

protected void onCreate(Bundle savedInstanceState) {

[Link](savedInstanceState);

[Link](this); // Habilita o modo de exibição EdgeToEdge

setContentView([Link].activity_alteracao_email); // Define o layout da


atividade
66

// Inicializa instâncias do FirebaseAuth e FirebaseFirestore

mAuth = [Link]();

firestore = [Link]();

// Ajusta o padding da visualização principal para evitar sobreposição


com as barras do sistema

[Link](findViewById([Link]),
(v, insets) -> {

Insets systemBars =
[Link]([Link]());

[Link]([Link], [Link], [Link],


[Link]);

return insets;

});

// Inicializa as referências dos componentes da interface

editTextEmail = findViewById([Link]);

editTextPassword = findViewById([Link].editTextTextPassword2);

buttonConfirmar = findViewById([Link].button3);

progressBar = findViewById([Link]);

textViewEmailAtual = findViewById([Link].textView6);

textViewVerificar = findViewById([Link].textView5);

loadingOverlay = findViewById([Link]);

// Configura o texto com o e-mail atual do usuário

configurarEmailAtual();
67

// Define o listener para o clique no TextView de verificar senha

[Link](view -> verificarSenha());

// Define o listener para o clique no botão de confirmar alteração de e-


mail

[Link](view -> alterarEmail());

// Define o listener para o clique no botão de voltar

findViewById([Link]).setOnClickListener(v -> finish());

// Configura o texto com o e-mail atual do usuário

private void configurarEmailAtual() {

FirebaseUser user = [Link](); // Obtém o usuário atual


autenticado

if (user != null) {

String emailAtual = [Link](); // Obtém o e-mail atual do usuário

[Link]("Seu e-mail atual é " + emailAtual + ". Qual


será o novo endereço?");

} else {

[Link]("Não foi possível obter o e-mail atual."); //


Mensagem de erro se o usuário não estiver autenticado

// Verifica a senha do usuário


68

private void verificarSenha() {

String senha = [Link]().toString().trim(); // Obtém a


senha inserida pelo usuário

// Verifica se a senha foi inserida

if ([Link](senha)) {

[Link](this, "Por favor, insira sua senha.",


Toast.LENGTH_SHORT).show();

return;

[Link]([Link]); // Mostra a
sobreposição de carregamento

FirebaseUser user = [Link](); // Obtém o usuário atual


autenticado

if (user != null) {

// Cria um objeto de credenciais para reautenticação

AuthCredential credential =
[Link]([Link](), senha);

// Reautentica o usuário com as credenciais fornecidas

[Link](credential).addOnCompleteListener(this, task -> {

[Link]([Link]); // Oculta a
sobreposição de carregamento
69

if ([Link]()) {

isPasswordVerified = true; // Marca a senha como verificada

[Link](Alterando_email.this, "Senha confirmada. Você


pode alterar seu e-mail agora.", Toast.LENGTH_SHORT).show();

[Link](true); // Habilita o campo de e-mail para


edição

} else {

[Link](Alterando_email.this, "Senha incorreta. Tente


novamente.", Toast.LENGTH_SHORT).show();

}).addOnFailureListener(e -> {

[Link]([Link]); // Oculta a
sobreposição de carregamento

[Link](1.0f); // Restaura a visibilidade do


TextView de verificar

[Link](Alterando_email.this, "Erro ao reautenticar: " +


[Link](), Toast.LENGTH_SHORT).show();

});

} else {

[Link]([Link]); // Oculta a
sobreposição de carregamento

[Link](1.0f); // Restaura a visibilidade do TextView


de verificar
70

[Link](this, "Não é possível verificar a senha. Usuário não


autenticado.", Toast.LENGTH_SHORT).show();

// Altera o e-mail do usuário

private void alterarEmail() {

FirebaseUser user = [Link](); // Obtém o usuário atual


autenticado

if (user != null && isPasswordVerified) { // Verifica se o usuário está


autenticado e a senha foi verificada

String novoEmail = [Link]().toString().trim(); // Obtém o


novo e-mail inserido pelo usuário

// Verifica se o novo e-mail não está vazio

if (![Link](novoEmail)) {

// Atualiza o e-mail do usuário

[Link](novoEmail).addOnCompleteListener(task -> {

if ([Link]()) {

// Envia um e-mail de verificação para o novo e-mail

[Link]().addOnCompleteListener(verificati
onTask -> {

if ([Link]()) {

atualizarEmailNoFirestore([Link](), novoEmail); //
Atualiza o e-mail no Firestore
71

[Link](this, "E-mail alterado e verificação


enviada para o novo e-mail.", Toast.LENGTH_SHORT).show();

} else {

[Link](this, "Falha ao enviar e-mail de


verificação.", Toast.LENGTH_SHORT).show();

Log.e("Alterando_email", "Erro ao enviar e-mail de


verificação: ", [Link]());

});

} else {

[Link](this, "Falha ao alterar o e-mail. Tente


novamente.", Toast.LENGTH_SHORT).show();

Log.e("Alterando_email", "Erro ao atualizar e-mail: ",


[Link]());

}).addOnFailureListener(e -> {

[Link](this, "Erro ao alterar o e-mail: " +


[Link](), Toast.LENGTH_SHORT).show();

Log.e("Alterando_email", "Erro ao atualizar e-mail: ", e);

});

} else {

[Link](this, "Por favor, insira um novo e-mail válido.",


Toast.LENGTH_SHORT).show();

} else {

[Link](this, "Usuário não autenticado ou senha não


verificada.", Toast.LENGTH_SHORT).show();
72

// Atualiza o e-mail do usuário no Firestore

private void atualizarEmailNoFirestore(String userId, String novoEmail) {

[Link]("users").document(userId).update("email", novoEmail)

.addOnCompleteListener(task -> {

if ([Link]()) {

Log.d("Alterando_email", "E-mail atualizado no Firestore com


sucesso!");

} else {

Log.e("Alterando_email", "Erro ao atualizar e-mail no Firestore:


", [Link]());

}).addOnFailureListener(e -> {

Log.e("Alterando_email", "Erro ao atualizar e-mail no Firestore: ",


e);

});

Alterando_senha,java:

package [Link];

import [Link];
73

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

public class Alterando_senha extends AppCompatActivity {

private FirebaseAuth mAuth;

private EditText editTextSenhaAtual;

private EditText editTextNovaSenha;

private EditText editTextConfirmarNovaSenha;

@Override

protected void onCreate(Bundle savedInstanceState) {


74

[Link](savedInstanceState);

[Link](this); // Configura o layout para se ajustar às barras


do sistema

setContentView([Link].activity_alteracao_senha); // Define o layout da


activity

mAuth = [Link](); // Inicializa a instância do


FirebaseAuth

// Ajusta o padding da view principal para evitar sobreposição com as


barras do sistema

[Link](findViewById([Link]),
(v, insets) -> {

Insets systemBars =
[Link]([Link]());

[Link]([Link], [Link], [Link],


[Link]);

return insets;

});

// Associa variáveis aos elementos da interface

editTextSenhaAtual = findViewById([Link]);

editTextNovaSenha = findViewById([Link]);

editTextConfirmarNovaSenha =
findViewById([Link]);

// Configura o listener para o botão de alterar senha


75

findViewById([Link].button3).setOnClickListener(view -> alterarSenha());

// Configura o listener para o botão de voltar

ImageButton backButton = findViewById([Link]);

[Link](v -> finish());

private void alterarSenha() {

// Obtém os valores inseridos nos campos

String senhaAtual = [Link]().toString().trim();

String novaSenha = [Link]().toString().trim();

String confirmarNovaSenha =
[Link]().toString().trim();

// Verifica se todos os campos foram preenchidos

if ([Link](senhaAtual) || [Link](novaSenha) ||
[Link](confirmarNovaSenha)) {

[Link](this, "Preencha todos os campos.",


Toast.LENGTH_SHORT).show();

return;

// Verifica se a nova senha e a confirmação são iguais

if (![Link](confirmarNovaSenha)) {

[Link](this, "As senhas novas não coincidem.",


Toast.LENGTH_SHORT).show();
76

return;

// Obtém o usuário atual

FirebaseUser user = [Link]();

if (user != null) {

// Reautentica o usuário com a senha atual

[Link]([Link]([Link](),
senhaAtual))

.addOnSuccessListener(aVoid -> {

// Atualiza a senha do usuário

[Link](novaSenha)

.addOnSuccessListener(aVoid1 -> {

// Exibe uma mensagem de sucesso e finaliza a activity

[Link](Alterando_senha.this, "Senha alterada


com sucesso.", Toast.LENGTH_SHORT).show();

finish();

})

.addOnFailureListener(e -> {

// Exibe uma mensagem de erro se a atualização falhar

[Link](Alterando_senha.this, "Erro ao alterar


a senha: " + [Link](), Toast.LENGTH_SHORT).show();

});

})
77

.addOnFailureListener(e ->
[Link](Alterando_senha.this, "Senha atual incorreta: " + [Link](),
Toast.LENGTH_SHORT).show());

.getMessage(), Toast.LENGTH_SHORT).show());

Atualizar_dispositivo.java:

package [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];
78

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

public class Atualizar_dispositivo extends AppCompatActivity {


79

private static final double TARIFA = 0.636240;

private static final int MAX_HORAS = 24;

private static final int MAX_MINUTOS = 1440;

private EditText nomeEditText;

private EditText potenciaEditText;

private EditText tempoEditText;

private EditText custoMensalEditText;

private Spinner tempoUsoSpinner;

private String dispositivoId;

private String userId;

private TextView quantidadeTextView;

private EditText quantidadeEditText;

private Calendar calendar;

private EditText custoDiarioEditText;

private EditText gastoDiarioEditText;

private EditText gastoMensalEditText;

private FirebaseAuth auth;

private FirebaseFirestore firestore;

@Override

protected void onCreate(Bundle savedInstanceState) {

[Link](savedInstanceState);

setContentView([Link].activity_atualizando_dispositivos);
80

// Inicializa as instâncias do FirebaseAuth e FirebaseFirestore

auth = [Link]();

firestore = [Link]();

// Obtém o usuário atual do Firebase Authentication

FirebaseUser currentUser = [Link]();

if (currentUser == null) {

// Se não houver um usuário autenticado, exibe uma mensagem e fecha


a activity

[Link](this, "Você precisa estar logado para acessar esta


página.", Toast.LENGTH_SHORT).show();

finish();

return;

userId = [Link](); // Armazena o ID do usuário

// Associa as variáveis aos elementos da interface no layout

nomeEditText = findViewById([Link]);

potenciaEditText = findViewById([Link]);

tempoEditText = findViewById([Link]);

custoDiarioEditText = findViewById([Link]);

gastoDiarioEditText = findViewById([Link]);

custoMensalEditText = findViewById([Link]);

gastoMensalEditText = findViewById([Link]);
81

tempoUsoSpinner = findViewById([Link]);

quantidadeEditText = findViewById([Link]);

// Verifica se algum dos EditTexts não foi encontrado no layout

if (nomeEditText == null || potenciaEditText == null || tempoEditText == null


||

custoDiarioEditText == null || gastoDiarioEditText == null ||


custoMensalEditText == null ||

gastoMensalEditText == null || tempoUsoSpinner == null ||


quantidadeEditText == null) {

Log.e("Atualizar_dispositivo", "Um ou mais EditTexts não foram


encontrados no layout.");

return;

// Inicializa os EditTexts com valores padrão

try {

[Link]([Link]([Link](), "%.2f",
0.0));

[Link]([Link]([Link](), "%.2f",
0.0));

[Link]([Link]([Link](), "%.2f",
0.0));

[Link]([Link]([Link](), "%.2f",
0.0));

} catch (Exception e) {
82

Log.e("Atualizar_dispositivo", "Erro ao definir texto nos EditTexts: " +


[Link]());

// Obtém os dados passados para a activity através do Intent

Intent intent = getIntent();

dispositivoId = [Link]("ID");

String nome = [Link]("NOME");

String potencia = [Link]("POTENCIA");

String tempo = [Link]("TEMPO");

double custoDiario = [Link]("CUSTO_DIARIO", 0.0);

double custoDiarioKWh = [Link]("CUSTO_DIARIO_KWh",


0.0);

double custoMensal = [Link]("CUSTO_MENSAL", 0.0);

double custoMensalKWh =
[Link]("CUSTO_MENSAL_KWh", 0.0);

String imagemUrl = [Link]("IMAGEM");

String unidadeTempo = [Link]("UNIDADE_TEMPO");

String quantidade = [Link]("QUANTIDADE");

// Loga as informações recebidas para depuração

Log.d("Atualizar_dispositivo", "ID: " + dispositivoId);

Log.d("Atualizar_dispositivo", "Nome: " + nome);

Log.d("Atualizar_dispositivo", "Potência: " + potencia);

Log.d("Atualizar_dispositivo", "Tempo: " + tempo);


83

Log.d("Atualizar_dispositivo", "Custo Diário: " + custoDiario);

Log.d("Atualizar_dispositivo", "Custo Diário KWh: " + custoDiarioKWh);

Log.d("Atualizar_dispositivo", "Custo Mensal: " + custoMensal);

Log.d("Atualizar_dispositivo", "Custo Mensal KWh: " + custoMensalKWh);

Log.d("Atualizar_dispositivo", "Imagem URL: " + imagemUrl);

Log.d("Atualizar_dispositivo", "Unidade Tempo: " + unidadeTempo);

Log.d("Atualizar_dispositivo", "Quantidade: " + quantidade);

// Preenche os campos com os dados recebidos, se disponíveis

[Link](nome != null ? nome : "");

[Link](potencia != null ? potencia : "");

[Link](tempo != null ? tempo : "");

int quantidadeInt = (quantidade != null) ? (int)


[Link]([Link](quantidade)) : 1;

// Formata e define os valores dos campos de custo e gasto

NumberFormat currencyFormat = [Link](new


Locale("pt", "BR"));

[Link](2);

[Link](2);

String custoDiarioFormatado = [Link](custoDiario);

[Link](custoDiarioFormatado);

String custoMensalFormatado = [Link](custoMensal);


84

[Link](custoMensalFormatado);

DecimalFormat decimalFormatSemCasas = new DecimalFormat("#");

String gastoDiarioKWhFormatado =
[Link](custoDiarioKWh) + " KWh";

String gastoKWhFormatado =
[Link](custoMensalKWh) + " KWh";

[Link]([Link]([Link](), "%d",
quantidadeInt));

[Link](gastoDiarioKWhFormatado);

[Link](gastoKWhFormatado);

// Configura o Spinner com as opções de tempo de uso

ArrayAdapter<CharSequence> tempoAdapter =
[Link](this,

[Link].tempo_uso_opcoes, [Link].simple_spinner_item);

[Link]([Link].simple_spinner
_dropdown_item);

[Link](tempoAdapter);

// Define a posição do Spinner com base na unidade de tempo recebida

if (unidadeTempo != null) {

int spinnerPosition = [Link](unidadeTempo);

[Link](spinnerPosition);

}
85

// Adiciona um listener ao Spinner para validar e calcular o custo quando


um item é selecionado

[Link](new
[Link]() {

@Override

public void onItemSelected(AdapterView<?> parent, View view, int


position, long id) {

validateAndCalculateCost();

@Override

public void onNothingSelected(AdapterView<?> parent) {

});

// Adiciona listeners para atualizar os cálculos quando os campos são


modificados

[Link](new DeviceInfoTextWatcher());

[Link](new DeviceInfoTextWatcher());

[Link](new DeviceInfoTextWatcher());

[Link](new
DeviceInfoTextWatcher());

// Configura o botão de salvar para atualizar o dispositivo quando clicado

findViewById([Link]).setOnClickListener(v -> {
86

String novoNome = [Link]().toString();

String novaPotencia = [Link]().toString();

String novoTempo = [Link]().toString();

String novaQuantidade = [Link]().toString();

String novoCustoMensal = [Link]().toString();

String novoCustoDiario = [Link]().toString();

String novoGastoDiario = [Link]().toString();

String novoGastoMensal = [Link]().toString();

// Valida os campos e atualiza o dispositivo se estiverem corretos

if (validarCampos(novoNome, novaPotencia, novoTempo,


novaQuantidade, novoCustoMensal, novoCustoDiario, novoGastoDiario,
novoGastoMensal)) {

verificarEAtualizarDispositivo(novoNome, novaPotencia, novoTempo,


novaQuantidade, novoCustoMensal, novoCustoDiario, novoGastoDiario,
novoGastoMensal);

} else {

[Link](Atualizar_dispositivo.this, "Por favor, preencha todos


os campos corretamente.", Toast.LENGTH_SHORT).show();

});

// Configura o botão de voltar para fechar a activity atual

ImageButton voltarButton = findViewById([Link]);

[Link](v -> finish());


87

// Configura o botão de ajuda para exibir um diálogo de ajuda

ImageButton helpButton = findViewById([Link]);

[Link](v -> showHelpDialog());

// Exibe um diálogo de ajuda quando chamado

private void showHelpDialog() {

// Cria um construtor de AlertDialog

[Link] builder = new [Link](this);

// Infla a visualização do diálogo a partir do layout especificado

LayoutInflater inflater = getLayoutInflater();

View dialogView = [Link]([Link].dialog_help, null);

// Define a visualização do diálogo

[Link](dialogView);

// Adiciona um botão "OK" que simplesmente fecha o diálogo

[Link]("OK", null);

// Cria e exibe o diálogo

AlertDialog dialog = [Link]();

[Link]();

// Implementa um TextWatcher para monitorar mudanças nos campos de


texto

private class DeviceInfoTextWatcher implements TextWatcher {


88

@Override

public void beforeTextChanged(CharSequence s, int start, int count, int


after) {

// Nenhuma ação necessária antes da mudança do texto

@Override

public void onTextChanged(CharSequence s, int start, int before, int count)


{

// Valida e calcula o custo sempre que o texto mudar

validateAndCalculateCost();

@Override

public void afterTextChanged(Editable s) {

// Nenhuma ação necessária após a mudança do texto

// Valida as entradas e calcula os custos baseado nos valores inseridos

private void validateAndCalculateCost() {

// Verifica se os campos necessários foram inicializados

if (potenciaEditText == null || tempoEditText == null || quantidadeEditText


== null) {

Log.e("Atualizar_dispositivo", "Um ou mais EditText não foram


inicializados.");
89

return;

// Obtém o texto dos campos e a unidade de tempo selecionada

String potenciaString = [Link]().toString();

String tempoString = [Link]().toString();

String quantidadeString = [Link]().toString();

String unidadeTempo = [Link]().toString();

// Se algum campo estiver vazio, define valores padrão e retorna

if ([Link]() || [Link]() ||
[Link]()) {

[Link]("R$ 00,00");

[Link]("0 KWh");

[Link]("R$ 00,00");

[Link]("0 KWh");

return;

// Converte as strings em números

double potencia;

double tempo;

int quantidade;

try {
90

potencia = [Link](potenciaString);

tempo = [Link](tempoString);

quantidade = [Link](quantidadeString);

} catch (NumberFormatException e) {

[Link]("R$ 00,00");

[Link]("0 KWh");

[Link]("R$ 00,00");

[Link]("0 KWh");

return;

// Verifica e ajusta o tempo baseado na unidade selecionada

if ([Link]("minutos/dia")) {

if (tempo > MAX_MINUTOS) {

[Link](this, "O máximo permitido é 1440 minutos.",


Toast.LENGTH_SHORT).show();

[Link]("R$ 00,00");

[Link]("0 KWh");

[Link]("R$ 00,00");

[Link]("0 KWh");

return;

tempo = tempo / 60.0; // Converte minutos para horas

} else if ([Link]("horas/dia")) {

if (tempo > MAX_HORAS) {


91

[Link](this, "O máximo permitido é 24 horas.",


Toast.LENGTH_SHORT).show();

[Link]("R$ 00,00");

[Link]("0 KWh");

[Link]("R$ 00,00");

[Link]("0 KWh");

return;

} else {

[Link](this, "Unidade de tempo inválida.",


Toast.LENGTH_SHORT).show();

[Link]("R$ 00,00");

[Link]("0 KWh");

[Link]("R$ 00,00");

[Link]("0 KWh");

return;

// Calcula o consumo diário e os custos com base nos valores inseridos

double consumoDiario = (potencia / 1000.0) * tempo;

double custoDiario = consumoDiario * TARIFA * quantidade;

double custoMensal = consumoDiario * TARIFA * quantidade * 30;

double gastoMensalKWh = consumoDiario * 30 * quantidade;

double gastoDiarioKWh = consumoDiario * quantidade;


92

// Arredonda os valores e os formata para exibição

int gastoMensalKWhInt = (int) [Link](gastoMensalKWh);

int gastoDiarioKWhInt = (int) [Link](gastoDiarioKWh);

[Link]("R$ " + [Link]("%.2f", custoMensal));

[Link](gastoMensalKWhInt + " KWh");

[Link]("R$ " + [Link]("%.2f", custoDiario));

[Link](gastoDiarioKWhInt + " KWh");

// Verifica se todos os campos fornecidos não estão vazios

private boolean validarCampos(String nome, String potencia, String tempo,


String quantidade, String custoMensal, String gastoMensal, String custoDiario, String
gastoDiario) {

return ![Link]() && ![Link]() && ![Link]() && !


[Link]() && ![Link]() && ![Link]() && !
[Link]() && ![Link]();

// Verifica e atualiza as informações do dispositivo no Firestore


93

private void verificarEAtualizarDispositivo(String nome, String potencia, String


tempo, String quantidade, String custoMensal, String gastoMensal, String
custoDiario, String gastoDiario) {

// Verifica se o ID do dispositivo é válido

if (dispositivoId == null || [Link]()) {

Log.e("Atualizar_dispositivo", "ID do dispositivo é inválido.");

[Link](Atualizar_dispositivo.this, "ID do dispositivo é inválido.",


Toast.LENGTH_SHORT).show();

return;

double potenciaValue;

double tempoValue;

double quantidadeValue;

// Exibe os valores dos parâmetros no log para depuração

Log.d("Atualizar_dispositivo", "Potência: " + potencia);

Log.d("Atualizar_dispositivo", "Tempo: " + tempo);

Log.d("Atualizar_dispositivo", "Quantidade: " + quantidade);

// Tenta converter os valores de potência, tempo e quantidade para


números

try {

potenciaValue = [Link](potencia);

tempoValue = [Link](tempo);

quantidadeValue = [Link](quantidade);
94

} catch (NumberFormatException e) {

// Em caso de erro na conversão, exibe uma mensagem e sai do método

Log.e("Atualizar_dispositivo", "Erro na conversão: " + [Link]());

[Link](Atualizar_dispositivo.this, "Potência, tempo ou


quantidade inválidos. Não foi possível atualizar.", Toast.LENGTH_SHORT).show();

return;

// Obtém a data atual formatada como "MM-yyyy"

Calendar calendar = [Link]();

SimpleDateFormat sdf = new SimpleDateFormat("MM-yyyy", new


Locale("pt", "BR"));

String mesAno = [Link]([Link]());

// Referência para o documento do dispositivo no Firestore

DocumentReference dispositivoRef =
[Link]("usuarios").document(userId)

.collection("dispositivos").document(mesAno).collection("dispositivos").
document(dispositivoId);

// Obtém o documento do dispositivo e atualiza os dados

[Link]().addOnCompleteListener(task -> {

if ([Link]()) {

// Verifica se o documento existe

if ([Link]().exists()) {

// Calcula o consumo diário e os custos


95

double consumoDiario = (potenciaValue / 1000.0) * tempoValue;

double custoDiarioValue = consumoDiario * TARIFA *


quantidadeValue;

double custoMensalValue = custoDiarioValue * 30; // Assumindo 30


dias no mês

double gastoDiarioValue = consumoDiario * quantidadeValue;

double gastoMensalValue = gastoDiarioValue * 30;

// Obtém a unidade de tempo selecionada no Spinner

Spinner tempoUsoSpinner = findViewById([Link]);

String unidadeTempo = (tempoUsoSpinner != null) ?


[Link]().toString() : "Não definido";

// Cria um mapa com as atualizações a serem feitas no documento

Map<String, Object> dispositivoUpdates = new HashMap<>();

[Link]("Nome", nome);

[Link]("Potência", potenciaValue);

[Link]("Tempo", tempoValue);

[Link]("Quantidade", quantidadeValue);

[Link]("CustoMensal", custoMensalValue);

[Link]("CustoDiario", custoDiarioValue);

[Link]("GastoMensalKwh", gastoMensalValue);

[Link]("GastoDiarioKwh", gastoDiarioValue);

[Link]("UnidadeTempo", unidadeTempo);
96

// Atualiza o documento no Firestore e trata o sucesso e falha

[Link](dispositivoUpdates)

.addOnSuccessListener(aVoid -> {

[Link](Atualizar_dispositivo.this, "Dispositivo
atualizado com sucesso!", Toast.LENGTH_SHORT).show();

Intent intent = new Intent(Atualizar_dispositivo.this,


[Link]);

startActivity(intent);

finish();

})

.addOnFailureListener(e -> {

[Link](Atualizar_dispositivo.this, "Erro ao atualizar


dispositivo. Tente novamente.", Toast.LENGTH_SHORT).show();

Log.e("Atualizar_dispositivo", "Erro ao atualizar dispositivo",


e);

});

} else {

// Documento não encontrado, exibe mensagem de erro

Log.e("Atualizar_dispositivo", "Documento com ID " + dispositivoId +


" não encontrado.");

[Link](Atualizar_dispositivo.this, "Documento não


encontrado. Verifique o ID.", Toast.LENGTH_SHORT).show();

} else {

// Falha ao obter o documento, exibe mensagem de erro


97

Log.e("Atualizar_dispositivo", "Erro ao obter o documento",


[Link]());

[Link](Atualizar_dispositivo.this, "Erro ao verificar o


documento. Tente novamente.", Toast.LENGTH_SHORT).show();

});

// Exibe os valores que estão sendo atualizados para depuração

Log.d("Atualizar_dispositivo", "Atualizando dispositivo com:");

Log.d("Atualizar_dispositivo", "Nome: " + nome);

Log.d("Atualizar_dispositivo", "Potência: " + potencia);

Log.d("Atualizar_dispositivo", "Tempo: " + tempo);

Log.d("Atualizar_dispositivo", "Quantidade: " + quantidade);

Log.d("Atualizar_dispositivo", "Custo Mensal: " + custoMensal);

Log.d("Atualizar_dispositivo", "Gasto Mensal: " + gastoMensal);

Log.d("Atualizar_dispositivo", "Custo Diário: " + custoDiario);

Log.d("Atualizar_dispositivo", "Gasto Diário: " + gastoDiario);

}
98

// Método para carregar uma imagem em um ImageView usando a URL


fornecida

private void loadImage(String imageUrl) {

// Obtém a referência para o ImageView do layout

ImageView imageView = findViewById([Link]);

// Verifica se o ImageView foi encontrado no layout

if (imageView == null) {

Log.e("Atualizar_dispositivo", "ImageView não encontrado no layout");

return; // Sai do método se o ImageView não estiver presente

// Exibe a URL da imagem no log para depuração

Log.d("Atualizar_dispositivo", "URL da imagem: " + imageUrl);

try {

// Se a URL da imagem for nula ou vazia, carrega uma imagem padrão

if (imageUrl == null || [Link]()) {

[Link](this) // Usa a biblioteca Glide para carregar a imagem

.load([Link]) // Carrega um recurso drawable como


imagem padrão

.into(imageView); // Define a imagem carregada no ImageView


99

} else {

// Se a URL da imagem não for nula ou vazia, carrega a imagem da


URL fornecida

[Link](this)

.load(imageUrl) // Carrega a imagem da URL fornecida

.placeholder([Link]) // Exibe uma imagem de


placeholder enquanto a imagem está carregando

.error([Link]) // Exibe uma imagem padrão se ocorrer


um erro ao carregar a imagem

.into(imageView); // Define a imagem carregada no ImageView

// Define a URL da imagem como uma tag no ImageView para referência


futura

[Link](imageUrl);

} catch (Exception e) {

// Captura e imprime qualquer exceção que ocorra durante o


carregamento da imagem

[Link]();

// Exibe uma mensagem de erro no log se ocorrer uma exceção

Log.e("Atualizar_dispositivo", "Erro ao carregar imagem: " +


[Link]());

[Link]:

package [Link];
100

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];
101

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link].*;

import [Link];

import [Link];

import [Link];

public class Cadastro extends AppCompatActivity {

private EditText nameEditText;

private EditText emailEditText;

private EditText passwordEditText;

private EditText confirmPasswordEditText;

private FirebaseAuth mAuth;

private FirebaseFirestore db;

@Override

protected void onCreate(Bundle savedInstanceState) {

[Link](savedInstanceState);
102

// Define o layout da atividade usando o arquivo XML de layout


activity_cadastro

setContentView([Link].activity_cadastro);

// Inicializa a instância do FirebaseAuth para autenticação

mAuth = [Link]();

// Inicializa a instância do FirebaseFirestore para operações de banco de


dados

db = [Link]();

// Define um listener para ajustar o padding da visualização principal de


acordo com as barras do sistema

[Link](findViewById([Link]), (v,
insets) -> {

Insets systemBars =
[Link]([Link]());

// Ajusta o padding da visualização principal com base nas insets das


barras do sistema

[Link]([Link], [Link], [Link],


[Link]);

return insets;

});

// Obtém referências para os campos de entrada de texto

nameEditText = findViewById([Link]);

emailEditText = findViewById([Link]);
103

passwordEditText = findViewById([Link].editTextTextPassword2);

confirmPasswordEditText = findViewById([Link].editTextTextPassword3);

// Configura o TextView de termos e condições

TextView();

// Obtém referência para o botão de cadastro

Button buttonCadastrar = findViewById([Link].button3);

// Define um listener para o clique do botão de cadastro

[Link](v -> {

Log.d("Cadastro", "Botão Cadastrar clicado");

// Verifica se todos os campos são válidos

if (areFieldsValid()) {

// Mostra um overlay de carregamento

showLoadingOverlay();

// Obtém os valores dos campos de entrada

String email = [Link]().toString().trim();

String senha = [Link]().toString().trim();

String nome = [Link]().toString().trim();

// Cria um novo usuário com e-mail e senha fornecidos

[Link](email, senha)
104

.addOnCompleteListener(task -> {

// Esconde o overlay de carregamento após a tentativa de


cadastro

hideLoadingOverlay();

if ([Link]()) {

// Se o cadastro for bem-sucedido

Log.d("Cadastro", "Usuário criado com sucesso.");

FirebaseUser user = [Link]();

if (user != null) {

// Envia um e-mail de verificação para o novo usuário

[Link]()

.addOnCompleteListener(task1 -> {

if ([Link]()) {

// Se o e-mail de verificação for enviado com


sucesso

Log.d("Cadastro", "E-mail de verificação


enviado.");

[Link]([Link], "Cadastro
realizado e e-mail de confirmação enviado.", Toast.LENGTH_LONG).show();

} else {

// Se houver um erro ao enviar o e-mail de


verificação

Log.e("Cadastro", "Erro ao enviar e-mail de


verificação", [Link]());
105

[Link]([Link], "Falha ao enviar


e-mail de verificação.", Toast.LENGTH_LONG).show();

// Navega para a atividade de início e encerra a


atividade de cadastro

Intent intent = new Intent([Link],


[Link]);

startActivity(intent);

finish();

});

// Converte o nome para caixa alta e salva os dados do


usuário

String nomeEmCaixaAlta = [Link]();

salvarDadosUsuario([Link](), nomeEmCaixaAlta);

} else {

// Se o cadastro falhar

hideLoadingOverlay();

if ([Link]() instanceof
FirebaseAuthUserCollisionException) {

// Caso o e-mail já esteja cadastrado

mostrarAlertaEmailJaCadastrado();

} else if ([Link]() instanceof


FirebaseAuthWeakPasswordException) {

// Caso a senha seja fraca


106

[Link]([Link], "A senha é muito fraca.


Por favor, use uma senha mais forte.", Toast.LENGTH_LONG).show();

} else {

// Para outros erros de cadastro

Log.e("Cadastro", "Erro ao cadastrar usuário",


[Link]());

[Link]([Link], "Erro ao cadastrar


usuário.", Toast.LENGTH_LONG).show();

});

});

private void setupTermsTextView() {

TextView textViewTerms = findViewById([Link].textView3);

// Obtém a referência do TextView dos termos

String text = [Link]().toString();

// Obtém o texto do TextView

SpannableString spannableString = new SpannableString(text);


107

// Cria uma string editável para formatar o texto

int start = [Link]("Termos de Uso");

// Encontra a posição do texto "Termos de Uso"

if (start >= 0) {

// Se o texto for encontrado

int end = start + "Termos de Uso".length();

[Link](new StyleSpan([Link]), start, end,


Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

// Aplica negrito

[Link](new
ForegroundColorSpan([Link]("#228B22")), start, end,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

// Aplica cor verde

[Link](new ClickableSpan() {

@Override

public void onClick(@NonNull View widget) {

startActivity(new Intent([Link], [Link]));

// Ao clicar, vai para a activity de Termos

}, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);


108

[Link](spannableString);

// Define o texto formatado no TextView

[Link]([Link]()
);

// Permite que o texto seja clicável

private boolean areFieldsValid() {

String nome = [Link]().toString().trim();

String email = [Link]().toString().trim();

String senha = [Link]().toString().trim();

String confirmaSenha = [Link]().toString().trim();

// Obtém os valores dos campos de entrada

if ([Link]() || [Link]() || [Link]() ||


[Link]()) {

// Verifica se algum campo está vazio

[Link](this, "Por favor, preencha todos os campos.",


Toast.LENGTH_SHORT).show();

return false;

}
109

if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()) {

// Verifica se o e-mail é válido

[Link](this, "Por favor, insira um e-mail válido.",


Toast.LENGTH_SHORT).show();

return false;

if ([Link]() < 8) {

// Verifica se a senha tem no mínimo 8 caracteres

[Link](this, "A senha deve ter no mínimo 8 caracteres.",


Toast.LENGTH_SHORT).show();

return false;

if (![Link](confirmaSenha)) {

// Verifica se as senhas coincidem

[Link](this, "As senhas não coincidem.",


Toast.LENGTH_SHORT).show();

return false;

return true;

// Se todos os campos estiverem corretos

}
110

private void salvarDadosUsuario(String userId, String nome) {

Map<String, Object> user = new HashMap<>();

[Link]("nome", nome);

// Cria um mapa de dados do usuário

[Link]("usuarios").document(userId)

.set(user)

.addOnSuccessListener(aVoid -> {

Log.d("Cadastro", "Dados do usuário salvos com sucesso.");

})

.addOnFailureListener(e -> {

Log.e("Cadastro", "Erro ao salvar os dados do usuário", e);

});

// Salva os dados no Firestore

private void mostrarAlertaEmailJaCadastrado() {

[Link] builder = new [Link](this);

[Link]("E-mail já cadastrado")

.setMessage("Este e-mail já está cadastrado. Deseja fazer login?")

.setPositiveButton("Sim", (dialog, which) -> {

Intent intent = new Intent([Link], [Link]);

startActivity(intent);

finish();
111

// Vai para a tela de login se o usuário clicar em "Sim"

})

.setNegativeButton("Não", (dialog, which) -> {

[Link]();

// Fecha o diálogo se o usuário clicar em "Não"

})

.setCancelable(false)

.show();

private void showLoadingOverlay() {

View loadingOverlay = findViewById([Link]);

if (loadingOverlay != null) {

[Link]([Link]);

setUserInteractionEnabled(false);

// Exibe o overlay de carregamento

private void hideLoadingOverlay() {

View loadingOverlay = findViewById([Link]);

if (loadingOverlay != null) {

[Link]([Link]);

setUserInteractionEnabled(true);
112

// Esconde o overlay de carregamento

private void setUserInteractionEnabled(boolean enabled) {

View mainContent = findViewById([Link]);

if (mainContent != null) {

[Link](!enabled);

[Link](!enabled);

[Link](!enabled);

// Ativa ou desativa a interação do usuário

[Link]:

package [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];
113

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

public class Dados extends AppCompatActivity {

private FirebaseAuth mAuth;

private FirebaseFirestore db;

private EditText editTextNome;


114

private EditText editTextEmail;

private EditText editTextSenha;

private ImageView profileImageView;

private ImageButton ImageButtonLapisN;

private ImageButton ImageButtonLapisE;

private ImageButton ImageButtonLapisS;

private TextView logoutTextView;

private boolean isEditing = false;

@Override

protected void onCreate(Bundle savedInstanceState) {

[Link](savedInstanceState);

[Link](this);

// Habilita o modo "Edge-to-Edge", que utiliza toda a tela do dispositivo,


incluindo áreas com barras de sistema

setContentView([Link].activity_dados);

// Define o layout da atividade

mAuth = [Link]();

// Inicializa a instância do Firebase Authentication

db = [Link]();

// Inicializa a instância do Firebase Firestore


115

if ([Link]() == null) {

startActivity(new Intent([Link], [Link]));

finish();

return;

// Verifica se o usuário está autenticado; se não, redireciona para a tela


de login e finaliza a atividade atual

[Link](findViewById([Link]), (v,
insets) -> {

Insets systemBars =
[Link]([Link]());

[Link]([Link], [Link], [Link],


[Link]);

return insets;

// Ajusta o padding do layout principal para levar em conta as barras do


sistema (status bar, navigation bar)

});

editTextNome = findViewById([Link]);

editTextEmail = findViewById([Link]);

editTextSenha = findViewById([Link]);

profileImageView = findViewById([Link]);

// Obtém referências para os campos de entrada e o ImageView do perfil


116

ImageButtonLapisN = findViewById([Link]);

ImageButtonLapisE = findViewById([Link]);

ImageButtonLapisS = findViewById([Link]);

// Obtém referências para os botões de edição

disableEditTexts();

// Desativa os campos de edição inicialmente

[Link](view ->
toggleEditMode(editTextNome));

// Configura o botão de lápis para o nome para alternar o modo de edição

[Link](view -> {

Intent intent = new Intent([Link], Alterando_email.class);

startActivity(intent);

// Configura o botão de lápis para o e-mail para abrir a tela de alteração


de e-mail

});

[Link](view -> {

Intent intent = new Intent([Link], Alterando_senha.class);

startActivity(intent);

// Configura o botão de lápis para a senha para abrir a tela de alteração


de senha

});
117

logoutTextView = findViewById([Link].textView5);

[Link](view -> {

if (isEditing) {

salvarAlteracoes();

} else {

showExitConfirmationDialog();

// Configura o TextView de logout para salvar as alterações se estiver


editando ou mostrar um diálogo de confirmação de saída

});

ImageButton voltarButton = findViewById([Link]);

[Link](v -> finish());

// Configura o botão de voltar para finalizar a atividade atual

fetchUserData();

// Chama o método para buscar os dados do usuário

findViewById([Link]).setOnClickListener(view -> disableEditTexts());

// Configura o clique na área principal para desativar os campos de edição

private void fetchUserData() {


118

FirebaseUser user = [Link](); // Obtém o usuário atual


autenticado

if (user != null) { // Verifica se o usuário está autenticado

[Link]([Link]()); // Define o e-mail do usuário no


campo de texto

String userId = [Link](); // Obtém o ID do usuário

// Obtém o documento "FotoPerfil" da coleção "Foto" para buscar a URL


da foto padrão

[Link]("Foto").document("FotoPerfil").get()

.addOnCompleteListener(task -> {

if ([Link]() && [Link]() != null) {

DocumentSnapshot fotoDocument = [Link]();

String defaultPhotoUrl = [Link]("FotoPerfil");

// Obtém o documento do usuário da coleção "usuarios" para


buscar o nome e a URL da foto de perfil

[Link]("usuarios").document(userId).get()

.addOnCompleteListener(userTask -> {

if ([Link]() && [Link]() !=


null) {

DocumentSnapshot userDocument =
[Link]();

String nome = [Link]("nome");


119

[Link](nome != null ? nome : "Nome


não encontrado");

// Carrega a foto de perfil do usuário ou a foto


padrão, se disponível

String fotoPerfilUrl =
[Link]("fotoPerfil");

if (fotoPerfilUrl != null && ![Link]()) {

[Link]([Link])

.load(fotoPerfilUrl)

.placeholder([Link])

.error([Link])

.into(profileImageView);

} else if (defaultPhotoUrl != null && !


[Link]()) {

[Link]([Link])

.load(defaultPhotoUrl)

.placeholder([Link])

.error([Link])

.into(profileImageView);

} else {

[Link]([Link].v
azio); // Define uma imagem padrão caso não haja URL

} else {

[Link]("Erro ao buscar nome");


120

[Link]([Link]
io); // Define uma imagem padrão em caso de erro

});

} else {

[Link]([Link], "Erro ao buscar foto padrão",


Toast.LENGTH_SHORT).show();

[Link]([Link]); //
Define uma imagem padrão em caso de erro ao buscar foto padrão

});

[Link]("********"); // Define um texto oculto para a senha

private void deslogar() {

[Link](); // Desloga o usuário

[Link] editor = getSharedPreferences("PrefsFile",


MODE_PRIVATE).edit();

[Link]("isLoggedIn", false); // Atualiza o status de login nas


preferências compartilhadas

[Link]();

startActivity(new Intent([Link], [Link])); // Redireciona para a tela


de login

finish(); // Finaliza a atividade atual


121

private void toggleEditMode(EditText editText) {

if (!isEditing) { // Se não estiver em modo de edição

enableEditText(editText); // Habilita o campo de edição

[Link]("SALVAR ALTERAÇÕES"); // Atualiza o texto do


TextView de logout

isEditing = true; // Define o estado de edição como verdadeiro

} else { // Se já estiver em modo de edição

disableEditTexts(); // Desativa todos os campos de edição

[Link]("Sair"); // Atualiza o texto do TextView de logout

isEditing = false; // Define o estado de edição como falso

private void enableEditText(EditText editText) {

disableEditTexts(); // Desativa todos os campos de edição

[Link](true); // Habilita o campo de edição específico

[Link](); // Solicita o foco para o campo de edição

private void disableEditTexts() {

[Link](false); // Desativa o campo de texto para o nome

[Link](false); // Desativa o campo de texto para o e-mail


122

[Link](false); // Desativa o campo de texto para a


senha

private void salvarAlteracoes() {

FirebaseUser user = [Link](); // Obtém o usuário atual


autenticado

if (user != null) { // Verifica se o usuário está autenticado

String userId = [Link](); // Obtém o ID do usuário

String nomeAtualizado =
[Link]().toString().toUpperCase(); // Obtém o nome atualizado e
converte para maiúsculas

String novoEmail = [Link]().toString(); // Obtém o novo e-


mail

String novaSenha = [Link]().toString(); // Obtém a nova


senha

// Atualiza o nome do usuário no Firestore

[Link]("usuarios").document(userId)

.update("nome", nomeAtualizado)

.addOnSuccessListener(aVoid -> {

[Link]([Link], "Nome atualizado com sucesso!",


Toast.LENGTH_SHORT).show();

})

.addOnFailureListener(e -> [Link]([Link], "Erro ao


atualizar nome", Toast.LENGTH_SHORT).show());

// Atualiza o e-mail se o novo e-mail for diferente do atual


123

if (![Link](novoEmail) && ![Link]([Link]()))


{

String senhaAtual = [Link]().toString(); // Obtém a


senha atual do usuário

if (![Link](senhaAtual)) {

AuthCredential credential =
[Link]([Link](), senhaAtual); // Cria as credenciais
de autenticação

// Reautentica o usuário com a senha atual

[Link](credential)

.addOnSuccessListener(aVoid -> {

// Atualiza o e-mail do usuário

[Link](novoEmail)

.addOnSuccessListener(aVoid1 -> {

[Link]([Link], "Email atualizado com


sucesso!", Toast.LENGTH_SHORT).show();

enviarEmailConfirmacao(user); // Envia um e-mail de


confirmação após a atualização

})

.addOnFailureListener(e -> [Link]([Link],


"Erro ao atualizar email", Toast.LENGTH_SHORT).show());

})

.addOnFailureListener(e -> [Link]([Link], "Erro


na reautenticação. Verifique a senha atual.", Toast.LENGTH_SHORT).show());

} else {
124

[Link]([Link], "Por favor, insira a senha atual para


atualizar o email.", Toast.LENGTH_SHORT).show();

// Placeholder para a atualização de senha, mas o código está


incompleto

if (![Link](novaSenha) && ![Link]("********")) {

// Atualiza o texto do TextView de logout e desativa o modo de edição

[Link]("Sair");

disableEditTexts();

isEditing = false; // Define o estado de edição como falso

private void showExitConfirmationDialog() {

// Cria e exibe um diálogo de confirmação para sair da atividade

new [Link](this)

.setTitle("Confirmar Saída")

.setMessage("Você tem certeza de que deseja sair? Todas as


alterações não salvas serão perdidas.")

.setPositiveButton("Sim, sair agora!!!!!!!!!!!!!!!!!!!!!!!!!!!!", new


[Link]() {

@Override
125

public void onClick(DialogInterface dialog, int which) {

deslogar(); // Chama o método para deslogar o usuário

})

.setNegativeButton("Cancelar", null) // Botão para cancelar a saída

.show();

private void enviarEmailConfirmacao(FirebaseUser user) {

// Envia um e-mail de confirmação para o usuário

[Link]()

.addOnSuccessListener(aVoid -> [Link]([Link], "Email


de confirmação enviado!", Toast.LENGTH_SHORT).show())

.addOnFailureListener(e -> [Link]([Link], "Erro ao


enviar email de confirmação", Toast.LENGTH_SHORT).show());

[Link]:

package [Link];

// Definição da classe Device, que representa um dispositivo e suas


propriedades.

public class Device {

// Propriedades do dispositivo
126

private String nome;

private double potencia;

private double tempo;

private int quantidade;

private double custoDiario;

private double custoDiarioTwh;

private double custoMensal;

private double custoMensalTwh;

private String imagemUrl;

private String mesAno;

private String unidadeTempo;

// Construtor da classe Device que inicializa todos os campos

public Device(String nome, double potencia, double tempo, int quantidade,


double custoDiario, double custoDiarioTwh, double custoMensalTwh, double
custoMensal, String imagemUrl, String mesAno, String unidadeTempo) {

// Inicializa dados do dispositivo

[Link] = nome;

[Link] = potencia;

[Link] = tempo;

[Link] = quantidade;

[Link] = custoMensal;

[Link] = imagemUrl;

[Link] = mesAno;

[Link] = unidadeTempo;
127

// Métodos getter e setter para o campo nome

public String getNome() { return nome; }

public void setNome(String nome) { [Link] = nome; }

// Métodos getter e setter para o campo potencia

public double getPotencia() { return potencia; }

public void setPotencia(double potencia) { [Link] = potencia; }

// Métodos getter e setter para o campo tempo

public double getTempo() { return tempo; }

public void setTempo(double tempo) { [Link] = tempo; }

// Métodos getter e setter para o campo quantidade

public int getQuantidade() { return quantidade; }

public void setQuantidade(int quantidade) { [Link] = quantidade; }

// Métodos getter e setter para o campo custoDiario

public double getCustoDiario() { return custoDiario; }

public void setCustoDiario(double custoDiario) { [Link] =


custoDiario; }

// Métodos getter e setter para o campo custoDiarioTwh

public double getCustoDiarioTwh() { return custoDiarioTwh; }


128

public void setCustoDiarioTwh(double custoDiarioTwh)


{ [Link] = custoDiarioTwh; }

// Métodos getter e setter para o campo custoMensal

public double getCustoMensal() { return custoMensal; }

public void setCustoMensal(double custoMensal) { [Link] =


custoMensal; }

// Métodos getter e setter para o campo custoMensalTwh

public double getCustoMensalTwh() { return custoMensalTwh; }

public void setCustoMensalTwh(double custoMensalTwh)


{ [Link] = custoMensalTwh; }

// Métodos getter e setter para o campo imagemUrl

public String getImagemUrl() { return imagemUrl; }

public void setImagemUrl(String imagemUrl) { [Link] =


imagemUrl; }

// Métodos getter e setter para o campo mesAno

public String getMesAno() { return mesAno; }

public void setMesAno(String mesAno) { [Link] = mesAno; }

// Métodos getter e setter para o campo unidadeTempo

public String getUnidadeTempo() { return unidadeTempo; }

public void setUnidadeTempo(String unidadeTempo) { [Link] =


unidadeTempo; }
129

;}

[Link]:

package [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];
130

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

public class Dispositivo extends AppCompatActivity {

private static final String TAG = "Dispositivo";

private RelativeLayout loadingOverlay;

private Spinner spinnerTempoUso;

private FirebaseFirestore db;

private String userId;

private SwipeRefreshLayout swipeRefreshLayout;

private TextView textViewCusto;

private Calendar calendar;

@Override
131

protected void onCreate(Bundle savedInstanceState) {

[Link](savedInstanceState);

setContentView([Link].activity_dispositivo);

// Inicializa o Firebase Firestore e obtém o ID do usuário autenticado

db = [Link]();

FirebaseUser user = [Link]().getCurrentUser();

if (user != null) {

userId = [Link]();

} else {

[Link](this, "Usuário não autenticado.",


Toast.LENGTH_SHORT).show();

finish();

return;

// Configura o SwipeRefreshLayout para permitir o carregamento por


atualização

swipeRefreshLayout = findViewById([Link]);

[Link](this::onRefresh);

// Inicializa o overlay de carregamento e o spinner

loadingOverlay = findViewById([Link]);

spinnerTempoUso = findViewById([Link]);
132

// Obtém os dados do Intent que iniciaram esta Activity

Intent intent = getIntent();

final String dispositivoId = [Link]("ID");

final String nome = [Link]("NOME");

final String potencia = [Link]("POTENCIA");

final String tempo = [Link]("TEMPO");

final double custoDiario = [Link]("CUSTO_DIARIO", 0.0);

final double custoDiarioKWh =


[Link]("CUSTO_DIARIO_KWh", 0.0);

final double custoMensal = [Link]("CUSTO_MENSAL",


0.0);

final double custoMensalKWh =


[Link]("CUSTO_MENSAL_KWh", 0.0);

final String imagemUrl = [Link]("IMAGEM");

final String unidadeTempo = [Link]("UNIDADE_TEMPO");

final String quantidade = [Link]("QUANTIDADE");

// Inicializa o calendário para obter o mês e ano atuais

calendar = [Link]();

// Configura os campos da interface com os dados recebidos

EditText nomeTextView = findViewById([Link]);

EditText potenciaTextView = findViewById([Link]);

EditText tempoTextView = findViewById([Link]);

EditText custoDiarioTextView = findViewById([Link]);


133

EditText gastoDiarioKWhTextView =
findViewById([Link]);

EditText custoTextView = findViewById([Link]);

EditText gastoKWhEditText = findViewById([Link]);

EditText quantidadeEditText = findViewById([Link]);

ImageView dispositivoImageView =
findViewById([Link]);

TextView atualizarTextView = findViewById([Link].textView5);

TextView excluirTextView = findViewById([Link].textView6);

// Define os textos dos campos

[Link](nome != null ? nome : "Nome não disponível");

[Link](potencia != null ? formatAsInteger(potencia) +


" W" : "Não disponível");

[Link](tempo != null ? tempo : "Horas não disponíveis");

// Configura o formato de moeda para os custos

NumberFormat currencyFormat =
[Link](new Locale("pt", "BR"));

[Link](2);

[Link](2);

String custoDiarioFormatado = [Link](custoDiario);

[Link](custoDiarioFormatado);

String custoMensalFormatado = [Link](custoMensal);


134

[Link](custoMensalFormatado);

// Configura o formato decimal para o consumo em KWh

DecimalFormat decimalFormat = new DecimalFormat("#.#");

String gastoDiarioKWhFormatado =
[Link](custoDiarioKWh) + " KWh";

String gastoKWhFormatado = [Link](custoMensalKWh) +


" KWh";

[Link](gastoDiarioKWhFormatado);

[Link](gastoKWhFormatado);

[Link]((quantidade != null ?
formatAsInteger(quantidade) : "Não disponível"));

// Exibe a imagem do dispositivo e configura o spinner

showLoadingOverlay();

loadImage(imagemUrl);

setupSpinner(unidadeTempo);

// Configura o comportamento do botão de atualizar

[Link](v -> {

Intent editarIntent = new Intent([Link],


Atualizar_dispositivo.class);

[Link]("ID", dispositivoId);

[Link]("NOME", nome);
135

[Link]("POTENCIA", potencia);

[Link]("TEMPO", tempo);

[Link]("GASTO", custoMensal);

[Link]("IMAGEM", imagemUrl);

[Link]("UNIDADE_TEMPO", unidadeTempo);

[Link]("QUANTIDADE", quantidade);

[Link]("CUSTO_DIARIO", custoDiario);

[Link]("CUSTO_DIARIO_KWh", custoDiarioKWh);

[Link]("CUSTO_MENSAL", custoMensal);

[Link]("CUSTO_MENSAL_KWh", custoMensalKWh);

startActivity(editarIntent);

});

// Configura o comportamento do botão de excluir

[Link](v -> {

if (dispositivoId != null) {

showDeleteConfirmationDialog(dispositivoId);

} else {

[Link]([Link], "ID do dispositivo não disponível.",


Toast.LENGTH_SHORT).show();

});

// Configura o botão de voltar


136

ImageButton backButton = findViewById([Link]);

[Link](v -> finish());

// Atualiza a visualização ao realizar o pull-to-refresh.

private void onRefresh() {

showLoadingOverlay();

new Handler().postDelayed(() -> {

hideLoadingOverlay();

[Link](false);

}, 1000);

// Configura o Spinner com as opções de tempo de uso e define a seleção


atual.

private void setupSpinner(String unidadeTempo) {

Spinner spinner = findViewById([Link]);

ArrayAdapter<CharSequence> adapter =
[Link](this, [Link].tempo_uso_opcoes,
[Link].simple_spinner_item);

[Link]([Link].simple_spinner_dr
opdown_item);

[Link](adapter);

if (unidadeTempo != null) {

int position = [Link](unidadeTempo);


137

if (position >= 0) {

[Link](position);

[Link](false);

// Carrega a imagem do dispositivo usando a URL fornecida.

private void loadImage(String imageUrl) {

showLoadingOverlay();

ImageView imageView = findViewById([Link]);

if (imageView == null) {

Log.e(TAG, "ImageView com ID imageViewDispositivo não


encontrado");

[Link](this, "Erro: ImageView não encontrado.",


Toast.LENGTH_SHORT).show();

return;

if (imageUrl == null || [Link]()) {

Log.w(TAG, "URL da imagem é nula ou vazia. Usando URL padrão.");

imageUrl = "https:[Link]/default_image.png";

}
138

Log.d(TAG, "URL da imagem: " + imageUrl);

[Link](this)

.load(imageUrl)

.placeholder([Link])

.error([Link])

.into(imageView);

hideLoadingOverlay();

// Exibe o overlay de carregamento.

private void showLoadingOverlay() {

if (loadingOverlay != null) {

[Link]([Link]);

// Oculta o overlay de carregamento.

private void hideLoadingOverlay() {

if (loadingOverlay != null) {

[Link]([Link]);

}
139

// Formata o valor como um número inteiro.

private String formatAsInteger(String value) {

try {

int number = [Link](value);

return [Link]().format(number);

} catch (NumberFormatException e) {

Log.e(TAG, "Erro ao formatar o valor: " + value, e);

return "Valor inválido";

// Exibe um diálogo de confirmação para exclusão do dispositivo.

private void showDeleteConfirmationDialog(String dispositivoId) {

[Link] builder = new [Link](this);

[Link]("Excluir Dispositivo");

[Link]("Tem certeza de que deseja excluir este


dispositivo?");

[Link]("Sim", (dialog, which) ->


deleteDevice(dispositivoId));

[Link]("Não", null);

[Link]();

}
140

//Exclui o dispositivo da base de dados.

private void deleteDevice(String dispositivoId) {

[Link]("dispositivos").document(userId).collection("meusdispositivo
s").document(dispositivoId)

.delete()

.addOnCompleteListener(task -> {

if ([Link]()) {

[Link]([Link], "Dispositivo excluído com


sucesso.", Toast.LENGTH_SHORT).show();

finish();

} else {

[Link]([Link], "Erro ao excluir dispositivo.",


Toast.LENGTH_SHORT).show();

Log.e(TAG, "Erro ao excluir dispositivo: ", [Link]());

});

[Link], "Erro ao excluir dispositivo.", Toast.LENGTH_SHORT).show();

Log.e(TAG, "Erro ao excluir dispositivo: ", [Link]());

});

}
141

[Link]:

package [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];
142

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

public class Gastos extends AppCompatActivity {

// Declaração de variáveis para elementos da interface

private FirebaseAuth mAuth;

private FirebaseFirestore db;

private LinearLayout linearLayoutDevices;

private TextView textViewLista;

private TextView textViewTotal;

private TextView monthTextView;

private Calendar calendar;

private DecimalFormat currencyFormat;

private SwipeRefreshLayout swipeRefreshLayout;

private ImageButton btnPreviousMonth;

private ImageButton btnNextMonth;

@Override

protected void onCreate(Bundle savedInstanceState) {

[Link](savedInstanceState);
143

// Define o layout da atividade a partir do arquivo XML activity_gastos.xml

setContentView([Link].activity_gastos);

// Inicializa as instâncias do Firebase Authentication e Firestore

mAuth = [Link]();

db = [Link]();

// Vincula variáveis aos elementos do layout através dos IDs

linearLayoutDevices = findViewById([Link]);

textViewLista = findViewById([Link]);

textViewTotal = findViewById([Link]);

monthTextView = findViewById([Link]);

ImageView monthPickerIcon = findViewById([Link]);

swipeRefreshLayout = findViewById([Link]);

// Configura o formato de moeda com separadores personalizados

DecimalFormatSymbols symbols = new DecimalFormatSymbols();

[Link](',');

[Link]('.');

currencyFormat = new DecimalFormat("R$ #,##0.00", symbols);

// Inicializa o calendário e atualiza o TextView com o mês atual

calendar = [Link]();

updateMonthTextView();
144

// Define o listener para o ícone de seleção de mês, que exibe o


DatePickerDialog

[Link](v -> showDatePickerDialog());

// Define o listener para o SwipeRefreshLayout para atualizar os


dispositivos e o custo total

[Link](() -> {

fetchDevicesAndTotalCost();

});

// Faz a primeira chamada para buscar os dispositivos e o custo total

fetchDevicesAndTotalCost();

// Inicializa os botões de navegação de mês e define os listeners para


alterar o mês

ImageButton btnPreviousMonth = findViewById([Link]);

ImageButton btnNextMonth = findViewById([Link]);

[Link](v -> changeMonth(-1));

[Link](v -> changeMonth(1));

// Inicializa o botão de voltar e define o listener para fechar a atividade

ImageButton voltarButton = findViewById([Link]);

[Link](v -> finish());

}
145

private void updateMonthTextView() {

// Cria uma instância de SimpleDateFormat para formatar a data no


formato "MMMM yyyy"

SimpleDateFormat dateFormat = new SimpleDateFormat("MMMM yyyy",


[Link]());

// Obtém a data atual do calendário e formata como uma string

String currentMonth = [Link]([Link]());

// Define o texto do TextView com o mês e ano formatados

[Link](currentMonth);

private void changeMonth(int offset) {

// Clona o calendário atual para não alterar o objeto original

Calendar newCalendar = (Calendar) [Link]();

// Adiciona o offset de meses ao calendário clonado

[Link]([Link], offset);

// Verifica se a nova data está no futuro

if ([Link]([Link]())) {

// Exibe uma mensagem de erro se a nova data for no futuro

[Link]([Link], "Você não pode ir para um mês futuro.",


Toast.LENGTH_SHORT).show();

return;

}
146

// Atualiza o calendário atual com o novo mês

[Link]([Link], offset);

// Atualiza o TextView com o mês e ano corretos

updateMonthTextView();

// Recarrega os dispositivos e o custo total para o novo mês

fetchDevicesAndTotalCost();

private void showDatePickerDialog() {

// Obtém o ano e o mês atuais do calendário

int year = [Link]([Link]);

int month = [Link]([Link]);

// Cria um DatePickerDialog para selecionar uma data

DatePickerDialog datePickerDialog = new DatePickerDialog(this, (view,


selectedYear, selectedMonth, dayOfMonth) -> {

// Cria um calendário com a data selecionada

Calendar selectedCalendar = [Link]();

[Link]([Link], selectedYear);

[Link]([Link], selectedMonth);

// Verifica se a data selecionada está no futuro

if ([Link]([Link]())) {

// Exibe uma mensagem de erro se a data for no futuro


147

[Link]([Link], "Você não pode selecionar um mês


futuro.", Toast.LENGTH_SHORT).show();

return;

// Atualiza o calendário atual com a data selecionada

[Link]([Link], selectedYear);

[Link]([Link], selectedMonth);

// Atualiza o TextView com o mês e ano selecionados

updateMonthTextView();

// Recarrega os dispositivos e o custo total para o mês selecionado

fetchDevicesAndTotalCost();

}, year, month, [Link](Calendar.DAY_OF_MONTH));

// Obtém o ID do spinner de dias e o oculta

int daySpinnerId = getResources().getIdentifier("day", "id", "android");

View daySpinner =
[Link]().findViewById(daySpinnerId);

if (daySpinner != null) {

[Link]([Link]);

// Exibe o DatePickerDialog

[Link]();

}
148

private void fetchDevicesAndTotalCost() {

// Mostra um overlay de carregamento para indicar que a operação está


em progresso

showLoadingOverlay();

// Obtém o ID do usuário autenticado

String userId = [Link]().getUid();

// Formata a data atual no formato "MM-yyyy"

SimpleDateFormat sdf = new SimpleDateFormat("MM-yyyy",


[Link]());

String mesAno = [Link]([Link]());

// Obtém a coleção de dispositivos do Firestore para o usuário e mês


específicos

[Link]("usuarios").document(userId).collection("dispositivos").docu
ment(mesAno)

.collection("dispositivos")

.get()

.addOnCompleteListener(task -> {

// Remove todas as views existentes do LinearLayout

[Link]();

double totalCost = 0.0;

// Verifica se a tarefa foi concluída com sucesso

if ([Link]() && [Link]() != null) {


149

Log.d("Gastos", "Dados retornados: " +


[Link]().getDocuments());

// Verifica se a consulta retornou resultados

if ([Link]().isEmpty()) {

Log.d("Gastos", "Nenhum dispositivo encontrado para o


mês: " + mesAno);

// Define uma mensagem informando que nenhum


dispositivo foi encontrado

[Link]("Nenhum dispositivo encontrado.");

[Link](new
[Link](

[Link].MATCH_PARENT,

[Link].WRAP_CONTENT

));

[Link]([Link]);

// Adiciona a mensagem ao LinearLayout

[Link](textViewLista);

} else {

// Itera sobre os documentos retornados

for (QueryDocumentSnapshot document : [Link]()) {

Log.d("Gastos", "Documento: " + [Link]() + "


Dados: " + [Link]());
150

// Obtém os dados do documento

String nome = [Link]("Nome");

Double custoMensal =
[Link]("CustoMensal");

String imagemUrl = [Link]("ImagemUrl");

// Verifica se os campos são nulos antes de converter

String potencia = [Link]("Potência") != null ?


[Link]("Potência").toString() : "Não disponível";

String tempo = [Link]("Tempo") != null ?


[Link]("Tempo").toString() : "Não disponível";

String custoMensalString = custoMensal != null ?


[Link](custoMensal) : "Não disponível";

// Infla a view do item do dispositivo e define os dados

View deviceView =
[Link](this).inflate([Link].device_item, linearLayoutDevices, false);

TextView deviceName =
[Link]([Link]);

TextView deviceCost =
[Link]([Link]);

[Link](nome != null ? nome : "Nome não


disponível");

[Link](custoMensalString);
151

// Define um clique para a view do dispositivo

[Link](v -> {

Intent intent = new Intent([Link],


[Link]);

// Adiciona dados extras à Intent

[Link]("ID", [Link]());

[Link]("NOME", nome != null ? nome : "Nome


não disponível");

[Link]("POTENCIA", potencia);

[Link]("TEMPO", tempo);

[Link]("GASTO", custoMensalString);

[Link]("IMAGEM", imagemUrl != null ?


imagemUrl : "Não disponível");

[Link]("QUANTIDADE",
[Link]("Quantidade"));

[Link]("CUSTO_DIARIO",
[Link]("CustoDiario"));

[Link]("CUSTO_DIARIO_KWh",
[Link]("GastoDiarioKwh"));

[Link]("CUSTO_MENSAL",
[Link]("CustoMensal"));

[Link]("CUSTO_MENSAL_KWh",
[Link]("GastoMensalKwh"));

// Inicia a atividade Dispositivo


152

startActivity(intent);

});

// Adiciona a view do dispositivo ao LinearLayout

[Link](deviceView);

// Adiciona o custo mensal ao total se não for nulo

if (custoMensal != null) {

totalCost += custoMensal;

// Exibe o custo total acumulado

displayTotalCost(totalCost);

} else {

// Loga o erro caso a tarefa falhe e mostra uma mensagem


para o usuário

Log.e("Gastos", "Erro ao obter dispositivos",


[Link]());

[Link]([Link], "Erro ao carregar dispositivos",


Toast.LENGTH_SHORT).show();

// Oculta o overlay de carregamento e para a animação de


carregamento do swipe refresh layout
153

hideLoadingOverlay();

[Link](false);

});

private void fetchTotalCost() {

// Mostra um overlay de carregamento

showLoadingOverlay();

// Obtém o ID do usuário autenticado

String userId = [Link]().getUid();

// Formata a data atual no formato "MM-yyyy"

String selectedMonth = new SimpleDateFormat("MM-yyyy",


[Link]()).format([Link]());

Log.d("Gastos", "Selecionando mês para totalCost: " + selectedMonth);

// Obtém o documento de custos do Firestore para o usuário e mês


específicos

[Link]("usuarios").document(userId).collection("gastos").document(
selectedMonth)

.get()

.addOnCompleteListener(task -> {

// Verifica se a tarefa foi concluída com sucesso

if ([Link]()) {
154

DocumentSnapshot document = [Link]();

if ([Link]()) {

Object totalCostObj = [Link](selectedMonth);

double totalCost = 0;

// Converte o valor obtido para um double

if (totalCostObj instanceof Number) {

totalCost = ((Number) totalCostObj).doubleValue();

} else if (totalCostObj instanceof String) {

try {

totalCost = [Link]((String) totalCostObj);

} catch (NumberFormatException e) {

Log.e("Gastos", "Formato de número inválido para


totalCost", e);

// Formata o custo total para exibição

String formattedValue = [Link](totalCost);

// Atualiza o TextView com o custo total formatado

runOnUiThread(() -> [Link]("GASTOS: " +


formattedValue));

} else {

// Atualiza o TextView com custo total de 0 se o documento


não existir
155

runOnUiThread(() -> [Link]("GASTOS: " +


[Link](0)));

} else {

// Loga o erro caso a tarefa falhe

Log.e("Gastos", "Erro ao obter totalCost", [Link]());

// Oculta o overlay de carregamento

hideLoadingOverlay();

});

private void displayTotalCost(double totalCost) {

// Formata o custo total para exibição

String formattedTotalCost = [Link](totalCost);

// Encontra o TextView pelo ID

TextView totalCostTextView = findViewById([Link]);

// Atualiza o TextView com o custo total formatado

[Link]("Gasto: " + formattedTotalCost);

private void showLoadingOverlay() {


156

// Encontra a view que representa o overlay de carregamento usando o


ID fornecido

View loadingOverlay = findViewById([Link]);

// Verifica se a view do overlay de carregamento não é nula

if (loadingOverlay != null) {

// Torna a view do overlay de carregamento visível

[Link]([Link]);

// Desativa a interação do usuário com o SwipeRefreshLayout

setUserInteractionEnabled(false);

private void hideLoadingOverlay() {

// Encontra a view que representa o overlay de carregamento usando o


ID fornecido

View loadingOverlay = findViewById([Link]);

// Verifica se a view do overlay de carregamento não é nula

if (loadingOverlay != null) {

// Torna a view do overlay de carregamento invisível

[Link]([Link]);

// Reativa a interação do usuário com o SwipeRefreshLayout

setUserInteractionEnabled(true);

}
157

private void setUserInteractionEnabled(boolean enabled) {

// Encontra o SwipeRefreshLayout e define se ele deve permitir interação


com o usuário

findViewById([Link]).setEnabled(enabled);

[Link]:

package [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];
158

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];
159

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

public class Inicio extends AppCompatActivity {

private DrawerLayout drawerLayout;

private NavigationView navigationView;

private FirebaseAuth mAuth;

private FirebaseFirestore db;


160

private TextView textViewName;

private ViewFlipper viewFlipper;

private LinearLayout indicatorLayout;

private DecimalFormat currencyFormat;

private LinearLayout cardsLayout;

private SwipeRefreshLayout swipeRefreshLayout;

private static final String TAG = "FirebaseTen";

@Override

protected void onCreate(Bundle savedInstanceState) {

[Link](savedInstanceState);

[Link](this);

// Verifica se há conexão com a internet

if (!isInternetAvailable()) {

// Se não houver internet, exibe um diálogo informando ao usuário

showNoInternetDialog();

} else {

// Se houver conexão, continua o fluxo de inicialização

// Define o layout da atividade

setContentView([Link].activity_inicio);
161

// Inicializa instâncias do FirebaseAuth e FirebaseFirestore

mAuth = [Link]();

db = [Link]();

// Verifica se o usuário está autenticado

if ([Link]() == null) {

// Se não estiver autenticado, redireciona para a tela de login e


encerra a atividade atual

startActivity(new Intent([Link], [Link]));

finish();

return;

// Inicializa as views da interface do usuário

textViewName = findViewById([Link].textView4);

cardsLayout = findViewById([Link]);

swipeRefreshLayout = findViewById([Link]);

viewFlipper = findViewById([Link]);

indicatorLayout = findViewById([Link]);

// Configura os elementos da interface

fetchUserData();

setupDrawer();

setupCards();
162

setupViewFlipper();

// Configura o listener para o SwipeRefreshLayout

[Link](this::setupCards);

// Configura o ajuste dos insets de janela para a view principal

[Link](findViewById([Link]
n), (v, insets) -> {

Insets systemBars =
[Link]([Link]());

[Link]([Link], [Link], [Link],


[Link]);

return insets;

});

// Configura o formato de moeda para exibição

DecimalFormatSymbols symbols = new DecimalFormatSymbols();

[Link](',');

[Link]('.');

currencyFormat = new DecimalFormat("R$ #,##0.00", symbols);

// Configura novamente os cartões, aparentemente isso é redundante

setupCards();

// Configura o listener para o SwipeRefreshLayout novamente


(redundante)
163

[Link](this::setupCards);

// Intervalo em milissegundos para o auto-flip do ViewFlipper

private static final long AUTO_FLIP_INTERVAL = 5000;

// Handler para gerenciar a execução de tarefas com atraso

private final Handler autoFlipHandler = new Handler();

// Runnable que define a tarefa a ser executada repetidamente

private Runnable autoFlipRunnable;

// Configuração do ViewFlipper

private void setupViewFlipper() {

// Cria uma escuta para as mudanças na coleção "dicas" do banco de


dados

[Link]("dicas")

.orderBy("ordem", [Link]) // Ordena as dicas


pela ordem crescente

.addSnapshotListener((snapshots, e) -> {

// Verifica se houve um erro na escuta

if (e != null) {

Log.e("Inicio", "Erro ao escutar dicas", e);

[Link]([Link], "Erro ao carregar dicas",


Toast.LENGTH_SHORT).show();

return;
164

// Se há mudanças na coleção

if (snapshots != null) {

// Recupera as dicas notificadas e a última dica notificada das


preferências compartilhadas

SharedPreferences prefs =
getSharedPreferences("dicas_prefs", MODE_PRIVATE);

Set<String> notifiedDicas = [Link]("notified_dicas",


new HashSet<>());

String lastNotifiedDicaId =
[Link]("last_notified_dica_id", null);

// Mapeia as visualizações de dica existentes no ViewFlipper

Map<String, View> dicaViews = new HashMap<>();

for (int i = 0; i < [Link](); i++) {

View view = [Link](i);

TextView dicaTextView =
[Link]([Link]);

if (dicaTextView != null) {

[Link]([Link]().toString(), view);

boolean newDicaAdded = false;

String newLastDicaId = null;


165

String newLastDicaTexto = null;

String newLastDicaLink = null;

// Itera sobre as mudanças nos documentos

for (DocumentChange dc : [Link]())


{

DocumentSnapshot document = [Link]();

String dicaId = [Link]();

String dicaTexto = [Link]("texto");

String dicaLink = [Link]("link");

// Se a dica é nova e não foi notificada antes

if (dicaId != null && dicaTexto != null) {

if ([Link]() == [Link]) {

newLastDicaId = dicaId;

newLastDicaTexto = dicaTexto;

newLastDicaLink = dicaLink;

// Se a dica ainda não foi notificada e não existe no


ViewFlipper

if (![Link](dicaId) && !
[Link](dicaTexto)) {

// Infla a nova visualização de dica e a adiciona ao


ViewFlipper

View cardView =
getLayoutInflater().inflate([Link].card_dica, null);
166

TextView dicaTextView =
[Link]([Link]);

[Link](dicaTexto);

// Configura o clique no card da dica para abrir o link

[Link](v -> {

if (dicaLink != null && ![Link]()) {

Intent intent = new Intent(Intent.ACTION_VIEW,


[Link](dicaLink));

startActivity(intent);

} else {

// Handle empty link case if necessary

});

[Link](cardView);

// Adiciona um indicador para a nova dica

ImageView indicator = new ImageView(this);

[Link]([Link].indicator_in
active);

[Link](8, 8, 8, 8);

[Link](indicator);

newDicaAdded = true;
167

// Envia notificação para a nova dica se ela for diferente da


última notificada

if (newLastDicaId != null && !


[Link](lastNotifiedDicaId)) {

sendNotification(newLastDicaTexto, newLastDicaId);

[Link](newLastDicaId);

// Atualiza as preferências compartilhadas com as novas


dicas notificadas

[Link] editor = [Link]();

[Link]("notified_dicas", notifiedDicas);

[Link]("last_notified_dica_id", newLastDicaId);

[Link]();

// Se novas dicas foram adicionadas, atualiza os indicadores e


inicia o auto-flip

if (newDicaAdded) {

updateIndicators([Link]());

startAutoFlip();

}
168

// Configura os botões de navegação

ImageButton prevButton = findViewById([Link]);

ImageButton nextButton = findViewById([Link]);

// Configura o clique para mostrar a dica anterior

[Link](v -> {

[Link]();

updateIndicators([Link]());

resetAutoFlip();

});

// Configura o clique para mostrar a próxima dica

[Link](v -> {

[Link]();

updateIndicators([Link]());

resetAutoFlip();

});

// Configura o toque para deslizar entre as dicas

[Link](new
OnSwipeTouchListener(this) {

@Override

public void onSwipeLeft() {

[Link]();
169

updateIndicators([Link]());

resetAutoFlip();

@Override

public void onSwipeRight() {

[Link]();

updateIndicators([Link]());

resetAutoFlip();

});

} else {

// Loga e exibe uma mensagem caso nenhuma dica seja


encontrada

Log.e("Inicio", "Dicas não encontradas");

[Link]([Link], "Nenhuma dica encontrada",


Toast.LENGTH_SHORT).show();

});

private void sendNotification(String dica, String dicaId) {

// Obtém o serviço de notificações do sistema


170

NotificationManager notificationManager = (NotificationManager)


getSystemService(Context.NOTIFICATION_SERVICE);

// Define o ID do canal de notificação

String channelId = "dica_channel";

// Verifica se a versão do Android é Oreo (API 26) ou superior para criar


um canal de notificação

if ([Link].SDK_INT >= Build.VERSION_CODES.O) {

// Cria um canal de notificação com alta importância

NotificationChannel channel = new NotificationChannel(channelId,


"Dicas Channel", NotificationManager.IMPORTANCE_HIGH);

[Link](channel);

// Cria um Intent que será acionado quando a notificação for clicada

Intent intent = new Intent(this, [Link]);

[Link]("dica_extra", dica); // Adiciona a dica como um extra no


Intent

[Link](Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP); // Configura flags para evitar múltiplas
instâncias

// Cria um PendingIntent para a notificação

PendingIntent pendingIntent = [Link](

this,
171

[Link](), // Usando hashCode do ID da dica para a chave


do PendingIntent

intent,

PendingIntent.FLAG_UPDATE_CURRENT |
PendingIntent.FLAG_MUTABLE // Permite atualizar o PendingIntent e torna-o
mutável

);

// Cria um construtor para a notificação

[Link] builder = new [Link](this,


channelId)

.setSmallIcon([Link]) // Ícone pequeno da


notificação

.setContentTitle("Nova notificação!") // Título da notificação

.setContentText(dica) // Texto da notificação

.setPriority(NotificationCompat.PRIORITY_HIGH) // Define a
prioridade da notificação como alta

.setContentIntent(pendingIntent) // Configura o PendingIntent que


será acionado quando a notificação for clicada

.setAutoCancel(true); // A notificação será removida ao ser clicada

// Loga a notificação que está sendo enviada

Log.d("Notification", "Sending notification with dica: " + dica);

// Exibe a notificação

[Link]([Link](), [Link]());
172

private void startAutoFlip() {

// Define o Runnable que será executado repetidamente para o auto-flip

autoFlipRunnable = new Runnable() {

@Override

public void run() {

[Link](); // Exibe a próxima dica no ViewFlipper

updateIndicators([Link]()); // Atualiza os
indicadores para a dica exibida

[Link](this, AUTO_FLIP_INTERVAL); //
Reagenda o Runnable para ser executado novamente após o intervalo

};

// Inicia o auto-flip com o intervalo definido

[Link](autoFlipRunnable,
AUTO_FLIP_INTERVAL);

private void resetAutoFlip() {

// Remove o Runnable atual da fila de execução

[Link](autoFlipRunnable);

// Reinicia o auto-flip
173

startAutoFlip();

public class OnSwipeTouchListener implements [Link] {

private static final int SWIPE_THRESHOLD = 100; // Limiar para


considerar um movimento como swipe

private static final int SWIPE_VELOCITY_THRESHOLD = 100; // Limiar


de velocidade para considerar um movimento como swipe

private final GestureDetector gestureDetector; // Detector de gestos

private float startX; // Posição X inicial do toque

private float startY; // Posição Y inicial do toque

private boolean isSwiping; // Flag para verificar se o usuário está


deslizando

// Construtor que inicializa o GestureDetector com um GestureListener

public OnSwipeTouchListener(Context context) {

gestureDetector = new GestureDetector(context, new


GestureListener());

@Override

public boolean onTouch(View v, MotionEvent event) {

switch ([Link]()) {

case MotionEvent.ACTION_DOWN:

// Captura a posição inicial do toque


174

startX = [Link]();

startY = [Link]();

isSwiping = false;

break;

case MotionEvent.ACTION_MOVE:

// Calcula o deslocamento e verifica se o movimento é um swipe

float dx = [Link]() - startX;

float dy = [Link]() - startY;

if ([Link](dx) > SWIPE_THRESHOLD && [Link](dx) >


[Link](dy)) {

isSwiping = true;

break;

case MotionEvent.ACTION_UP:

// Se for um swipe, usa o GestureDetector para lidar com o gesto

if (isSwiping) {

[Link](event);

break;

return true;

// Classe interna para lidar com gestos


175

private final class GestureListener extends


[Link] {

@Override

public boolean onDown(MotionEvent e) {

return true; // Necessário para que o gesto de fling funcione

@Override

public boolean onFling(MotionEvent e1, MotionEvent e2, float


velocityX, float velocityY) {

// Calcula a diferença e a velocidade do movimento

float diffX = [Link]() - [Link]();

float diffY = [Link]() - [Link]();

// Verifica se o movimento é horizontal e atende aos critérios de


swipe

if ([Link](diffX) > [Link](diffY)) {

if ([Link](diffX) > SWIPE_THRESHOLD &&


[Link](velocityX) > SWIPE_VELOCITY_THRESHOLD) {

if (diffX > 0) {

onSwipeRight(); // Detecção de swipe para a direita

} else {

onSwipeLeft(); // Detecção de swipe para a esquerda

return true;

}
176

return false;

// Métodos para serem sobrescritos conforme necessário

public void onSwipeLeft() {

public void onSwipeRight() {

private void updateIndicators(int position) {

// Obtém o número total de indicadores no layout

int count = [Link]();

// Itera sobre todos os indicadores

for (int i = 0; i < count; i++) {

// Obtém o indicador atual da lista de filhos do layout

ImageView indicator = (ImageView) [Link](i);

// Verifica se o índice do indicador atual é igual à posição fornecida

if (i == position) {

// Se for o indicador ativo, define o recurso de imagem como


indicador ativo

[Link]([Link].indicator_active);
177

} else {

// Caso contrário, define o recurso de imagem como indicador


inativo

[Link]([Link].indicator_inactive);

private void fetchUserData() {

showLoadingOverlay(); // Mostra um overlay de carregamento enquanto


obtém dados do usuário

String userId = [Link]().getUid(); // Obtém o ID do


usuário autenticado

// Obtém o documento do usuário da coleção "usuarios" usando o ID do


usuário

[Link]("usuarios").document(userId).get()

.addOnCompleteListener(task -> {

hideLoadingOverlay(); // Esconde o overlay de carregamento


após a operação ser concluída

// Verifica se a operação foi bem-sucedida

if ([Link]()) {

DocumentSnapshot document = [Link]();

if ([Link]()) {
178

// Se o documento existe, obtém o nome do usuário

String nome = [Link]("nome");

if (nome != null) {

// Atualiza o TextView e o item de logout com o nome do


usuário

[Link]("Olá, " + nome + "!");

MenuItem logoutItem =
[Link]().findItem([Link]);

[Link]("Não é " + nome + "?");

} else {

// Se o nome não está disponível, exibe uma mensagem


padrão

[Link]("Olá!");

MenuItem logoutItem =
[Link]().findItem([Link]);

[Link]("Logout");

} else {

// Se o documento não existe, exibe uma mensagem padrão

[Link]("Olá!");

MenuItem logoutItem =
[Link]().findItem([Link]);

[Link]("Logout");

} else {
179

// Se houve um erro na operação, exibe uma mensagem


padrão e loga o erro

[Link]("Olá!");

Log.e("Inicio", "Erro ao obter dados do usuário",


[Link]());

MenuItem logoutItem =
[Link]().findItem([Link]);

[Link]("Logout");

});

private void setupDrawer() {

// Obtém referências para o DrawerLayout e o NavigationView

drawerLayout = findViewById([Link].drawer_layout);

navigationView = findViewById([Link].nav_view);

// Cria um ActionBarDrawerToggle para sincronizar o estado do drawer


com o botão de navegação

ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(

this, drawerLayout, [Link].navigation_drawer_open,


[Link].navigation_drawer_close);

[Link](toggle); // Adiciona o listener ao


DrawerLayout
180

[Link](); // Sincroniza o estado do drawer com o botão de


navegação

// Configura o listener para os itens do menu de navegação

[Link](item -> {

int id = [Link]();

// Verifica o ID do item selecionado e executa a ação correspondente

if (id == [Link].nav_item_one) {

// Navega para a atividade Dados

Intent intent = new Intent([Link], [Link]);

startActivity(intent);

} else if (id == [Link].nav_item_two) {

// Navega para a atividade Gastos

Intent intent = new Intent([Link], [Link]);

startActivity(intent);

} else if (id == [Link]) {

// Faz logout do usuário, limpa a preferência de login e navega para


a tela de login

[Link]();

[Link] editor =
getSharedPreferences("PrefsFile", MODE_PRIVATE).edit();

[Link]("isLoggedIn", false);

[Link]();

startActivity(new Intent([Link], [Link]));


181

finish(); // Encerra a atividade atual

// Fecha o drawer após a seleção do item

[Link]([Link]);

return true;

});

private void fetchTotalCost() {

// Obtém o ID do usuário autenticado

String userId = [Link]().getCurrentUser().getUid();

// Obtém a instância do Firebase Firestore

FirebaseFirestore db = [Link]();

// Obtém a data atual e formata o mês e ano no formato "MM-yyyy"

Calendar calendar = [Link]();

SimpleDateFormat sdf = new SimpleDateFormat("MM-yyyy",


[Link]());

String selectedMonth = [Link]([Link]());

// Obtém o documento correspondente ao mês atual na subcoleção


"gastos" do usuário

[Link]("usuarios").document(userId).collection("gastos").document(
selectedMonth)
182

.get()

.addOnCompleteListener(task -> {

// Verifica se a tarefa foi bem-sucedida

if ([Link]()) {

DocumentSnapshot document = [Link]();

// Verifica se o documento existe

if ([Link]()) {

// Obtém o valor do campo "Total" do documento

Object totalCostObj = [Link]("Total");

double monthlyCost = 0;

// Converte o valor do campo "Total" para um tipo numérico


(double)

if (totalCostObj instanceof Number) {

monthlyCost = ((Number) totalCostObj).doubleValue();

} else if (totalCostObj instanceof String) {

try {

monthlyCost = [Link]((String)
totalCostObj);

} catch (NumberFormatException e) {

// Loga um erro caso a conversão do String para double


falhe

Log.e("Inicio", "Formato de número inválido para


totalCost", e);

}
183

// Formata o valor para exibição em formato de moeda

String formattedValue =
[Link](monthlyCost);

// Atualiza o TextView com o valor formatado na UI thread

runOnUiThread(() -> {

TextView totalValueTextView =
findViewById([Link].textView5);

if (totalValueTextView != null) {

[Link](formattedValue);

} else {

// Loga um erro se o TextView com o ID especificado


não for encontrado

Log.e("Inicio", "TextView com ID textView5 não


encontrado");

});

// Loga o custo do mês recuperado

Log.d("Inicio", "Custo do mês recuperado: " +


formattedValue);

} else {

// Loga um aviso se o documento para o mês especificado


não for encontrado

Log.d("Inicio", "Documento para o mês " + selectedMonth + "


não encontrado");
184

// Atualiza o TextView com um valor padrão ("R$ 00,00") na


UI thread

runOnUiThread(() -> {

TextView totalValueTextView =
findViewById([Link].textView5);

if (totalValueTextView != null) {

[Link]("R$ 00,00");

});

} else {

// Loga um erro se a tarefa falhar ao obter o custo mensal

Log.e("Inicio", "Erro ao obter custo mensal",


[Link]());

// Exibe uma mensagem de erro para o usuário na UI thread

runOnUiThread(() -> {

[Link](this, "Erro ao carregar custo do mês",


Toast.LENGTH_SHORT).show();

});

});

private void setupCards() {

// Mostra um overlay de carregamento enquanto busca os dados


185

showLoadingOverlay();

// Obtém o ID do usuário autenticado

String userId = [Link]().getUid();

// Obtém a data atual e formata o mês e ano no formato "MM-yyyy"

Calendar calendar = [Link]();

SimpleDateFormat sdf = new SimpleDateFormat("MM-yyyy",


[Link]());

String mesAnoAtual = [Link]([Link]());

// Consulta a coleção de dispositivos do usuário para o mês atual

[Link]("usuarios").document(userId)

.collection("dispositivos").document(mesAnoAtual)

.collection("dispositivos").get()

.addOnCompleteListener(task -> {

// Esconde o overlay de carregamento após a consulta

hideLoadingOverlay();

// Verifica se a consulta foi bem-sucedida

if ([Link]()) {

// Remove todas as visualizações atuais do layout

[Link]();
186

// Inicializa variáveis para armazenar o custo total e a


contagem de cartões

double totalCost = 0;

int cardCount = 0;

// Cria um layout horizontal para os cartões

LinearLayout rowLayout = new LinearLayout(this);

[Link]([Link]);

// Define os parâmetros de layout para o rowLayout

[Link] layoutParams = new


[Link](

[Link].MATCH_PARENT,

[Link].WRAP_CONTENT);

// Define a margem dos cartões

int margin = (int) (24 *


getResources().getDisplayMetrics().density);

[Link](margin, 0, margin, 0);

// Aplica os parâmetros de layout ao rowLayout

[Link](layoutParams);

// Adiciona o rowLayout ao cardsLayout

[Link](rowLayout);
187

// Itera sobre os documentos retornados pela consulta

for (DocumentSnapshot document : [Link]()) {

// Obtém o nome do dispositivo, se não disponível define um


padrão

String nome = [Link]("Nome");

if (nome == null) {

nome = "Nome não disponível";

// Obtém a URL da imagem, se não disponível define um


valor padrão

String imagemUrl = [Link]("ImagemUrl");

if (imagemUrl == null) {

imagemUrl = "";

// Obtém a quantidade, se não disponível define um valor


padrão

Object quantidadeObj = [Link]("Quantidade");

String quantidade = (quantidadeObj instanceof Number) ?


[Link]() : "Não disponível";

// Infla o layout do cartão e obtém referências para os


componentes
188

View card = getLayoutInflater().inflate([Link].card_layout,


cardsLayout, false);

TextView cardTitle = [Link]([Link]);

TextView cardValue = [Link]([Link]);

ImageView cardImage = [Link]([Link]);

// Define o nome do dispositivo no TextView

[Link](nome);

// Obtém e formata o custo mensal do dispositivo

Object custoObj = [Link]("CustoMensal");

double custoValue = (custoObj instanceof Number) ?


((Number) custoObj).doubleValue() : 0;

String formattedValue = [Link](custoValue);

[Link](formattedValue);

// Adiciona o custo ao total

totalCost += custoValue;

// Carrega a imagem do dispositivo com Glide

[Link]([Link])

.load(imagemUrl)

.placeholder([Link])

.into(cardImage);
189

// Obtém a potência, se não disponível define um valor


padrão

Object potenciaObj = [Link]("Potência");

final String potenciaString = (potenciaObj instanceof


Number) ? [Link]() : "Não disponível";

// Obtém o tempo de uso, tratando diferentes tipos de dados

final String tempoString;

Object tempoObj = [Link]("Tempo");

if (tempoObj instanceof String) {

tempoString = (String) tempoObj;

} else if (tempoObj instanceof Number) {

tempoString = [Link](((Number)
tempoObj).intValue());

} else if (tempoObj != null) {

tempoString = [Link]();

} else {

tempoString = "Não disponível";

// Obtém o ID do dispositivo

final String dispositivoId = [Link]();

String finalImagemUrl = imagemUrl;

String finalNome = nome;


190

// Define o comportamento ao clicar no cartão

[Link](v -> {

// Cria uma Intent para abrir a tela Dispositivo com os


detalhes do dispositivo

Intent intent = new Intent([Link], [Link]);

[Link]("ID", dispositivoId);

[Link]("NOME", finalNome);

[Link]("POTENCIA", potenciaString);

[Link]("TEMPO", tempoString);

[Link]("GASTO", custoObj != null ?


[Link]() : "Não disponível");

[Link]("IMAGEM", finalImagemUrl);

[Link]("UNIDADE_TEMPO",
[Link]("UnidadeTempo"));

[Link]("QUANTIDADE", quantidade);

// Adiciona outros dados do dispositivo à Intent

[Link]("CUSTO_DIARIO",
[Link]("CustoDiario"));

[Link]("CUSTO_DIARIO_KWh",
[Link]("GastoDiariwh"));

[Link]("CUSTO_MENSAL",
[Link]("CustoMensal"));

[Link]("CUSTO_MENSAL_KWh",
[Link]("GastoMensalKwh"));
191

// Inicia a atividade Dispositivo

startActivity(intent);

});

// Adiciona o cartão ao layout

[Link](card);

cardCount++;

// Se a quantidade de cartões é par, cria uma nova linha

if (cardCount % 2 == 0) {

rowLayout = new LinearLayout(this);

[Link]([Link]);

[Link](layoutParams);

[Link](rowLayout);

// Adiciona um botão para adicionar novos dispositivos

View addButton = getLayoutInflater().inflate([Link].card_add,


cardsLayout, false);

ImageButton addButtonImage =
[Link]([Link]);

[Link]([Link]);

[Link](v -> {
192

// Verifica a conexão com a internet antes de abrir a tela de


adicionar dispositivos

if (isInternetAvailable()) {

Intent intent = new Intent([Link],


Adicionando_dispositivos.class);

startActivity(intent);

} else {

[Link]([Link], "Sem conexão com a internet.


Verifique sua conexão e tente novamente.", Toast.LENGTH_LONG).show();

});

// Adiciona o botão de adicionar dispositivos à última linha

[Link](addButton);

// Atualiza o custo mensal total

updateMonthlyCost(userId, totalCost);

// Busca e atualiza o custo total do mês

fetchTotalCost();

// Busca e atualiza o custo mensal

fetchMonthlyCost();

// Loga uma mensagem se nenhum dispositivo for encontrado


193

if ([Link]().isEmpty()) {

Log.d("Inicio", "Nenhum dispositivo encontrado para o mês


atual");

} else {

// Loga um erro e mostra uma mensagem caso a tarefa falhe

Log.e("Inicio", "Erro ao obter dispositivos", [Link]());

[Link]([Link], "Erro ao carregar dispositivos",


Toast.LENGTH_SHORT).show();

// Para a animação de carregamento do SwipeRefreshLayout

[Link](false);

});

private void fetchMonthlyCost() {

// Obtém o ID do usuário autenticado

String userId = [Link]().getCurrentUser().getUid();

// Obtém uma instância do Firestore

FirebaseFirestore db = [Link]();

// Obtém a data atual e formata o mês e ano no formato "MM-yyyy"

Calendar calendar = [Link]();

SimpleDateFormat sdf = new SimpleDateFormat("MM-yyyy",


[Link]());
194

String mesAno = [Link]([Link]());

// Consulta o documento referente ao mês atual na coleção "gastos"

[Link]("usuarios").document(userId).collection("gastos").document(
mesAno)

.get()

.addOnCompleteListener(task -> {

// Verifica se a consulta foi bem-sucedida

if ([Link]()) {

// Obtém o resultado da consulta

DocumentSnapshot document = [Link]();

if ([Link]()) {

// Obtém o custo mensal do documento

Double monthlyCost = [Link](mesAno);

if (monthlyCost == null) {

// Define o custo como 0.0 se não estiver disponível

monthlyCost = 0.0;

// Formata o valor do custo mensal

String formattedValue =
[Link](monthlyCost);

// Atualiza a UI na thread principal com o custo formatado

runOnUiThread(() -> {
195

TextView totalValueTextView =
findViewById([Link].textView5);

if (totalValueTextView != null) {

[Link](formattedValue);

} else {

Log.e("Inicio", "TextView com ID textView5 não


encontrado");

});

// Loga o custo do mês recuperado

Log.d("Inicio", "Custo do mês recuperado: " +


formattedValue);

} else {

// Loga uma mensagem se o documento não for encontrado

Log.d("Inicio", "Documento 'total' não encontrado");

runOnUiThread(() -> {

TextView totalValueTextView =
findViewById([Link].textView5);

if (totalValueTextView != null) {

[Link]("R$ 00,00");

});

} else {

// Loga um erro e mostra uma mensagem se a tarefa falhar


196

Log.e("Inicio", "Erro ao obter custo mensal",


[Link]());

runOnUiThread(() -> {

[Link](this, "Erro ao carregar custo do mês",


Toast.LENGTH_SHORT).show();

});

});

private void updateMonthlyCost(String userId, double monthlyCost) {

// Obtém a data atual e formata o mês e ano no formato "MM-yyyy"

Calendar calendar = [Link]();

SimpleDateFormat sdf = new SimpleDateFormat("MM-yyyy",


[Link]());

String mesAno = [Link]([Link]());

// Cria um mapa com o custo mensal para atualizar o documento

Map<String, Object> updates = new HashMap<>();

[Link](mesAno, monthlyCost);

// Obtém uma instância do Firestore

FirebaseFirestore db = [Link]();

// Atualiza o documento com o custo mensal


197

[Link]("usuarios").document(userId).collection("gastos").document(
mesAno)

.set(updates, [Link]())

.addOnSuccessListener(aVoid -> Log.d("Inicio", "Custo mensal


salvo com sucesso"))

.addOnFailureListener(e -> {

// Loga um erro e mostra uma mensagem se a operação falhar

Log.e("Inicio", "Erro ao salvar custo mensal", e);

[Link]([Link], "Erro ao salvar custo mensal",


Toast.LENGTH_SHORT).show();

});

public void openDispositivosActivity(String dispositivoId) {

// Cria um Intent para iniciar a atividade Dispositivo

Intent intent = new Intent(this, [Link]);

// Adiciona o ID do dispositivo como um extra no Intent

[Link]("ID", dispositivoId);

// Inicia a atividade

startActivity(intent);

public void openGastosActivity(View view) {

// Cria um Intent para iniciar a atividade Gastos


198

Intent intent = new Intent(this, [Link]);

// Inicia a atividade

startActivity(intent);

public void openAdicionandoDispositivosActivity(View view) {

// Cria um Intent para iniciar a atividade Adicionando_dispositivos

Intent intent = new Intent(this, Adicionando_dispositivos.class);

// Adiciona um extra ao Intent para indicar que os cartões devem ser


atualizados

[Link]("UPDATE_CARDS", true);

// Inicia a atividade

startActivity(intent);

private void setUserInteractionEnabled(boolean enabled) {

// Obtém a referência para o view principal que pode ser usada para
bloquear interação do usuário

View mainContent = findViewById([Link]);

if (mainContent != null) {

// Configura se o view principal deve ser clicável e focável, baseado no


parâmetro 'enabled'

[Link](!enabled);

[Link](!enabled);
199

[Link](!enabled);

private void showLoadingOverlay() {

// Obtém a referência para o overlay de carregamento

View loadingOverlay = findViewById([Link]);

if (loadingOverlay != null) {

// Torna o overlay visível

[Link]([Link]);

private void hideLoadingOverlay() {

// Obtém a referência para o overlay de carregamento

View loadingOverlay = findViewById([Link]);

if (loadingOverlay != null) {

// Oculta o overlay

[Link]([Link]);

private boolean isInternetAvailable() {

// Obtém o gerenciador de conectividade


200

ConnectivityManager cm = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);

// Obtém as informações da rede ativa

NetworkInfo activeNetwork = [Link]();

// Verifica se a rede está conectada ou se está em processo de conexão

return activeNetwork != null &&


[Link]();

private void showNoInternetDialog() {

new [Link](this)

.setTitle("Sem Conexão com a Internet")

.setMessage("Você precisa de uma conexão com a internet para


acessar o app.")

.setCancelable(false)

.setPositiveButton("Tentar novamente", new


[Link]() {

@Override

public void onClick(DialogInterface dialog, int which) {

// Reinicia a atividade atual para tentar reconectar

recreate();

})

.setNegativeButton("Fechar", new [Link]()


{

@Override
201

public void onClick(DialogInterface dialog, int which) {

// Encerra a atividade

finish();

})

.show();

public void openDrawer(View view) {

// Abre o menu de navegação (drawer) do layout

[Link]([Link]);

[Link]:

package [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];
202

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

public class Login extends AppCompatActivity {


203

private EditText emailEditText;

private EditText passwordEditText;

private ImageButton togglePasswordVisibilityButton;

private boolean isPasswordVisible = false;

private FirebaseAuth mAuth;

private SharedPreferences sharedPreferences;

private static final String PREFS_NAME = "PrefsFile";

private ProgressBar progressBar;

private static final int REQUEST_CODE_NOTIFICATION_PERMISSION =


1;

@Override

protected void onCreate(Bundle savedInstanceState) {

[Link](savedInstanceState);

// Define o layout da atividade como activity_login

setContentView([Link].activity_login);

// Verifica se a permissão para exibir notificações foi concedida

if ([Link](this,
[Link].POST_NOTIFICATIONS)

!= PackageManager.PERMISSION_GRANTED) {

// Se a permissão não foi concedida, solicita ao usuário a permissão


204

[Link](this, new String[]


{[Link].POST_NOTIFICATIONS},

REQUEST_CODE_NOTIFICATION_PERMISSION);

} else {

// Se a permissão já foi concedida, não faz nada (pode adicionar


código se necessário)

// Inicializa o FirebaseAuth e SharedPreferences

mAuth = [Link]();

sharedPreferences = getSharedPreferences(PREFS_NAME,
MODE_PRIVATE);

// Verifica se o usuário já está autenticado

if ([Link]() != null) {

// Se o usuário já estiver autenticado, redireciona para a atividade


Inicio

startActivity(new Intent([Link], [Link]));

// Encerra a atividade de login

finish();

// Inicializa os componentes da interface do usuário

emailEditText = findViewById([Link]);

passwordEditText = findViewById([Link].editTextTextPassword2);
205

togglePasswordVisibilityButton =
findViewById([Link]);

// Configura o botão para alternar a visibilidade da senha

[Link](v -> {

if (isPasswordVisible) {

// Se a senha está visível, oculta a senha

[Link](InputType.TYPE_CLASS_TEXT |
InputType.TYPE_TEXT_VARIATION_PASSWORD);

[Link]([Link]
aver);

} else {

// Se a senha está oculta, torna a senha visível

[Link](InputType.TYPE_CLASS_TEXT |
InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);

[Link]([Link]
aocultar);

// Move o cursor para o final do texto da senha

[Link]([Link]().length());

// Alterna o estado da visibilidade da senha

isPasswordVisible = !isPasswordVisible;

});

// Configura o botão de login

findViewById([Link].button3).setOnClickListener(v -> {
206

// Obtém o e-mail e a senha dos campos de texto

String email = [Link]().toString().trim();

String senha = [Link]().toString().trim();

if (![Link]() && ![Link]()) {

if (isConnectedToInternet()) {

// Mostra a sobreposição de carregamento enquanto a


autenticação está em progresso

showLoadingOverlay();

// Tenta fazer login com e-mail e senha

[Link](email, senha)

.addOnCompleteListener(task -> {

// Oculta a sobreposição de carregamento quando a


autenticação for concluída

hideLoadingOverlay();

if ([Link]()) {

// Se a autenticação for bem-sucedida, salva o estado


de login e redireciona para a atividade Inicio

[Link] editor =
[Link]();

[Link]("isLoggedIn", true);

[Link]();

startActivity(new Intent([Link], [Link]));

finish();
207

} else {

// Se a autenticação falhar, mostra uma mensagem de


erro

[Link]([Link], "Verifique e-mail e senha e


tente novamente.", Toast.LENGTH_LONG).show();

});

} else {

// Se não houver conexão com a internet, mostra uma mensagem


de erro

[Link]([Link], "Sem conexão com a internet.


Verifique sua conexão e tente novamente.", Toast.LENGTH_LONG).show();

} else {

// Se os campos de e-mail ou senha estiverem vazios, mostra uma


mensagem para preencher todos os campos

[Link]([Link], "Por favor, preencha todos os campos.",


Toast.LENGTH_SHORT).show();

});

// Configura os TextViews para cadastro e recuperação de senha

setupCadastroTextView();

setupEsqueceuSenhaTextView();

// Configura o TextView para redefinir a senha


208

TextView resetPasswordTextView = findViewById([Link].textView4);

[Link](v -> {

// Obtém o e-mail do campo de texto

String email = [Link]().toString().trim();

if (![Link]()) {

// Tenta enviar um e-mail de redefinição de senha

[Link](email)

.addOnCompleteListener(task -> {

if ([Link]()) {

// Se o e-mail de redefinição for enviado com sucesso,


mostra uma mensagem de sucesso

[Link]([Link], "Email de redefinição de


senha enviado.", Toast.LENGTH_SHORT).show();

} else {

// Se houver um erro ao enviar o e-mail de redefinição,


mostra uma mensagem de erro

[Link]([Link], "Erro ao enviar email de


redefinição.", Toast.LENGTH_SHORT).show();

});

} else {

// Se o campo de e-mail estiver vazio, mostra uma mensagem para


inserir o e-mail

[Link]([Link], "Por favor, insira seu email para


redefinir a senha.", Toast.LENGTH_SHORT).show();

}
209

});

@Override

public void onRequestPermissionsResult(int requestCode, @NonNull


String[] permissions, @NonNull int[] grantResults) {

[Link](requestCode, permissions,
grantResults);

// Verifica se a permissão solicitada é a de notificações

if (requestCode == REQUEST_CODE_NOTIFICATION_PERMISSION) {

// Checa se a resposta da solicitação de permissão foi recebida

if ([Link] > 0 && grantResults[0] ==


PackageManager.PERMISSION_GRANTED) {

// Se a permissão foi concedida, exibe uma mensagem de sucesso

showToast("Permissão de notificações concedida.");

} else {

// Se a permissão foi negada, exibe uma mensagem de erro

showToast("Permissão de notificações negada.");

private void showToast(String message) {


210

// Configura o TextView para exibir um texto clicável que redireciona o


usuário para a tela de cadastro.

private void setupCadastroTextView() {

// Obtém o TextView pelo ID definido no layout.

TextView textViewCadastro = findViewById([Link].textView3);

// Obtém o texto atual do TextView.

String text = [Link]().toString();

// Cria um SpannableString a partir do texto para aplicar estilos.

SpannableString spannableString = new SpannableString(text);

// Encontra o início do texto que será estilizado.

int start = [Link]("Crie uma!");

if (start >= 0) {

// Calcula o fim do texto a ser estilizado.

int end = start + "Crie uma!".length();

// Aplica negrito ao texto encontrado.

[Link](new StyleSpan([Link]), start, end,


Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
211

// Aplica a cor verde ao texto encontrado.

[Link](new
ForegroundColorSpan([Link]("#228B22")), start, end,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

// Define uma ação de clique para o texto estilizado.

[Link](new ClickableSpan() {

@Override

public void onClick(@NonNull View widget) {

// Abre a Activity de cadastro ao clicar no texto.

startActivity(new Intent([Link], [Link]));

}, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

// Define o texto estilizado no TextView e habilita a capacidade de


clicar no texto.

[Link](spannableString);

[Link]([Link]
nce());

// Configura o TextView para exibir um texto clicável que permite ao usuário


redefinir a senha.

private void setupEsqueceuSenhaTextView() {

// Obtém o TextView pelo ID definido no layout.


212

TextView textViewSenhae = findViewById([Link].textView4);

// Obtém o texto atual do TextView.

String text = [Link]().toString();

// Cria um SpannableString a partir do texto para aplicar estilos.

SpannableString spannableString = new SpannableString(text);

// Encontra o início do texto que será estilizado.

int start = [Link]("Esqueceu a senha?");

if (start >= 0) {

// Calcula o fim do texto a ser estilizado.

int end = start + "Esqueceu a senha?".length();

// Aplica negrito ao texto encontrado.

[Link](new StyleSpan([Link]), start, end,


Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

// Aplica a cor verde ao texto encontrado.

[Link](new
ForegroundColorSpan([Link]("#228B22")), start, end,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

// Define uma ação de clique para o texto estilizado.

[Link](new ClickableSpan() {
213

@Override

public void onClick(@NonNull View widget) {

// Obtém o email inserido pelo usuário.

String email = [Link]().toString().trim();

// Verifica se o email não está vazio antes de enviar o pedido de


redefinição de senha.

if (![Link]()) {

[Link](email)

.addOnCompleteListener(task -> {

if ([Link]()) {

// Notifica o usuário que o email de redefinição foi


enviado com sucesso.

[Link]([Link], "Email de redefinição de


senha enviado.", Toast.LENGTH_SHORT).show();

} else {

// Notifica o usuário sobre um erro ao enviar o email.

[Link]([Link], "Erro ao enviar email de


redefinição.", Toast.LENGTH_SHORT).show();

});

} else {

// Notifica o usuário para inserir o email se o campo estiver


vazio.

[Link]([Link], "Por favor, insira seu email para


redefinir a senha.", Toast.LENGTH_SHORT).show();
214

}, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

// Define o texto estilizado no TextView e habilita a capacidade de


clicar no texto.

[Link](spannableString);

[Link]([Link]
ce());

// Remove a cor de destaque padrão ao clicar no texto.

[Link]([Link]);

@Override

public boolean onKeyDown(int keyCode, KeyEvent event) {

// Este método é chamado quando uma tecla é pressionada no


dispositivo.

if ((keyCode == KeyEvent.KEYCODE_BACK)) {

// Se a tecla pressionada for a tecla "Voltar", move a tarefa atual para o


fundo (background) em vez de sair do aplicativo.

moveTaskToBack(true);

return true; // Indica que o evento foi tratado e não deve ser propagado
para outras partes do sistema.

}
215

return [Link](keyCode, event); // Caso contrário, trata a tecla


normalmente, utilizando o comportamento padrão.

// Solicita foco no campo de email quando chamado.

public void focusEmailEditText(View view) {

// Solicita foco para o campo de email.

[Link]();

// Solicita foco no campo de senha quando chamado.

public void focusPasswordEditText(View view) {

// Solicita foco para o campo de senha.

[Link]();

// Exibe uma sobreposição de carregamento para indicar que uma


operação está em andamento.

private void showLoadingOverlay() {

// Obtém a visualização da sobreposição de carregamento pelo ID


definido no layout.

View loadingOverlay = findViewById([Link]);

if (loadingOverlay != null) {

// Torna a sobreposição visível.

[Link]([Link]);
216

// Desabilita a interação do usuário com a interface principal enquanto


a sobreposição está visível.

setUserInteractionEnabled(false);

// Oculta a sobreposição de carregamento quando a operação estiver


concluída.

private void hideLoadingOverlay() {

// Obtém a visualização da sobreposição de carregamento pelo ID


definido no layout.

View loadingOverlay = findViewById([Link]);

if (loadingOverlay != null) {

// Torna a sobreposição invisível.

[Link]([Link]);

// Habilita a interação do usuário com a interface principal após ocultar


a sobreposição.

setUserInteractionEnabled(true);

// Define se a interação do usuário com a interface deve ser habilitada ou


desabilitada.

private void setUserInteractionEnabled(boolean enabled) {


217

// Obtém a visualização da sobreposição de carregamento (ou qualquer


outra visualização usada para bloquear a interface).

View mainContent = findViewById([Link]);

if (mainContent != null) {

// Define se a visualização pode receber cliques, foco e foco em modo


de toque.

[Link](!enabled);

[Link](!enabled);

[Link](!enabled);

// Verifica se o dispositivo está conectado à Internet.

private boolean isConnectedToInternet() {

// Obtém o gerenciador de conectividade do sistema.

ConnectivityManager cm = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);

// Obtém informações sobre a rede ativa.

NetworkInfo activeNetwork = [Link]();

// Verifica se há uma rede ativa e se está conectada ou tentando se


conectar.

return activeNetwork != null &&


[Link]();

}
218

[Link]:

package [Link];

// Importações necessárias para o funcionamento da Activity

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

// Definição da classe Splash que estende AppCompatActivity

public class Splash extends AppCompatActivity {

// Método chamado quando a Activity é criada

@Override

protected void onCreate(Bundle savedInstanceState) {

[Link](savedInstanceState);

// Habilita o modo de tela cheia (Edge to Edge) para a Activity

[Link](this);
219

// Define o layout da Activity usando o arquivo de recursos XML


'activity_splash'

setContentView([Link].activity_splash);

// Configura um ouvinte para aplicar as margens do sistema de barras


(status e navegação)

[Link](findViewById([Link]),
(v, insets) -> {

// Obtém os insets das barras do sistema (status e navegação)

Insets systemBars =
[Link]([Link]());

// Define o padding da view principal para evitar sobreposição pelas


barras do sistema

[Link]([Link], [Link], [Link],


[Link]);

// Retorna os insets não modificados

return insets;

});

// Cria um Handler para iniciar a próxima Activity após um atraso de 500


milissegundos

new Handler().postDelayed(() -> {

// Cria uma nova Intent para iniciar a Activity de Login


220

Intent intent = new Intent([Link], [Link]);

// Inicia a Activity de Login

startActivity(intent);

// Finaliza a Activity Splash para que não possa ser retornada com o
botão de voltar

finish();

}, 500); // O atraso é de 500 milissegundos (0,5 segundos)

[Link]:

package [Link];

// Importações necessárias para o funcionamento da Activity

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];

import [Link];
221

import [Link];

import [Link];

// Definição da classe Termos que estende AppCompatActivity

public class Termos extends AppCompatActivity {

// Método chamado quando a Activity é criada

@Override

protected void onCreate(Bundle savedInstanceState) {

[Link](savedInstanceState);

// Habilita o modo de tela cheia (Edge to Edge) para a Activity

[Link](this);

// Define o layout da Activity usando o arquivo de recursos XML


'activity_termos'

setContentView([Link].activity_termos);

// Configura um ouvinte para aplicar as margens do sistema de barras


(status e navegação)

[Link](findViewById([Link]),
(v, insets) -> {

// Obtém os insets das barras do sistema (status e navegação)

Insets systemBars =
[Link]([Link]());
222

// Define o padding da view principal para evitar sobreposição pelas


barras do sistema

[Link]([Link], [Link], [Link],


[Link]);

// Retorna os insets não modificados

return insets;

});

// Obtém uma referência ao botão definido no layout

Button button = findViewById([Link]);

// Define um listener para o evento de clique do botão

[Link](new [Link]() {

@Override

public void onClick(View v) {

// Finaliza a Activity atual quando o botão é clicado

finish();

});

activity_adicionando_dispositivos.xml:
223

<?xml version="1.0" encoding="utf-8"?>


<[Link]
xmlns:android="[Link]
xmlns:app="[Link]
xmlns:tools="[Link]
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Adicionando_dispositivos">

<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">

<[Link]
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
android:id="@+id/topContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginTop="0dp"
android:layout_marginEnd="0dp"
android:background="@android:color/transparent"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="24dp"
app:layout_constraintTop_toTopOf="parent">
<!-- Container horizontal que alinha seu conteúdo ao centro
verticalmente.
Tem margem padrão de 0dp nas laterais e fundo transparente.
Contém um botão de imagem e um texto, com padding de 24dp.
224

A LinearLayout é posicionada no topo do layout do


ConstraintLayout. -->

<ImageButton
android:id="@+id/imageButtonBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:background="@android:color/transparent"
android:src="@drawable/voltar" />
<!-- Botão de imagem para voltar, sem fundo (transparente) e com
margem à direita.
Mostra o ícone definido em "voltar". -->

<TextView
android:id="@+id/textViewBack"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/archivo_semibold"
android:text="Adicione um dispositivo"
android:textColor="@color/main"
android:textSize="30sp" />
<!-- Texto ao lado do botão, ocupando o espaço restante.
Fonte personalizada, tamanho de 30sp e cor definida em "main".
Texto: "Adicione um dispositivo". -->

</LinearLayout> <!---->

<[Link]
android:id="@+id/cardView1"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_marginHorizontal="24dp"
225

android:layout_marginTop="24dp"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/topContainer">
<!-- CardView que serve como contêiner para um layout.
Dimensões fixas (150x150dp), margem horizontal e superior de
24dp.
Cor de fundo cinza, cantos arredondados de 15dp.
Posicionado centralizado horizontalmente abaixo de
"topContainer". -->

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<!-- Layout interno do CardView, com orientação vertical e
centralização do conteúdo. -->

<ImageView
android:id="@+id/imageViewDispositivo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:scaleType="centerCrop"
android:src="@drawable/vazio" />
<!-- Imagem centralizada dentro do LinearLayout, ajustada com
"centerCrop".
Mostra o drawable "vazio". -->

</LinearLayout>
226

</[Link]> <!---->

<LinearLayout
android:id="@+id/LinearDisp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="24dp"
android:gravity="center_vertical"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.666"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardView1">
<!-- LinearLayout para entrada de texto, horizontal e centrado
verticalmente.
Tem margens laterais e superior de 24dp. Posicionado abaixo do
CardView. -->

<[Link]
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Nome do dispositivo">
<!-- Contêiner para campo de entrada de texto, preenchendo o
espaço disponível.
Exibe o texto "Nome do dispositivo" como dica. -->

<EditText
android:id="@+id/editTextNome"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:fontFamily="@font/archivo_semibold"
227

android:gravity="center"
android:maxLength="25"
android:textSize="35sp" />
<!-- Campo de texto para o nome do dispositivo, sem fundo, fonte
personalizada.
Texto centralizado, limite de 25 caracteres e tamanho de texto
35sp. -->

</[Link]>

<ImageButton
android:id="@+id/imageButtonNome"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="-33dp"
android:background="?attr/selectableItemBackground"
android:contentDescription="Escolher nome"
android:src="@drawable/dropdown" />
<!-- Botão de imagem para abrir opções de nome, com fundo interativo
padrão.
Ícone de "dropdown" e descrição de conteúdo para acessibilidade.
Tem margem negativa para ajustar o posicionamento ao lado do
EditText. -->

<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="gone" />
<!-- Barra de progresso que aparece durante alguma operação (por
exemplo, carregamento).
Oculta por padrão com visibility "gone". -->
228

</LinearLayout> <!---->

<[Link]
android:id="@+id/cardView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="24dp"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/LinearDisp">
<!-- CardView que serve como contêiner para os elementos internos.
Largura máxima e altura ajustável, com margens laterais de 24dp e
superior de 24dp.
Cor de fundo cinza e bordas arredondadas (15dp). -->

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="vertical">
<!-- LinearLayout vertical que alinha os elementos ao centro
verticalmente. -->

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="24dp"
android:paddingTop="20dp"
android:paddingEnd="24dp">
229

<!-- LinearLayout horizontal com padding de 24dp nas laterais e


20dp em cima. -->

<[Link]
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Insira aqui a potência em WATTS">
<!-- Layout de entrada para potência, ocupando espaço flexível
(layout_weight). -->

<EditText
android:id="@+id/editTextPotencia"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/archivo_semibold"
android:inputType="numberDecimal"
android:textSize="15sp" />
<!-- Campo de entrada para potência, com fonte personalizada
e tipo numérico decimal. -->

</[Link]>

<ImageButton
android:id="@+id/helpButton"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="@android:color/transparent"
android:contentDescription="Help"
android:src="@drawable/question" />
<!-- Botão de imagem para ajuda, com ícone de pergunta, sem
fundo visível. -->
230

</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="20dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<!-- Outra LinearLayout horizontal para os próximos campos de
entrada. -->

<[Link]
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Ex: 8">
<!-- Layout de entrada para tempo, com espaço flexível. -->

<[Link]
android:id="@+id/editTextTempo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/archivo_semibold"
android:inputType="numberDecimal"
android:textSize="15sp" />
<!-- Campo de entrada para tempo, com fonte personalizada e
tipo numérico decimal. -->

</[Link]>

<Spinner
android:id="@+id/spinnerTempoUso"
231

android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:contentDescription="Escolher tempo de uso"
android:src="@android:drawable/arrow_down_float"
android:textAlignment="viewEnd" />
<!-- Spinner para selecionar a unidade de tempo de uso, com
fundo selecionável. -->

</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="20dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<!-- LinearLayout horizontal para a quantidade. -->

<[Link]
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Quantidade">
<!-- Layout de entrada para quantidade, ocupando espaço
flexível. -->

<EditText
android:id="@+id/editTextQuantidade"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:fontFamily="@font/archivo_semibold"
232

android:hint="Insira um número"
android:inputType="number"
android:text="1"
android:textSize="15sp" />
<!-- Campo de entrada para quantidade, com número como
inputType e texto padrão de "1". -->

</[Link]>

</LinearLayout> <!---->

<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginVertical="16dp"
android:background="@android:color/darker_gray" />
<!-- Linha horizontal separadora, com altura de 1dp e margem
vertical. -->

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="24dp"
android:paddingEnd="24dp">
<!-- LinearLayout horizontal para os campos de custo diário. -->

<[Link]
android:id="@+id/textInputLayoutCustoDiario"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_weight="1"
233

android:hint="Custo diário">
<!-- Layout de entrada para custo diário, ocupando espaço
flexível. -->

<[Link]
android:id="@+id/editTextCustoDiario"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:enabled="false"
android:fontFamily="@font/archivo_semibold"
android:inputType="numberDecimal"
android:textSize="17sp" />
<!-- Campo de entrada para custo diário, desabilitado, com
fundo transparente. -->

</[Link]>

<[Link]
android:id="@+id/textInputLayoutCustoDiarioTWh"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_weight="1"
android:hint="Consumo diário">
<!-- Layout de entrada para consumo diário, ocupando espaço
flexível. -->

<[Link]
android:id="@+id/editTextCustoDiarioTWh"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:enabled="false"
234

android:fontFamily="@font/archivo_semibold"
android:inputType="numberDecimal"
android:textSize="15sp" />
<!-- Campo de entrada para consumo diário, desabilitado, com
fundo transparente. -->

</[Link]>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="24dp"
android:paddingTop="20dp"
android:paddingEnd="24dp"
android:paddingBottom="20dp">
<!-- LinearLayout horizontal para os campos de custo mensal. -->

<[Link]
android:id="@+id/textInputLayoutCusto"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_weight="1"
android:hint="Custo mensal">
<!-- Layout de entrada para custo mensal, ocupando espaço
flexível. -->

<[Link]
android:id="@+id/editTextCusto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
235

android:background="@android:color/transparent"
android:enabled="false"
android:fontFamily="@font/archivo_semibold"
android:inputType="numberDecimal"
android:textSize="17sp" />
<!-- Campo de entrada para custo mensal, desabilitado, com
fundo transparente. -->

</[Link]>

<[Link]
android:id="@+id/textInputLayoutCustoTWh"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_weight="1"
android:hint="Consumo mensal">
<!-- Layout de entrada para consumo mensal, ocupando
espaço flexível. -->

<[Link]
android:id="@+id/editTextCustoTWh"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:enabled="false"
android:fontFamily="@font/archivo_semibold"
android:inputType="numberDecimal"
android:textSize="15sp" />
<!-- Campo de entrada para consumo mensal, desabilitado,
com fundo transparente. -->

</[Link]>
</LinearLayout>
236

</LinearLayout>
</[Link]> <!---->

<TextView
android:id="@+id/textViewSalvar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="24dp"
android:fontFamily="@font/archivo_semibold"
android:text="SALVAR"
android:textColor="@color/main"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardView2" />
<!-- Botão de salvar, configurado com texto, cor e tamanho específicos. --
>

</[Link]>
</ScrollView>
<RelativeLayout
android:id="@+id/loadingOverlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CCFFFFFF"
android:gravity="center"
android:visibility="gone">
<!-- Layout relativo que ocupa toda a tela (largura e altura).
Tem um fundo semitransparente branco (CCFFFFFF).
Os elementos dentro dele serão centralizados.
Inicialmente invisível (gone), usado para exibir um carregamento. -->
</RelativeLayout>
237

</[Link]>

activity_alteracao_email.xml:

<?xml version="1.0" encoding="utf-8"?>


<[Link]
xmlns:android="[Link]
xmlns:app="[Link]
xmlns:tools="[Link]
xmlns:material="[Link]
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Alterando_email">

<[Link]
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteX="-27dp"
tools:layout_editor_absoluteY="136dp">

<LinearLayout
android:id="@+id/topContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="24dp"
android:background="@android:color/transparent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="0dp"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
238

android:gravity="center_vertical">

<ImageButton
android:id="@+id/imageButtonBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/voltar"
android:background="@android:color/transparent"
android:layout_marginEnd="16dp" />

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/archivo_semibold"
android:text="Confirme sua senha antes de alterar o e-mail"
android:textColor="@color/main"
android:textSize="30sp"/>
</LinearLayout>

<LinearLayout
android:id="@+id/linearTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginHorizontal="24dp"
app:layout_constraintTop_toBottomOf="@id/textView5">

<TextView
android:id="@+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/archivo_semibold"
android:text="Seu e-mail atual é .... qual será o novo endereço?"
239

android:textSize="18dp"
android:textColor="@color/main"/>
</LinearLayout>

<[Link]
android:id="@+id/cardView2"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginTop="30dp"
android:layout_marginHorizontal="24dp"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/topContainer">

<[Link]
android:layout_width="match_parent"
android:layout_height="wrap_content">

<EditText
android:id="@+id/editTextTextPassword2"
style="@style/[Link]"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_margin="16dp"
android:background="@android:color/transparent"
android:hint="Digite sua senha"
android:inputType="textPassword"
android:textColor="#000000"
android:textColorHint="#000000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
240

</[Link]>
</[Link]>

<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="VERIFICAR"
android:fontFamily="@font/archivo_semibold"
android:textColor="@color/main"
android:textSize="20sp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="24dp"
app:layout_constraintTop_toBottomOf="@id/cardView2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>

<[Link]
android:id="@+id/cardView1"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginTop="10dp"
android:layout_marginHorizontal="24dp"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/linearTextView">

<EditText
android:id="@+id/editTextTextEmailAddress"
style="@style/[Link]"
android:layout_width="match_parent"
241

android:layout_height="60dp"
android:layout_marginHorizontal="16dp"
android:background="@android:color/transparent"
android:hint="Digite seu e-mail"
android:inputType="textEmailAddress"
android:textColor="#000000"
android:textColorHint="#000000"
android:enabled="false"/>
</[Link]>

<Button
android:id="@+id/button3"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="30dp"
android:background="@drawable/button_background"
android:text="Confirmar"
android:textColor="@color/main"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cardView1" />
</[Link]>

<RelativeLayout
android:id="@+id/loadingOverlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CCFFFFFF"
android:visibility="gone"
android:gravity="center">

<ProgressBar
android:id="@+id/progressBar"
242

android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone"
android:indeterminateTint="@android:color/white"
android:indeterminate="true" />
</RelativeLayout>

</[Link]>

activity_alteracao_senha.xml:

<?xml version="1.0" encoding="utf-8"?>


<[Link]
xmlns:android="[Link]
xmlns:app="[Link]
xmlns:tools="[Link]
xmlns:material="[Link]
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Alterando_senha">

<LinearLayout
android:id="@+id/topContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="24dp"
android:background="@android:color/transparent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="0dp"
android:layout_marginStart="0dp"
243

android:layout_marginEnd="0dp"
android:gravity="center_vertical">

<ImageButton
android:id="@+id/imageButtonBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/voltar"
android:background="@android:color/transparent"
android:layout_marginEnd="16dp" />

<TextView
android:id="@+id/textViewBack"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Confirme e mude sua senha"
android:fontFamily="@font/archivo_semibold"
android:textColor="@color/main"
android:textSize="30sp"/>

</LinearLayout>

<[Link]
android:id="@+id/cardView1"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="30dp"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
244

app:layout_constraintTop_toBottomOf="@id/topContainer">

<[Link]
android:layout_width="match_parent"
android:layout_height="wrap_content">

<EditText
android:id="@+id/editTextSenhaAtual"
style="@style/[Link]"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_margin="16dp"
android:background="@android:color/transparent"
android:ems="10"
android:hint="Senha atual"
android:inputType="textPassword"
android:textColor="#000000"
android:textColorHint="#000000"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />

</[Link]>
</[Link]>

<[Link]
android:id="@+id/cardView2"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginTop="40dp"
android:layout_marginHorizontal="24dp"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp"
app:layout_constraintEnd_toEndOf="parent"
245

app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cardView1">

<[Link]
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/editTextNovaSenha"
style="@style/[Link]"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_margin="16dp"
android:textColor="#000000"
android:textColorHint="#000000"
android:background="@android:color/transparent"
android:ems="10"
android:hint="Nova senha"
android:inputType="textPassword"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />

</[Link]>
</[Link]>

<[Link]
android:id="@+id/cardView3"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginTop="20dp"
android:layout_marginHorizontal="24dp"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp"
246

app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cardView2">

<[Link]
android:layout_width="match_parent"
android:layout_height="wrap_content">

<EditText
android:id="@+id/editTextConfirmarNovaSenha"
style="@style/[Link]"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_margin="16dp"
android:textColor="#000000"
android:textColorHint="#000000"
android:background="@android:color/transparent"
android:ems="10"
android:hint="Confirme senha"
android:inputType="textPassword"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
</[Link]>
</[Link]>>

<Button
android:id="@+id/button3"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="30dp"
android:background="@drawable/button_background"
247

android:text="Confirmar"
android:textColor="@color/main"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cardView3" />

</[Link]>

activity_atualizando_dispositivos.xml:

<?xml version="1.0" encoding="utf-8"?>


<[Link]
xmlns:android="[Link]
xmlns:app="[Link]
xmlns:tools="[Link]
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="20dp"
tools:context=".Atualizar_dispositivo">

<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<[Link]
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
android:id="@+id/topContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="24dp"
248

android:background="@android:color/transparent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="0dp"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:gravity="center_vertical">

<ImageButton
android:id="@+id/imageButtonBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/voltar"
android:background="@android:color/transparent"
android:layout_marginEnd="16dp" />

<TextView
android:id="@+id/textViewBack"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Atualizando dispositivo"
android:fontFamily="@font/archivo_semibold"
android:textColor="@color/main"
android:textSize="30sp"/>

</LinearLayout>

<[Link]
android:id="@+id/cardView1"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="24dp"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp"
249

app:layout_constraintTop_toBottomOf="@+id/topContainer"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">

<ImageView
android:id="@+id/imageViewDispositivo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/vazio"
android:scaleType="centerCrop" />

</LinearLayout>

</[Link]>

<LinearLayout
android:id="@+id/LinearDisp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="24dp"
android:gravity="center_vertical"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.666"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardView1">
250

<[Link]
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Nome do dispositivo">

<EditText
android:id="@+id/editTextNome"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:fontFamily="@font/archivo_semibold"
android:gravity="center"
android:maxLength="25"
android:textSize="25sp" />
</[Link]>

</LinearLayout>
<[Link]
android:id="@+id/cardView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="24dp"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp"
app:layout_constraintTop_toBottomOf="@+id/LinearDisp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
251

android:gravity="center_vertical"
android:orientation="vertical">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="24dp"
android:paddingTop="20dp"
android:paddingEnd="24dp">

<[Link]
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Potência em WATTS">

<EditText
android:id="@+id/editTextPotencia"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:fontFamily="@font/archivo_semibold"
android:textSize="15sp" />
</[Link]>

<ImageButton
android:id="@+id/helpButton"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="8dp"
android:background="@android:color/transparent"
android:contentDescription="Help"
252

android:src="@drawable/question" />

</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="20dp"
android:gravity="center_vertical"
android:orientation="horizontal">

<[Link]
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Tempo de uso">

<[Link]
android:id="@+id/editTextTempo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:backgroundTint="@color/main"
android:fontFamily="@font/archivo_semibold"
android:textSize="15sp" />
</[Link]>

<Spinner
android:id="@+id/spinnerTempoUso"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:background="?attr/selectableItemBackground"
253

android:contentDescription="Escolher tempo de uso"


android:src="@android:drawable/arrow_down_float" />
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="20dp"
android:gravity="center_vertical"
android:orientation="horizontal">

<[Link]
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Quantidade">
<EditText
android:id="@+id/editTextQuantidade"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:fontFamily="@font/archivo_semibold"
android:hint="Insira um número"
android:inputType="number"
android:text="1"

android:textSize="15sp" />
</[Link]>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
254

android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="24dp"
android:paddingTop="20dp"
android:paddingEnd="24dp">

<[Link]
android:id="@+id/textInputLayoutCustoDiario"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_weight="1"
android:hint="Custo diário">

<[Link]
android:id="@+id/editTextCustoDiario"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:background="@android:color/transparent"
android:fontFamily="@font/archivo_semibold"
android:textSize="15sp"
android:enabled="false"/>
</[Link]>

<[Link]
android:id="@+id/textInputLayoutCustoDiarioTWh"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="5dp"
android:hint="Gasto diário">

<[Link]
255

android:id="@+id/editTextGastoDiarioTWh"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:background="@android:color/transparent"
android:fontFamily="@font/archivo_semibold"
android:textSize="15sp"
android:enabled="false"/>
</[Link]>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="24dp"
android:paddingTop="20dp"
android:paddingBottom="20dp"
android:paddingEnd="24dp">

<[Link]
android:id="@+id/textInputLayoutCusto"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginRight="5dp"
android:hint="Custo mensal">

<[Link]
android:id="@+id/editTextCusto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
256

android:inputType="numberDecimal"
android:fontFamily="@font/archivo_semibold"
android:textSize="15sp"
android:enabled="false"/>
</[Link]>

<[Link]
android:id="@+id/textInputLayoutCustoTWh"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="5dp"
android:hint="Gasto mensal">

<[Link]
android:id="@+id/editTextCustoTWh"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:background="@android:color/transparent"
android:fontFamily="@font/archivo_semibold"
android:textSize="15sp"
android:enabled="false"/>
</[Link]>
</LinearLayout>
</LinearLayout>
</[Link]>

<TextView
android:id="@+id/textViewSalvar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SALVAR"
android:fontFamily="@font/archivo_semibold"
257

android:textColor="@color/main"
android:textSize="20sp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="24dp"
app:layout_constraintTop_toBottomOf="@+id/cardView2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>

</[Link]>
</ScrollView>
<RelativeLayout
android:id="@+id/loadingOverlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CCFFFFFF"
android:visibility="gone"
android:gravity="center">

</RelativeLayout>

</[Link]>

activity_cadastro.xml:

<?xml version="1.0" encoding="utf-8"?>


<[Link]
xmlns:android="[Link]
xmlns:app="[Link]
xmlns:tools="[Link]
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context=".Cadastro">
258

<[Link]
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteX="16dp"
tools:layout_editor_absoluteY="0dp">

<TextView
android:id="@+id/textView"
android:layout_width="368dp"
android:layout_height="110dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="24dp"
android:layout_marginBottom="16dp"
android:fontFamily="@font/archivo_semibold"
android:text="Criando uma conta"
android:textColor="@color/main"
android:textSize="48sp"
app:layout_constraintBottom_toTopOf="@+id/cardView1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<[Link]
android:id="@+id/cardView1"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="30dp"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
259

app:layout_constraintTop_toBottomOf="@id/textView">

<EditText
android:id="@+id/editTextText"
style="@style/[Link]"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginHorizontal="24dp"
android:background="@android:color/transparent"
android:backgroundTint="#000000"
android:ems="10"
android:hint="Digite seu nome"
android:hyphenationFrequency="normal"
android:inputType="textEmailAddress"
android:textColor="#000000"
android:textColorHint="#000000" />
</[Link]>

<[Link]
android:id="@+id/cardView2"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="30dp"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cardView1">

<EditText
android:id="@+id/editTextTextEmailAddress"
style="@style/[Link]"
android:layout_width="match_parent"
260

android:layout_height="60dp"
android:layout_marginHorizontal="24dp"
android:background="@android:color/transparent"
android:backgroundTint="#000000"
android:ems="10"
android:hint="Digite seu e-mail"
android:hyphenationFrequency="normal"
android:inputType="textEmailAddress"
android:textColor="#000000"
android:textColorHint="#000000" />
</[Link]>

<[Link]
android:id="@+id/cardView3"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="30dp"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cardView2">

<EditText
android:id="@+id/editTextTextPassword2"
style="@style/[Link]"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginHorizontal="24dp"
android:background="@android:color/transparent"
android:backgroundTint="#000000"
android:ems="10"
android:hint="Digite sua senha"
261

android:inputType="textPassword"
android:textColor="#000000"
android:textColorHint="#000000" />
</[Link]>

<[Link]
android:id="@+id/cardView4"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="30dp"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cardView3">

<EditText
android:id="@+id/editTextTextPassword3"
style="@style/[Link]"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginHorizontal="16dp"
android:background="@android:color/transparent"
android:backgroundTint="#000000"
android:ems="10"
android:hint="Confirme sua senha"
android:inputType="textPassword"
android:textColor="#000000"
android:textColorHint="#000000" />
</[Link]>

<Button
android:id="@+id/button3"
262

android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="30dp"
android:background="@drawable/button_background"
android:text="Cadastrar"
android:textColor="@color/main"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.666"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardView4" />

<TextView
android:id="@+id/textView3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="4dp"
android:text="Ao criar a conta, você concorda com nossos Termos de
Uso."
android:textAlignment="center"
android:textColor="@color/main"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.666"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button3" />
</[Link]>

<RelativeLayout
android:id="@+id/loadingOverlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CCFFFFFF"
263

android:visibility="gone"
android:gravity="center">

</RelativeLayout>
</[Link]>

activity_dados.xml:

<?xml version="1.0" encoding="utf-8"?>


<[Link]
xmlns:android="[Link]
xmlns:app="[Link]
xmlns:tools="[Link]
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Dados">

<LinearLayout
android:id="@+id/topContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="24dp"
android:background="@android:color/transparent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="0dp"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:gravity="center_vertical">

<ImageButton
android:id="@+id/imageButtonBack"
264

android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/voltar"
android:background="@android:color/transparent"
android:layout_marginEnd="16dp" />

<TextView
android:id="@+id/textViewBack"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Seus dados"
android:fontFamily="@font/archivo_semibold"
android:textColor="@color/main"
android:textSize="30sp"/>

</LinearLayout>

<[Link]
android:id="@+id/profileImageView"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginTop="32dp"
android:src="@drawable/controleenergialogo"
android:contentDescription="Icone"
app:layout_constraintTop_toBottomOf="@id/topContainer"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:background="@drawable/circle_border" />

<[Link]
android:id="@+id/cardView1"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginHorizontal="0dp"
265

android:layout_marginTop="30dp"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/profileImageView">

<[Link]
android:layout_width="match_parent"
android:layout_height="wrap_content">

<EditText
android:id="@+id/editTextNome"
style="@style/[Link]"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_margin="24dp"
android:background="@android:color/transparent"
android:ems="10"
android:enabled="false"
android:hint="Carregando..."
android:inputType="text"
android:textColor="#000000"
android:textColorHint="#000000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<ImageButton
android:id="@+id/ImageButtonLapisN"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:background="?attr/selectableItemBackgroundBorderless"
266

android:src="@drawable/lapis"
android:contentDescription="Toggle password visibility"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</[Link]>
</[Link]>

<[Link]
android:id="@+id/cardView2"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginTop="10dp"
android:layout_marginHorizontal="0dp"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cardView1">

<[Link]
android:layout_width="match_parent"
android:layout_height="wrap_content">

<EditText
android:id="@+id/editTextEmail"
style="@style/[Link]"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_margin="16dp"
android:background="@android:color/transparent"
android:ems="10"
android:hint="Carregando..."
android:inputType="textEmailAddress"
267

app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:enabled="false"/>

<ImageButton
android:id="@+id/ImageButtonLapisE"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:src="@drawable/lapis"
android:contentDescription="Toggle password visibility"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</[Link]>
</[Link]>

<[Link]
android:id="@+id/cardView3"
android:layout_width="0dp"
android:layout_height="60dp"

android:layout_marginHorizontal="0dp"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cardView2">

<[Link]
android:layout_width="match_parent"
android:layout_height="wrap_content">
268

<EditText
android:id="@+id/editTextSenha"
style="@style/[Link]"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_margin="16dp"
android:background="@android:color/transparent"
android:ems="10"
android:hint="Carregando..."
android:inputType="textPassword"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:enabled="false"/>

<ImageButton
android:id="@+id/ImageButtonLapisS"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:src="@drawable/lapis"
android:contentDescription="Toggle password visibility"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</[Link]>
</[Link]>>

<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
269

android:text="SAIR"
android:fontFamily="@font/archivo_semibold"
android:textColor="@color/main"
android:textSize="20sp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="24dp"
app:layout_constraintTop_toBottomOf="@+id/cardView3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>

</[Link]>

activity_dispositivo.xml:

<?xml version="1.0" encoding="utf-8"?>


<[Link]
xmlns:android="[Link]
xmlns:app="[Link]
xmlns:tools="[Link]
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Dispositivo">

<[Link]
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">

<ScrollView
android:layout_width="match_parent"
270

android:layout_height="match_parent">
<[Link]
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
android:id="@+id/topContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginTop="0dp"
android:layout_marginEnd="0dp"
android:background="@android:color/transparent"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="24dp"
app:layout_constraintTop_toTopOf="parent">

<ImageButton
android:id="@+id/imageButtonBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:background="@android:color/transparent"
android:src="@drawable/voltar" />

<TextView
android:id="@+id/textViewBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/archivo_semibold"
android:text="Seu dispositivo"
android:textColor="@color/main"
android:textSize="30sp" />
271

</LinearLayout>

<[Link]
android:id="@+id/cardView1"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="24dp"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/topContainer">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">

<ImageView
android:id="@+id/imageViewDispositivo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:scaleType="centerCrop"
android:src="@drawable/vazio" />

</LinearLayout>

</[Link]>

<LinearLayout
android:id="@+id/LinearDisp"
272

android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="24dp"
android:gravity="center_vertical"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.666"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardView1">

<[Link]
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Nome do dispositivo">

<EditText
android:id="@+id/editTextNome"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:enabled="false"
android:fontFamily="@font/archivo_semibold"
android:gravity="center"
android:textColor="@color/main"
android:maxLength="25"
android:textSize="35sp" />
</[Link]>

<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
273

android:indeterminate="true"
android:visibility="gone" />
</LinearLayout>

<[Link]
android:id="@+id/cardView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="24dp"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/LinearDisp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="vertical">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="24dp"
android:paddingTop="20dp"
android:paddingEnd="24dp">

<[Link]
android:layout_width="0dp"
android:layout_height="wrap_content"
274

android:layout_weight="1"
android:hint="Potência">

<EditText
android:id="@+id/editTextPotencia"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="@color/main"
android:enabled="false"
android:fontFamily="@font/archivo_semibold"
android:inputType="numberDecimal"
android:textColor="@color/main"
android:background="@android:color/transparent"
android:textSize="15sp" />
</[Link]>

</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="20dp"
android:gravity="center_vertical"
android:orientation="horizontal">

<[Link]
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Tempo de uso">

<[Link]
android:id="@+id/editTextTempo"
275

android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="@color/main"
android:enabled="false"
android:fontFamily="@font/archivo_semibold"
android:inputType="numberDecimal"
android:textColor="@color/main"
android:background="@android:color/transparent"
android:textSize="15sp" />
</[Link]>

<Spinner
android:id="@+id/spinnerTempoUso"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:background="?attr/selectableItemBackground"
android:contentDescription="Escolher tempo de uso"
android:src="@android:drawable/arrow_down_float" />
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="20dp"
android:gravity="center_vertical"
android:orientation="horizontal">

<[Link]
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Quantidade">
276

<EditText
android:id="@+id/editTextQuantidade"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:backgroundTint="@color/main"
android:enabled="false"
android:fontFamily="@font/archivo_semibold"
android:hint="Insira um número"
android:inputType="number"
android:text="1"
android:background="@android:color/transparent"
android:textColor="@color/main"
android:textSize="15sp" />
</[Link]>

</LinearLayout>

<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginVertical="16dp"
android:background="@android:color/darker_gray" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="24dp"
android:paddingEnd="24dp">

<[Link]
android:id="@+id/textInputLayoutCustoDiario"
277

android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_weight="1"
android:hint="Custo diário ">

<[Link]
android:id="@+id/editTextCustoDiario"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:enabled="false"
android:fontFamily="@font/archivo_semibold"
android:inputType="numberDecimal"
android:textSize="17sp" />
</[Link]>

<[Link]
android:id="@+id/textInputLayoutCustoDiarioKWh"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_weight="1"
android:hint="Consumo diário">

<[Link]
android:id="@+id/editTextGastoDiarioKWh"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:enabled="false"
android:fontFamily="@font/archivo_semibold"
android:inputType="numberDecimal"
android:textSize="15sp" />
278

</[Link]>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="24dp"
android:paddingTop="20dp"
android:paddingEnd="24dp"
android:paddingBottom="20dp">

<[Link]
android:id="@+id/textInputLayoutCusto"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_weight="1"
android:hint="Custo mensal">

<[Link]
android:id="@+id/editTextCusto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:enabled="false"
android:fontFamily="@font/archivo_semibold"
android:inputType="numberDecimal"
android:textSize="17sp" />
</[Link]>

<[Link]
android:id="@+id/textInputLayoutCustoKWh"
279

android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_weight="1"
android:hint="Consumo mensal">

<[Link]
android:id="@+id/editTextGastoKWh"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:enabled="false"
android:fontFamily="@font/archivo_semibold"
android:inputType="numberDecimal"
android:textSize="15sp" />
</[Link]>
</LinearLayout>
</LinearLayout>
</[Link]>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="24dp"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:padding="24dp"
app:layout_constraintTop_toBottomOf="@id/cardView2">

<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
280

android:layout_marginEnd="10dp"
android:fontFamily="@font/archivo_semibold"
android:text="ATUALIZAR"
android:textColor="@color/main"
android:textSize="20sp" />

<TextView
android:id="@+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:fontFamily="@font/archivo_semibold"
android:text="EXCLUIR"
android:textColor="@color/main"
android:textSize="20sp" />
</LinearLayout>

</[Link]>
</ScrollView>
</[Link]>

<RelativeLayout
android:id="@+id/loadingOverlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CCFFFFFF"
android:gravity="center"
android:visibility="gone" />
</[Link]>

activity_gastos.xml:

<?xml version="1.0" encoding="utf-8"?>


281

<[Link]
xmlns:android="[Link]
xmlns:app="[Link]
xmlns:tools="[Link]
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Gastos">

<[Link]
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
android:id="@+id/topContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="24dp"
android:background="@android:color/transparent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="0dp"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:gravity="center_vertical">

<ImageButton
android:id="@+id/imageButtonBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/voltar"
android:background="@android:color/transparent"
282

android:layout_marginEnd="16dp" />

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/archivo_semibold"
android:text="Seus gastos"
android:textColor="@color/main"
android:textSize="48sp"/>
</LinearLayout>

<TextView
android:id="@+id/textView6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:fontFamily="@font/archivo_semibold"
android:text="Esse é o histórico de seus gastos mensais. Compare e
procure economizar :)"
android:textSize="18dp"
android:textColor="@color/main"
app:layout_constraintTop_toBottomOf="@id/topContainer"
app:layout_constraintVertical_bias="0.0"/>

<LinearLayout
android:id="@+id/monthSelectorLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="15dp"
android:gravity="center_vertical"
app:layout_constraintTop_toBottomOf="@id/textView6"
app:layout_constraintStart_toStartOf="parent"
283

app:layout_constraintEnd_toEndOf="parent"
android:padding="16dp">

<ImageButton
android:id="@+id/mesAnterior"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:background="@android:color/transparent"
android:src="@drawable/setaesquerda"
android:contentDescription="Mês Anterior" />

<TextView
android:id="@+id/monthTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Mês atual"
android:textSize="24sp"
android:fontFamily="@font/archivo_semibold"
android:textColor="@color/main"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:gravity="center" />

<ImageView
android:id="@+id/monthPickerIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_menu_month"
android:contentDescription="Selecione o mês"
android:layout_marginEnd="8dp"
android:padding="4dp" />
284

<ImageButton
android:id="@+id/mesSeguinte"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="24dp"
android:background="@android:color/transparent"
android:src="@drawable/setadireita"
android:contentDescription="Mês Seguinte" />

</LinearLayout>

<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="-30dp"
android:layout_marginBottom="30dp"
android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@id/monthSelectorLayout"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:padding="16dp">

<[Link]
android:id="@+id/cardView1"
android:layout_width="match_parent"
android:layout_height="350dp"
android:layout_marginBottom="-8dp"
android:layout_marginHorizontal="24dp"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="30dp">

<[Link]
xmlns:android="[Link]
285

android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">

<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
android:id="@+id/linearLayoutDevices"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">

<TextView
android:id="@+id/textViewLista"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:text="Carregando..."
android:textSize="18dp"
android:fontFamily="@font/archivo_semibold"/>

</LinearLayout>

</ScrollView>
</[Link]>
</[Link]>

<[Link]
android:id="@+id/cardView2"
android:layout_width="match_parent"
android:layout_height="150dp"
286

android:layout_marginHorizontal="24dp"
app:cardBackgroundColor="@color/main"
app:cardCornerRadius="30dp">

<TextView
android:id="@+id/textViewTotal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="R$ 00,00 "
android:textSize="30sp"
android:fontFamily="@font/archivo_black"
android:textColor="@android:color/white"/>
</[Link]>

</LinearLayout>

<RelativeLayout
android:id="@+id/loadingOverlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CCFFFFFF"
android:visibility="gone"
android:gravity="center">

</RelativeLayout>
</[Link]>

</[Link]>

activity_inicio.xml:

<?xml version="1.0" encoding="utf-8"?>


287

<[Link]
xmlns:android="[Link]
xmlns:app="[Link]
xmlns:tools="[Link]
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@style/AppTheme"
tools:context=".Inicio">

<[Link]
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">

<[Link]
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">

<ImageButton
android:id="@+id/hamburger_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Menu"
android:onClick="openDrawer"
android:src="@drawable/menu"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
288

<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="20dp"
android:fontFamily="@font/archivo_semibold"
android:text="Olá!"
android:textColor="@color/main"
android:textSize="25dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/hamburger_menu" />

<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="67dp"
android:layout_marginStart="24dp"
android:layout_marginTop="5dp"
android:background="@drawable/marcatexto"
android:clickable="true"
android:focusable="true"
android:fontFamily="@font/archivo_black"
android:onClick="openGastosActivity"
android:text="R$ 0,00"
android:textColor="@color/main"
android:textSize="49dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView4" />

<TextView
android:id="@+id/textView6"
289

android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="5dp"
android:fontFamily="@font/archivo_semibold"
android:text="Veja os aparelhos que você já adicionou:"
android:textColor="@color/main"
android:textSize="18dp"
app:layout_constraintBottom_toTopOf="@id/swipeRefreshLayout"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView5" />

<[Link]
android:id="@+id/swipeRefreshLayout"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginBottom="10dp"
app:layout_constraintBottom_toTopOf="@id/viewFlipperContainer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView6">

<ScrollView
android:id="@+id/scroll_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginBottom="28dp"
android:foregroundGravity="center_horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView6">

<LinearLayout
290

android:id="@+id/cardsScrollContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginHorizontal="25dp"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="10dp"
android:scrollbars="horizontal">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="24dp"
android:orientation="horizontal">

<[Link]
android:layout_width="130dp"
android:layout_height="130dp"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
android:layout_marginEnd="25dp"
android:clickable="true"
android:focusable="true"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="10dp"
291

android:gravity="center_vertical"
android:orientation="vertical">

<ImageView
android:id="@+id/card1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/vazio" />

<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>
"
<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>

</LinearLayout>

</[Link]>

<[Link]
android:layout_width="130dp"
android:layout_height="130dp"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
292

android:layout_marginEnd="25dp"
android:clickable="true"
android:focusable="true"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="10dp"
android:gravity="center_vertical"
android:orientation="vertical">

<ImageView
android:id="@+id/card2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/vazio" />

<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>
"
<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>
293

</LinearLayout>

</[Link]>

</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="24dp"
android:orientation="horizontal">

<[Link]
android:layout_width="130dp"
android:layout_height="130dp"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
android:layout_marginEnd="25dp"
android:clickable="true"
android:focusable="true"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="10dp"
android:gravity="center_vertical"
android:orientation="vertical">

<ImageView
android:id="@+id/card3"
android:layout_width="wrap_content"
294

android:layout_height="wrap_content"
android:src="@drawable/vazio" />

<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>
"
<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>

</LinearLayout>

</[Link]>

<[Link]
android:layout_width="130dp"
android:layout_height="130dp"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
android:layout_marginEnd="25dp"
android:clickable="true"
android:focusable="true"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp">

<LinearLayout
android:layout_width="match_parent"
295

android:layout_height="match_parent"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="10dp"
android:gravity="center_vertical"
android:orientation="vertical">

<ImageView
android:id="@+id/card4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/vazio" />

<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>
"
<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>

</LinearLayout>

</[Link]>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="24dp"
296

android:orientation="horizontal">

<[Link]
android:layout_width="130dp"
android:layout_height="130dp"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
android:layout_marginEnd="25dp"
android:clickable="true"
android:focusable="true"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="10dp"
android:gravity="center_vertical"
android:orientation="vertical">

<ImageView
android:id="@+id/card7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/vazio" />

<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardBackgroundColor="@color/loading"
app:cardCornerRadius="60dp" />
"
297

<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardBackgroundColor="@color/loading"
app:cardCornerRadius="60dp" />

</LinearLayout>

</[Link]>

<[Link]
android:layout_width="130dp"
android:layout_height="130dp"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
android:layout_marginEnd="25dp"
android:clickable="true"
android:focusable="true"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="10dp"
android:gravity="center_vertical"
android:orientation="vertical">

<ImageView
android:id="@+id/card8"
android:layout_width="wrap_content"
298

android:layout_height="wrap_content"
android:src="@drawable/vazio" />

<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardBackgroundColor="@color/loading"
app:cardCornerRadius="60dp" />
"

<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardBackgroundColor="@color/loading"
app:cardCornerRadius="60dp" />

</LinearLayout>
</[Link]>
</LinearLayout>

</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_marginHorizontal="24dp">

<[Link]
android:layout_width="130dp"
android:layout_height="130dp"
android:layout_marginHorizontal="20dp"
299

android:layout_marginVertical="10dp"
android:layout_marginEnd="25dp"
android:clickable="true"
android:focusable="true"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="10dp"
android:gravity="center_vertical"
android:orientation="vertical">

<ImageView
android:id="@+id/card9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/vazio" />

<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>
"
<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>
300

</LinearLayout>

</[Link]>

<[Link]
android:layout_width="130dp"
android:layout_height="130dp"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
android:layout_marginEnd="25dp"
android:clickable="true"
android:focusable="true"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="10dp"
android:gravity="center_vertical"
android:orientation="vertical">

<ImageView
android:id="@+id/card10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/vazio" />

<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
301

app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>
"
<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>

</LinearLayout>
</[Link]>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_marginHorizontal="24dp">

<[Link]
android:layout_width="130dp"
android:layout_height="130dp"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
android:layout_marginEnd="25dp"
android:clickable="true"
android:focusable="true"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp">

<LinearLayout
302

android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="10dp"
android:gravity="center_vertical"
android:orientation="vertical">

<ImageView
android:id="@+id/card11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/vazio" />

<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>
"
<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>

</LinearLayout>

</[Link]>

<[Link]
android:layout_width="130dp"
android:layout_height="130dp"
303

android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
android:layout_marginEnd="25dp"
android:clickable="true"
android:focusable="true"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="10dp"
android:gravity="center_vertical"
android:orientation="vertical">

<ImageView
android:id="@+id/card12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/vazio" />

<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>
"
<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
304

app:cardBackgroundColor="@color/loading"/>

</LinearLayout>
</[Link]>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_marginHorizontal="24dp">

<[Link]
android:layout_width="130dp"
android:layout_height="130dp"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
android:layout_marginEnd="25dp"
android:clickable="true"
android:focusable="true"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="10dp"
android:gravity="center_vertical"
android:orientation="vertical">

<ImageView
android:id="@+id/card13"
305

android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/vazio" />

<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>
"
<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>

</LinearLayout>

</[Link]>

<[Link]
android:layout_width="130dp"
android:layout_height="130dp"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
android:layout_marginEnd="25dp"
android:clickable="true"
android:focusable="true"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp">

<LinearLayout
306

android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="10dp"
android:gravity="center_vertical"
android:orientation="vertical">

<ImageView
android:id="@+id/card14"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/vazio" />

<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>
"
<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>

</LinearLayout>
</[Link]>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
307

android:orientation="horizontal"
android:layout_marginHorizontal="24dp">

<[Link]
android:layout_width="130dp"
android:layout_height="130dp"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
android:layout_marginEnd="25dp"
android:clickable="true"
android:focusable="true"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="10dp"
android:gravity="center_vertical"
android:orientation="vertical">

<ImageView
android:id="@+id/card15"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/vazio" />

<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
308

app:cardBackgroundColor="@color/loading"/>
"
<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>

</LinearLayout>

</[Link]>

<[Link]
android:layout_width="130dp"
android:layout_height="130dp"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
android:layout_marginEnd="25dp"
android:clickable="true"
android:focusable="true"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="10dp"
android:gravity="center_vertical"
android:orientation="vertical">

<ImageView
android:id="@+id/card16"
309

android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/vazio" />

<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>
"
<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>

</LinearLayout>
</[Link]>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_marginHorizontal="24dp">

<[Link]
android:layout_width="130dp"
android:layout_height="130dp"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
310

android:layout_marginEnd="25dp"
android:clickable="true"
android:focusable="true"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="10dp"
android:gravity="center_vertical"
android:orientation="vertical">

<ImageView
android:id="@+id/card17"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/vazio" />

<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>
"
<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>
311

</LinearLayout>

</[Link]>

<[Link]
android:layout_width="130dp"
android:layout_height="130dp"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
android:layout_marginEnd="25dp"
android:clickable="true"
android:focusable="true"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="10dp"
android:gravity="center_vertical"
android:orientation="vertical">

<ImageView
android:id="@+id/card18"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/vazio" />

<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
312

app:cardBackgroundColor="@color/loading"/>
"
<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="60dp"
app:cardBackgroundColor="@color/loading"/>

</LinearLayout>
</[Link]>
</LinearLayout>

</LinearLayout>
</ScrollView>
</[Link]>

<[Link]
android:id="@+id/viewFlipperContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="30dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">

<ImageButton
android:id="@+id/prevButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
313

android:layout_marginRight="12dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Previous"
android:src="@drawable/setaesquerda"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<ViewFlipper
android:id="@+id/viewFlipper"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:inAnimation="@android:anim/fade_in"
android:outAnimation="@android:anim/fade_out"

app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/nextButton"
app:layout_constraintStart_toEndOf="@id/prevButton">

<[Link]
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="10dp"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="10dp"
android:orientation="vertical">
314

<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
app:cardBackgroundColor="@color/loading"
app:cardCornerRadius="60dp" />

<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginBottom="10dp"
app:cardBackgroundColor="@color/loading"
app:cardCornerRadius="60dp" />

<[Link]
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginBottom="10dp"
app:cardBackgroundColor="@color/loading"
app:cardCornerRadius="60dp" />

</LinearLayout>

</[Link]>

</ViewFlipper>

<ImageButton
android:id="@+id/nextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
315

android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Next"
android:src="@drawable/setadireita"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</[Link]>

<LinearLayout
android:id="@+id/indicatorLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/viewFlipperContainer" /
>

</[Link]>

<[Link]
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="@color/white"
app:menu="@menu/drawer_menu">

</[Link]>

</[Link]>
316

<RelativeLayout
android:id="@+id/loadingOverlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/loading1"
android:gravity="center"
android:visibility="gone"></RelativeLayout>
</[Link]>

<?xml version="1.0" encoding="utf-8"?>


<[Link]
xmlns:android="[Link]
xmlns:app="[Link]
xmlns:tools="[Link]
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context=".Login">

<[Link]
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteX="-27dp"
tools:layout_editor_absoluteY="136dp">

<ImageView
android:id="@+id/imageView"
android:layout_width="200dp"
android:layout_height="170dp"
android:layout_marginStart="-30dp"
android:layout_marginTop="50dp"
android:layout_marginBottom="16dp"
317

app:layout_constraintBottom_toTopOf="@+id/textView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/controleenergialogo" />

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:fontFamily="@font/archivo_semibold"
android:text="Bem-vindo a"
android:textColor="@color/main"
android:textSize="24sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.085"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView" />

<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="-8dp"
android:fontFamily="@font/anonymous_pro"
android:text="ControleEnergia"
android:textColor="@color/main"
android:textSize="34sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.175"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
318

<[Link]
android:id="@+id/cardView1"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="30dp"
app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView2">

<EditText
android:id="@+id/editTextTextEmailAddress"
style="@style/[Link]"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginHorizontal="24dp"
android:background="@android:color/transparent"
android:ems="10"
android:hint="Digite seu e-mail"
android:hyphenationFrequency="normal"
android:inputType="textEmailAddress"
android:textColor="#000000"
android:textColorHint="#000000" />
</[Link]>

<[Link]
android:id="@+id/cardView2"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="30dp"
319

app:cardBackgroundColor="@color/gray"
app:cardCornerRadius="15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cardView1">

<[Link]
android:layout_width="match_parent"
android:layout_height="wrap_content">

<EditText
android:id="@+id/editTextTextPassword2"
style="@style/[Link]"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginHorizontal="24dp"
android:background="@android:color/transparent"
android:ems="10"
android:hint="Digite sua senha"
android:inputType="textPassword"
android:textColor="#000000"
android:textColorHint="#000000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btnTogglePasswordVisibility
"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<ImageButton
android:id="@+id/btnTogglePasswordVisibility"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_margin="16dp"
android:background="?attr/selectableItemBackgroundBorderless"
320

android:contentDescription="Toggle password visibility"


android:src="@drawable/senhaver"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</[Link]>
</[Link]>

<Button
android:id="@+id/button3"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="30dp"
android:background="@drawable/button_background"
android:onClick="onLoginButtonClick"
android:text="Entrar"
android:textColor="@color/main"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.666"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardView2" />

<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="-20dp"
android:layout_marginBottom="16dp"
android:clickable="true"
android:focusable="true"
android:text="Esqueceu a senha?"
321

android:textColor="#000000"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button3"
app:layout_constraintVertical_bias="0.123" />

</[Link]>

<[Link]
android:id="@+id/viewFlipperContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="30dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent">

<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:clickable="true"
android:focusable="true"
android:text="Não tem conta? Crie uma!"
android:textColor="#000000"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
322

app:layout_constraintStart_toStartOf="parent"
app:layout_constraintVertical_bias="0.123" />

</[Link]>

<RelativeLayout
android:id="@+id/loadingOverlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CCFFFFFF"
android:visibility="gone"
android:gravity="center">

</RelativeLayout>
</[Link]>

activity_splash.xml:

<?xml version="1.0" encoding="utf-8"?>


<[Link]
xmlns:android="[Link]
xmlns:app="[Link]
xmlns:tools="[Link]
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/splash_gradient"
tools:context=".Splash">

<ImageView
android:id="@+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
323

app:srcCompat="@drawable/splash1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />

</[Link]>

activity_termos.xml:

<?xml version="1.0" encoding="utf-8"?>


<[Link]
xmlns:android="[Link]
xmlns:app="[Link]
xmlns:tools="[Link]
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Termos">

<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginBottom="24dp"
android:layout_marginHorizontal="24dp"
android:fontFamily="@font/archivo_semibold"
android:text="Termos de uso"
android:textColor="@color/main"
android:textSize="48sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
324

<ScrollView
android:id="@+id/scrollView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView"
app:layout_constraintBottom_toBottomOf="parent">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/terms_text"
android:textAlignment="viewStart"
android:justificationMode="inter_word"
android:textColor="@color/main"
android:textSize="20sp" />

<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="59dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="30dp"
android:background="@drawable/button_background"
325

android:text="CONCORDAR E CONTINUAR"
android:textColor="@color/main" />

</LinearLayout>
</ScrollView>
</[Link]>

9.1.1 Capturas de Telas

Figura 20: Tela de splash


326

Figura 21: tela de login

Figura 22: Tela de cadastro


327
328

Figura 23: tela de termos

Figura 24: Tela inicial


Figura 25: menu lateral
329
330

Figura 26: tela de dados pessoais

Figura 27: tela de alteração de e-mail


331

Figura 28: tela de alteração de senha

Figura 29: tela de gastos


332

Figura 30: tela de dispositivo

Figura 31: tela de atualização do dispositivo


333

Figura 32: Tela de adição do dispositivo


Figura 33: Dispositivos pré-definidos
334

10.1.1 Diagrama de Caso de Uso


Figura 34: diagrama de caso de uso da tela de adição de dispositivo

Figura 35: diagrama de caso de uso da tela de alteração do endereço de e-


mail
335

Figura 36: diagrama de caso de uso da tela de alteração de senha

Figura 37: diagrama de caso de uso da tela de atualização do dispositivo


336

Figura 38: diagrama de caso de uso da tela de cadastro


337

Figura 39: diagrama de caso de uso da tela de dados pessoais


338

Figura 40: diagrama de caso de uso da tela de dispositivo


339

Figura 41: diagrama de caso de uso da tela de gastos


340

Figura 42: diagrama de caso de uso da tela de inicio


341

Figura 43: diagrama de caso de uso da tela de login

Figura 44: diagrama de caso de uso da tela de termos


342

11.1.1 Diagrama UML

Figura 45: Diagrama UML Adicionando_dispositivos.java


343

Figura 46: Diagrama UML Alterando_email.java

Figura 47: Diagrama UML Alterando_senha.java:


344

Figura 48: Diagrama UML Atualizar_dispositivo.java:


345

Figura 49: Diagrama UML [Link]:


346

Figura 50: Diagrama UML [Link]:


347

Figura 51: Diagrama UML [Link]:


348

Figura 52: Diagrama UML [Link]:


349

Figura 53: Diagrama UML [Link]


350

Figura 54: Diagrama UML [Link]


351

Figura 55: Diagrama UML [Link]

Figura 56: Diagrama UML [Link]

Figura 57: Diagrama UML [Link]


352

12.1.1 Modelo Lógico do Banco de Dados


Figura 58: Modelo lógico do banco de dados
353

13.1.1 Modelo Conceitual do Banco de Dados


Figura 59: Modelo conceitual do banco de dados

14.1.1 Modelo Físico do Banco de Dados

CREATE TABLE Usuário (


ID VARCHAR(10) PRIMARY KEY,
Nome VARCHAR(10),
E-mail VARCHAR(10)
)

CREATE TABLE Dispositivos (


ID VARCHAR(25) PRIMARY KEY,
Nome VARCHAR(25),
Potencia INTEGER,
imagemUrl VARCHAR(255),
Quantidade NUMERIC(10),
TempoUso INTEGER,
UnidadeTempo VARCHAR(20),
CustoDiario NUMERIC(10),
354

CustoMensal NUMERIC(10),
GastoDiarioKWh DECIMAL(10),
GastoMensalKWh DECIMAL(10)
)

CREATE TABLE Gastos (


mesAno VARCHAR(7) PRIMARY KEY,
Total NUMERIC(10)
)

CREATE TABLE Dicas (


nome VARCHAR(10) PRIMARY KEY,
texto VARCHAR(255),
link VARCHAR(255 )
)

CREATE TABLE DispositivosPreDef (


Nome VARCHAR(25 ) PRIMARY KEY,
Potência INTEGER,
ImagemUrl VARCHAR(255 )
)

15.1.1 Manuais do Programa

Este manual descreve o funcionamento do aplicativo desenvolvido para


facilitar o controle e monitoramento do consumo de energia elétrica. O objetivo é
proporcionar aos usuários uma ferramenta simples e prática para calcular os gastos
energéticos de aparelhos eletrônicos e elétricos, de forma a auxiliar na economia e
no planejamento financeiro.
O aplicativo utiliza informações fornecidas pelo usuário ou dados pré-
definidos para calcular o consumo e convertê-lo automaticamente em reais. Desta
forma, é possível visualizar o quanto se gasta diariamente e mensalmente com cada
aparelho, além de ter acesso ao histórico de consumo por mês.
355

Funcionalidades Principais

1. Inserção, Edição e Excluir Aparelhos


O usuário pode inserir manualmente os dados de cada aparelho, incluindo:
- Potência (em watts): valor de potência do aparelho.
- Tempo de uso (em minutos ou horas/dia): quanto tempo o aparelho é
utilizado diariamente.
- Quantidade de aparelhos: o número de aparelhos iguais em uso.
Essas informações serão utilizadas para calcular o consumo energético e o
respectivo custo em reais.
O usuário pode editar manualmente os aparelhos no botão “editar”, podendo
alterar todas as informações inseridas.
O usuário pode também excluir cada aparelho no botão “Excluir”

2. Aparelhos Pré-definidos:
Caso o usuário não saiba os detalhes do aparelho, o aplicativo oferece uma
lista de aparelhos pré-definidos com as informações de potência já configuradas. O
usuário precisa apenas informar o tempo de uso e a quantidade. Isso facilita o uso
para aqueles que não possuem conhecimentos sobre os aparelhos.

3. Função de Ajuda (“?”):


Para casos em que o aparelho desejado não está disponível na lista pré-
definida, o aplicativo dispõe de uma função de ajuda (“?”). Nela, o usuário encontra
orientações sobre como obter as informações necessárias para realizar o cálculo de
consumo. Esse recurso inclui explicações simples sobre como encontrar a potência
do aparelho em etiquetas ou manuais.

4. Cálculo Automático de Custos:


Após a inserção dos dados, o aplicativo calcula automaticamente o consumo
energético e o converte em reais, apresentando o custo de:
- Gasto por dia: valor estimado de consumo diário.
- Gasto por mês: cálculo estimado de consumo mensal, baseado no uso diário
informado.
356

5. Atualização de Custos:
À medida que o usuário adiciona mais aparelhos, o valor total é atualizado
automaticamente, permitindo uma visualização em tempo real do consumo total em
reais. Essa funcionalidade ajuda o usuário a entender como os diferentes aparelhos
contribuem para o gasto total

6. Histórico de Consumo:
O aplicativo armazena o histórico de consumo por mês, oferecendo uma visão
detalhada dos gastos ao longo do tempo. O usuário pode consultar:
- O custo mensal
- O custo diário
- O gasto mensal
- O gasto diário
- Comparações entre os meses para verificar quando houve maior ou menor
consumo de energia.

7. Mudar dados de usuário:


O usuário pode mudar seus dados entrando na aba “perfil”, podendo alterar:
- Nome
- Email
- Senha

Instruções de Uso:
1. Acesso ao aplicativo: Abra o aplicativo e crie uma conta ou faça login.
2. Inserir aparelho: Na tela inicial, clique no + para adicionar o aparelho.
3. Preencher dados: Informe os dados solicitados (potência, tempo de uso,
quantidade) ou selecione um aparelho pré-definido.
4. Verificar gastos: O aplicativo calculará automaticamente o custo em reais,
tanto diário quanto mensal.
5. Salvar: Aperte no botão salvar.
6. Adicionar mais aparelhos: Repita o processo para quantos aparelhos forem
necessários. O valor total será atualizado em tempo real.
357

7. Consultar histórico: Acesse o botão "Gastos" para visualizar os gastos dos


meses anteriores.

Este aplicativo foi desenvolvido para ser uma ferramenta prática e eficiente
para controle de gastos energéticos, proporcionando ao usuário uma visão clara e
objetiva sobre o impacto do uso de seus aparelhos eletrônicos no consumo mensal
de energia. Além disso, permite um acompanhamento constante e comparações
mensais, contribuindo para uma gestão mais consciente e econômica dos recursos
energéticos.

16.1.1 Ciclo de Vida do Programa


358

6. CONSIDERAÇÕES FINAIS

Nas considerações finais busca-se recapitular de forma sintética os resultados


da pesquisa. Fundamenta-se no próprio texto, expressando de forma sistêmica os
pontos essenciais resultantes da monografia, podendo ainda constar propostas e
sugestões do autor, decorrentes da pesquisa elaborada.

Responda se os objetivos foram atendidos, se foram totalmente, ou


parcialmente ou não atendimento e justifique atestando os resultados

Destaque os pontos fortes do projeto e aquilo que é crucial

Deixe recomendações de novos estudos, aprofundamentos e melhorias


359

REFERÊNCIAS

As referências devem conter o conjunto de elementos que permitem a


identificação, no todo ou parte, de documentos impressos ou registrados em
diversos tipos de materiais. Busca-se, assim, facilitar a identificação de documentos
utilizados e citados ao longo da elaboração do trabalho científico.

MATIAS PEREIRA, José. Manual de metodologia da pesquisa científica.


São Paulo: Atlas, 2007
360

GLOSSÁRIO

Relação de termos técnicos utilizados no trabalho, com respectivos


significados.
361

APÊNDICE(S)

É um texto/ documento elaborado pelo autor, que serve de fundamentação,


comprovação e ilustração para o trabalho. Por exemplo: um questionário, um roteiro
de entrevista, um relatório, uma correspondência, um desenho etc. – São
identificados por letras maiúsculas e travessão, seguida do título.

Inserir o cronograma

Inserir o orçamento

Exemplo:

APÊNDICE A – Avaliação das células aos quatro dias de evolução


362

ANEXO(S)

É um texto/documento não elaborado pelo autor, que serve de


fundamentação, comprovação e ilustração para o trabalho. Por exemplo: uma norma
técnica, um certificado de qualidade, um documento de garantia etc. – São
identificados por letras maiúsculas e travessão, seguido do título.
Exemplo:
ANEXO A – Repr-esentação gráfica de contagem de células

Você também pode gostar