View
218
Download
4
Category
Preview:
Citation preview
UNIVERSIDADE INTELIGENTE:
SOLUÇÕES TECNOLÓGICAS PARA MELHORIA DO
COTIDIANO UNIVERSITÁRIO – MÓDULOS
GERENCIAMENTO DE USUÁRIO E DISCIPLINAS.
Laura Marra Pires
Projeto de Graduação apresentado ao Curso de
Engenharia Eletrônica e de Computação da Escola
Politécnica, Universidade Federal do Rio de
Janeiro, como parte dos requisitos necessários à
obtenção do título de Engenheiro.
Orientador: Heraldo Luis Silveira de Almeida
Rio de Janeiro
Agosto de 2015
ii
UNIVERSIDADE INTELIGENTE:
SOLUÇÕES TECNOLÓGICAS PARA MELHORIA DO
COTIDIANO UNIVERSITÁRIO – MÓDULOS
GERENCIAMENTO DE USUÁRIO E DISCIPLINAS.
Laura Marra Pires
PROJETO DE GRADUAÇÃO SUBMETIDO AO CORPO DOCENTE DO CURSO
DE ENGENHARIA ELETRÔNICA E DE COMPUTAÇÃO DA ESCOLA
POLITÉCNICA DA UNIVERSIDADE FEDERAL DO RIO DE JANEIRO COMO
PARTE DOS REQUISITOS NECESSÁRIOS PARA A OBTENÇÃO DO GRAU DE
ENGENHEIRO ELETRÔNICO E DE COMPUTAÇÃO
Autores:
_________________________________________________
Laura Marra Pires
Orientador:
_________________________________________________
Heraldo Luis Silveira de Almeida, D.Sc.
Examinador:
_________________________________________________
Aloysio de Castro Pinto Pedroza, D.Sc.
Examinador:
_________________________________________________
Carlos José Ribas D'Ávila, M.Sc.
Rio de Janeiro – RJ, Brasil
Agosto de 2015
iii
UNIVERSIDADE FEDERAL DO RIO DE JANEIRO
Escola Politécnica – Departamento de Eletrônica e de Computação
Centro de Tecnologia, bloco H, sala H-217, Cidade Universitária
Rio de Janeiro – RJ CEP 21949-900
Este exemplar é de propriedade da Universidade Federal do Rio de Janeiro, que
poderá incluí-lo em base de dados, armazenar em computador, microfilmar ou adotar
qualquer forma de arquivamento.
É permitida a menção, reprodução parcial ou integral e a transmissão entre
bibliotecas deste trabalho, sem modificação de seu texto, em qualquer meio que esteja
ou venha a ser fixado, para pesquisa acadêmica, comentários e citações, desde que sem
finalidade comercial e que seja feita a referência bibliográfica completa.
Os conceitos expressos neste trabalho são de responsabilidade do(s) autor(es).
iv
Dedico este trabalho à minha familia.
v
AGRADECIMENTO
Gostaria de agradecer primeiramente aos meus pais, Selma e Sérgio, por todo
amor, apoio, confiança, e por sempre fazerem de tudo para me proporcionar uma
excelente educação. Ao meu pai que, mesmo fisicamente distante, sempre procurou me
acalmar em momentos de crise e me fazia ver os problemas como algo simples e
passageiro. Em especial à minha mãe, pelas concessões que fez em prol da minha
formação e por sempre estar ao meu lado, preocupada com as inúmeras noites viradas e
me confortando nos momento mais críticos.
À minha irmã, Carolina, pelo preocupação, companheirismo e paciência.
Aos meus demais familiares, por todo o carinho que sempre me deram.
Aos amigos que fiz ao longo da faculdade, por tornaram essa trajetória mais
alegre. Em especial à minha amiga Natália, com a qual desenvolvi este trabalho e que
também contribuiu de forma essencial para a conclusão do curso de graduação.
Aos demais amigos, por compreenderem meus momentos de ausência.
Ao professor e orientador Heraldo, pela sua disponibilidade e atenção durante o
desenvolvimento deste projeto.
E por fim ao coordenador Casé, por sempre se mostrar solícito para ajudar com
os mais variados problemas.
vi
RESUMO
Este trabalho de conclusão de curso tem como finalidade encontrar soluções
atuais para problemas identificados na Universidade, bem como melhorar as atividades
já existentes, de forma a inserir a Universidade no contexto tecnológico e facilitar os
processos necessários para seu funcionamento.
Para tal, foi sugerido o projeto de um aplicativo destinado a usuários da
Universidade em geral, sendo eles professores, alunos e funcionários de diversas áreas.
Separamos os principais problemas em quatro temas: Disciplinas, Alimentação,
Biblioteca e Transporte, sendo os três últimos abordados na referência [1]. Inicialmente,
descrevemos cada um deles e identificamos a solução atual adotada. Em um segundo
momento, detalhamos as soluções propostas.
Como forma de comprovar a viabilidade do aplicativo, as seções de Disciplinas
e Alimentação foram desenvolvidas para o sistema Android, sendo a última abordada na
referência [1]
Palavras-Chave: desenvolvimento de software, automatização de tarefas, processos da
universidade
vii
ABSTRACT
This final paper is intended to find solutions to problems identified at the
University as well as improve existing activities in order to insert the University in the
technological context and facilitate the required processes for its operation.
To this end, the project of a mobile app for the users of the university in general,
that is, teachers, students and staff from several areas was suggested. We separated the
main problems in 5 themes: Disciplines, Food, Library and Transportation, the last three
covered in reference [1]. Initially, we described each of them and identified the current
solution adopted. In a second step, we detail the proposed solutions.
In order to prove the viability of the app, the sections of Disciplines and Food
were developed for the Android system, the last one covered in reference [1].
Key-words: software development, task automation, university processes
viii
SIGLAS
UFRJ – Universidade Federal do Rio de Janeiro
CT – Centro de Tecnologia
SISU – Sistema de Seleção Unificada
IDE – Integrated Development Environment
BOA – Boletim de Orientação Acadêmica
API – Application Programming Interface
SO – Sistema Operacional
ix
Sumário
INTRODUÇÃO......................................................................................................................... 3
1.1 – Tema .................................................................................................................................... 3
1.2 – Delimitação .......................................................................................................................... 3
1.3 – Justificativa ........................................................................................................................... 4
1.4 – Objetivos .............................................................................................................................. 4
1.5 – Metodologia ......................................................................................................................... 4
1.6 – Descrição .............................................................................................................................. 5
POSICIONAMENTO .............................................................................................................. 6
2.1– Oportunidade de Negócio ..................................................................................................... 6
2.2– Descrição dos problemas ...................................................................................................... 6
2.3– Sentença de Posição do Produto ........................................................................................... 9
2.4– Visão Geral do Produto ......................................................................................................... 9
2.5– Escopo ................................................................................................................................. 10
REVISÃO DAS TECNOLOGIAS UTILIZADAS ........................................................ 11
3.1– Android ............................................................................................................................... 11
3.2– SQLite .................................................................................................................................. 12
3.3– Google ................................................................................................................................. 13
GERENCIAMENTO DE USUÁRIOS ............................................................................. 15
4.1– Resumo dos envolvidos e usuários ....................................................................................... 15
4.2– Modelagem dos Casos de Uso .............................................................................................. 15
4.3– Diagrama de Caso de Uso ..................................................................................................... 16
4.4– Funcionamento .................................................................................................................... 16
DISCIPLINAS ........................................................................................................................ 19
5.1– Resumo dos envolvidos e usuários ....................................................................................... 19
5.2– Modelagem dos Casos de Uso .............................................................................................. 20
5.3– Diagrama de Caso de Uso ..................................................................................................... 21
x
5.4– Funcionamento .................................................................................................................... 21
CONCLUSÃO ........................................................................................................................ 27
6.1– Principais dificuldades ......................................................................................................... 27
BIBLIOGRAFIA ................................................................................................................... 30
APÊNDICE A ......................................................................................................................... 32
A.1– Implementação das Classes .................................................................................................. 32
APÊNDICE B ......................................................................................................................... 47
B.1– Mind Map ............................................................................................................................ 47
1
Lista de Figuras
Figura 1 - Market share dos sistemas operacionais para celulares, considerando o
mercado brasileiro. (fonte statcounter.com) ................................................................... 11
Figura 2 - Diagrama de Casos de Uso do Gerenciamento de Usuários .......................... 16
Figura 3 – Tela Inicial .................................................................................................... 16
Figura 4 – Tela de contas ................................................................................................ 17
Figura 5 – Permissões necessárias .................................................................................. 17
Figura 6 – Tela do Menu Principal ................................................................................. 18
Figura 7 - Diagrama de Casos de Uso de Disciplinas .................................................... 21
Figura 8 – Menu de Disciplinas ...................................................................................... 22
Figura 9 – Inserção das situações das disciplinas ........................................................... 23
Figura 10 – Grade do dia ................................................................................................ 24
Figura 11 – Pop-up com local e status da aula ............................................................... 25
Figura 12 – Lista com disciplinas a serem avaliadas...................................................... 26
Figura 13 – Questionário para avaliação de disciplinas ................................................. 26
Figura 14 – Parte I do Mind Map ................................................................................... 47
Figura 15 – Pate II do Mind Map ................................................................................... 48
2
Lista de Tabelas
Tabela 1 – Sentença de Posição ........................................................................................ 9
Tabela 2 - Resumo dos envolvidos e usuários do Gerenciamento de Usuários ............. 15
Tabela 3 - Casos de Uso do Gerenciamento de Usuários ............................................... 15
Tabela 4 – Resumo dos envolvidos e usuários de Disciplinas ....................................... 19
Tabela 5 – Casos de Uso de Disciplinas ......................................................................... 20
3
Capítulo 1
Introdução
1.1 – Tema
O tema do trabalho é o estudo das atividades da universidade, tais como
orientação acadêmica, suporte ao aluno, alimentação, transporte e biblioteca. Dessa
forma, deseja-se aperfeiçoar tais processos, por meio de tecnologias acessíveis a fim de
modernizar e tornar mais prático o cotidiano de todos que estão envolvidos no ambiente
acadêmico, sejam eles alunos, professores ou demais colaboradores.
Para tal, serão utilizados conhecimentos da área de computação adquiridos ao
longo do curso. Mais precisamente, assuntos como banco de dados, linguagem de
programação e desenvolvimento de aplicativos.
O presente trabalho abordará o desenvolvimento dos módulos Gerenciamento de
Usuário e Disciplinas. Os módulos Alimentação, Biblioteca e Transporte são abordados
na referência [1].
1.2 – Delimitação
O objeto de estudo é a Universidade Federal do Rio de Janeiro (UFRJ), tomando
como base o Centro de Tecnologia (CT). Atualmente, com o avanço da tecnologia, cada
vez mais os processos diários estão sendo automatizados, porém nota-se que as
atividades da universidade não estão acompanhando tal evolução.
O projeto estuda atividades comuns a diversas faculdades, deste modo uma vez
comprovada a aplicabilidade do projeto neste centro, o modelo poderia, então, ser
implementado na universidade como um todo, e posteriormente, em demais instituições
de ensino.
O estudo visa atender às necessidades de todos os envolvidos no ambiente
acadêmico: alunos, professores e demais servidores.
4
1.3 – Justificativa
Nos últimos anos, estimulados por financiamentos governamentais e parcerias
entre universidades, os intercâmbios acadêmicos, especialmente internacionais, têm
aumentado significativamente. Além disso, com as mudanças na forma de ingresso nas
Universidades, realizada agora por meio do Sistema de Seleção Unificada (SISU), o
número de alunos que estudam em Universidades fora de sua cidade ou mesmo de seu
estado de origem também sofreu grande aumento.
Somando-se os dois fenômenos citados acima, nota-se que há uma exigência
maior dos serviços oferecidos pela universidade quando comparada as demais.
1.4 – Objetivos
O objetivo do projeto é, portanto, sugerir um modelo que integre e otimize os
processos já existentes e também novos métodos a fim de complementar o sistema com
um todo. Mais especificamente, pretende-se (1) enumerar as principais deficiências
identificadas no cotidiano do ambiente universitário; (2) analisar possíveis melhorias
para tais falhas; e (3) propor soluções tecnológicas apropriadas para determinados
casos.
1.5 – Metodologia
A fim de identificar o escopo inicial das principais dificuldades enfrentadas por
aqueles que utilizam os serviços da universidade, será realizado um levantamento
baseado em experiências pessoais e observações dos meios de comunicação entre
alunos, como por exemplo, o polimail e grupos no Facebook.
Uma vez identificadas tais deficiências, será feito um mapeamento através de
ferramentas de mind mapping e, então, serão analisadas propostas de soluções
empregando tecnologias especificas para cada caso e também avaliar sua viabilidade.
Para implementação, será usado o software Android Studio e outras ferramentas
que possam ser necessárias para a modelagem das soluções.
5
1.6 – Descrição
O Capítulo 2 trata das soluções atuais adotadas, com uma descrição detalhada de
cada problema identificado. Com isso, foi possível determinar, neste mesmo capítulo, o
posicionamento do produto no mercado, uma visão geral do mesmo e seus requisitos.
O Capítulo 3 apresenta os conceitos e tecnologias necessárias para o
desenvolvimento do projeto e também discorre sobre a justificativa da escolha de cada
ferramenta.
O projeto de cada seção do aplicativo junto com a descrição das soluções
implementadas são abordados nos Capítulos 4 e 5. No Capítulo 4 será exposto como
ocorre o gerenciamento dos usuários do sistema. O Capítulo 5 descreve como é feito o
controle das disciplinas.
Por fim, as conclusões e trabalhos futuros são apresentados no Capítulo 6.
6
Capítulo 2
Posicionamento
2.1– Oportunidade de Negócio
Observamos a oportunidade de desenvolver o aplicativo neste setor, pois não há
qualquer solução completa para os problemas observados dentro da universidade que se
adequem ao atual cenário tecnológico, onde grande parte das atividades diárias é
realizada por meio de softwares.
2.2– Descrição dos problemas
Com base no objeto de estudo mencionado acima, UFRJ, identificamos as
atividades mais criticadas pelos usuários dentro da universidade e também situações em
que não há sequer solução para o problema encontrado. Organizamos as falhas
identificadas e as soluções utilizadas atualmente, nos tópicos abaixo.
a. Disciplinas
1.
Problema identificado:
Os alunos tendem a se inscrever nas disciplinas optativas de
escolha condicionada com base nos horários disponíveis e
indicações dos colegas. Há pouca informação quanto à linha de
especificação das disciplinas.
Solução atual disponível:
O fluxograma do curso é o único documento em que estão
relacionadas todas as disciplinas e suas dependências (requisitos)
umas com as outras. Ainda assim, não é de fácil acesso; está
disponível nos quadros de aviso, que estão localizados nos
corredores da faculdade, e entregue no momento do ingresso à
7
universidade, mas não é possível encontrá-la no SIGA, por
exemplo, principal meio de informação do aluno em relação às
disciplinas e sistema utilizado para realizar as inscrições,
momento no qual o aluno necessita desta informação.
2.
Problema identificado:
No início de cada período, os alunos precisam saber em que salas
serão ministradas as aulas em que se inscreveram,
preferencialmente, com certa antecedência para que não haja
perda de tempo em busca do local. Como é necessário cursar
disciplinas de escolha livre e também, como há equivalência entre
alguns cursos, muitas vezes os alunos encontram-se em blocos,
centros ou até mesmo campus que nunca estiveram antes e,
portanto, não conhecem a estrutura física do local e a organização
das salas de aula, ficando desorientados em relação à localização.
Solução atual disponível:
Existe uma listagem impressa contendo a relação entre todas as
disciplinas e suas salas de aula, entretanto não há uma convenção
entre todos os cursos e unidades da UFRJ sobre onde ficará
disponível esta lista física no início de cada período, portanto,
caso o aluno vá cursar uma matéria em uma unidade a qual não
conhece, terá dificuldades primeiramente em descobrir onde fica
disponível esta relação e posteriormente, em saber onde se
encontram as salas descritas nela.
Outro ponto a ser destacado é que no início do período, todos os
alunos precisam desta relação, portanto, uma lista física não é a
forma mais prática de atender a todos no momento de alta
procura. Além disso, a lista contém todas as cadeiras que serão
lecionadas naquele centro e cada aluno precisa da informação
apenas das matérias em que está inscrito, com isso, cada pessoa
8
leva um tempo desnecessário por se tratar de um documento
generalista.
3.
Problema identificado:
É comum os alunos buscarem dados sobre a qualidade das
disciplinas e dos professores antes da inscrição. Normalmente as
opiniões das pessoas que já cursaram as matérias são a maior
fonte de informação, na maioria das vezes, por meio de conversas
informais e redes sociais, portanto elas não estão consolidadas e
documentadas em nenhum lugar específico, de forma a facilitar a
todos que busquem essa informação. Além disso, quando
encontradas, essas opiniões geralmente não são muito objetivas.
Solução atual disponível:
Não há nenhuma solução disponível por parte da própria UFRJ.
As soluções encontradas pelos alunos são informais, como
conversas ou redes sociais.
4.
Problema identificado:
Muitas vezes os professores têm imprevistos que os
impossibilitam de comparecer à UFRJ para suas aulas ou, apenas,
de chegar no horário. Pode acontecer de o aluno ter ido à
universidade apenas para assistir a esta determinada aula que não
haverá ou estar esperando por ela no último horário. Existem
momentos também em que o aluno gostaria de ficar estudando na
sala de estudos ou na biblioteca, muitas vezes com outros colegas,
mas é necessário estar em frente à sala de aula aguardando o
professor chegar.
Solução atual disponível:
9
Não há solução implementada para agilizar a comunicação em
relação ao status que a aula se encontra, a não ser que o professor
comunique à secretaria ou envie um e-mail avisando do
imprevisto.
2.3– Sentença de Posição do Produto
Para Universidades.
O Aplicativo é um sistema para atividades e processos universitários.
Que integra diversos processos, otimizando-os e modernizando-os.
Diferente de processos manuais atualmente utilizados ou das soluções tecnológicas desenvolvidas isoladamente.
Nosso produto é específico, integrado e intuitivo.
Tabela 1 – Sentença de Posição
2.4– Visão Geral do Produto
a. Perspectiva do Produto
O aplicativo deve garantir o mesmo resultado e funcionamento
dos processos já empregados pela UFRJ, mas de forma mais prática e
modernizada.
Futuramente, poderá agregar outros sistemas existentes para
processos isolados, bem como o atual sistema oficial da UFRJ utilizado
para inscrições de disciplinas, o SIGA, e também acrescentar novas
funcionalidades que se tornem necessárias.
b. Suposições e Dependências
Para o funcionamento previsto para o aplicativo, pressupõe-se o
correto cadastramento dos dados por parte do usuário final (Aluno,
Professor ou Administrador).
10
c. Requisitos do Produto
O aplicativo empregará plataforma Android, podendo ser
utilizado em qualquer aparelho celular ou tablet com este sistema
operacional e que possua, no mínimo, o sistema Android 2.2 (Froyo).
Para realizar login no aplicativo, é necessário possuir uma conta Google
ou de qualquer outro domínio que seja possível conectar a partir do
Google, como por exemplo, @poli.ufrj.br.
Além disso, para ter acesso a algumas informações é necessário
que o dispositivo possua acesso à internet.
2.5– Escopo
Para cada problema listado é necessário planejar o projeto de engenharia para
então implementar cada um deles. De forma a demonstrar a viabilidade do projeto,
tomamos o tópico “Disciplinas” (considerando o perfil de usuário “Aluno”) como
exemplo para realizar o projeto e desenvolvê-lo, como pode ser vistos na seção a seguir.
11
Capítulo 3
Revisão das Tecnologias Utilizadas
3.1– Android
O Android é um sistema operacional (SO) desenvolvido atualmente pela
Google. Seu principal foco são os smartphones, mas possui também versões para
tablets, smartwatches e TVs.
A escolha desse sistema operacional para o projeto se deu pela sua facilidade
tanto uso quanto de desenvolvimento de aplicativos e também pela sua popularidade: o
Android é encontrado atualmente em mais de 1 (um) bilhão de dispositivos (Android,
2015), possuindo o maior market share de SO para celulares. Analisando os dados do
mercado brasileiro, se fizermos uma breve comparação com seu principal concorrente
(iOS), nos últimos 18 meses o Android apresentou, em média, mais que cinco vezes o
número de usuários do SO da Apple.
Figura 1 - Market share dos sistemas operacionais para celulares, considerando o mercado
brasileiro. (fonte statcounter.com)
0%
10%
20%
30%
40%
50%
60%
70%
80%
90%
100%
Market Share dos SO para Celulares no Brasil
Outros
Series 40
Windows Phone
iOS
Android
12
Quanto às ferramentas para desenvolvimento de aplicativos para o SO em
questão, a Google disponibiliza um Ambiente de Desenvolvimento Integrado (IDE, na
sigla em inglês) oficial, o Android Studio. A IDE possui diversas vantagens tais como:
Bibliotecas Open-Source;
Extensa quantidade de informações disponibilizada em fóruns e sites
proprietários;
Programação em linguagem Java;
Integração com sistemas de controle de versão (por exemplo: Git);
Diversas APIs disponíveis para integração a sistemas/tecnologias
amplamente utilizados.
No que diz respeito a armazenamento, o Android oferece opções variadas que
suprem diferentes necessidades do desenvolvedor. Dentre as disponíveis, gostaríamos
de destacar o SQLite, que será descrito em seguida, e também o Shared Preferences,
que utiliza um modelo key-value para armazenar/recuperar tipos de dados primitivos.
3.2– SQLite
SQLite é uma biblioteca open-source desenvolvida em linguagem C que
implementa um mecanismo de banco de dados SQL de forma muito simples. Sua
facilidade de uso se da devido a:
Implementa grande parte do padrão SQL (sintaxe/palavras-chave);
Não possui um processo de servidor a parte;
A leitura e escrita são feitas diretamente em um arquivo no dispositivo;
O sistema Android já suporta automaticamente a ferramenta, logo não
existe a necessidade de instalação.
Uma das maneiras de criar um banco de dados em uma aplicação é através de
uma Interface de Programação de Aplicações (API, na sigla em inglês). A API
disponibiliza classes que permitem criar e manipular o banco. Para tal, é necessário
estender a classe SQLiteOpenHelper e a partir daí é possível manipular o banco
13
utilizando querys comuns a sistemas SQL. Outra vantagem dessa ferramenta é que no
ambiente Android, os bancos de dados gerados por um aplicativo podem ser acessados
apenas por classes do mesmo, portando as informações do usuário não ficam expostas a
outras aplicações.
3.3– Google
a. Google Plus
O Google Plus é uma rede social desenvolvida pela Google. A
rede possui diversas ferramentas como:
Círculos, que permitem organizar seus amigos por grupos;
Hangout on Air, que permite transmitir vídeos online via Youtube;
Comunidades, que permitem que os membros compartilhem
imagens, comentário, eventos, dentro outros, sobre um
determinado tema;
Uma grande vantagem da rede é que ela possui total integração
com demais serviços oferecidos pela Google, como por exemplo, o
Gmail.
b. Google Play Services
A Google disponibiliza uma plataforma que permite integrar
alguns de seus serviços, como por exemplo, Google Maps e Google+, a
um aplicativo. Assim como ocorre no caso do SQLite, essas integrações
também ocorrem via uma API.
i. Google+ Android API: Google Sign-In
Para poder incluir essa funcionalidade no aplicativo, é
necessária a instalação do Google Play Services SDK no Android
Studio.
Essa API possibilita que a autenticação de usuário seja feita de
forma simples e segura. O login é feito através de uma conta Google já
14
existente, portanto não existe a necessidade de criar um usuário e senha.
Além disso, conta com toda a parte de segurança de autenticação dos
sistemas da Google (OAuth 2.0).
Uma vez feita a validação do usuário, é possível coletar dados
como nome, foto e outras informações caso o usuário tenha um perfil
ativo no G+. É possível ainda interagir na rede social da Google, por
exemplo criando e visualizando posts.
15
Capítulo 4
Gerenciamento de Usuários
Conforme descrito acima, para que o usuário tenha acesso ao aplicativo, é
necessário que ele possua uma conta válida. Visando facilitar o registro dos usuários e
levando em conta que todos os alunos possuem um e-mail da própria UFRJ, o qual pode
ser acessado através do Google, utilizamos a API Google Play Services.
4.1– Resumo dos envolvidos e usuários
Nome Descrição Responsabilidades
Usuário Usuário final Cadastrar seus dados utilizando um e-mail Google.
Tabela 2 - Resumo dos envolvidos e usuários do Gerenciamento de Usuários
4.2– Modelagem dos Casos de Uso
#UC Nome da UC Descrição
UC-01 Registrar-se Definir qual conta será utilizada neste aplicativo e inserir sua senha.
UC-02 Efetuar Login Autenticação de usuários cadastrados no sistema.
UC-03 Efetuar Logout Desconectar-se do aplicativo de forma a não visualizar mais seu menu e funcionalidades.
UC-04 Revogar Acesso
Deixar de ter permissão para acessar o menu e as funcionalidades do aplicativo. É necessário um novo cadastro.
Tabela 3 - Casos de Uso do Gerenciamento de Usuários
16
4.3– Diagrama de Caso de Uso
Figura 2 - Diagrama de Casos de Uso do Gerenciamento de Usuários
4.4– Funcionamento
Em seu primeiro uso, antes de registrar-se no aplicativo, em sua tela inicial
encontra-se o botão para realizar o login.
Figura 3 – Tela Inicial
No momento em que o botão de login é clicado, aparece uma tela pop-up com as
contas deste usuário identificadas pelo Google bem como a possibilidade de adicionar
uma conta que não está listada. Caso seja o primeiro acesso, após escolher a conta que
será utilizada, é necessário permitir que o Google utilize algumas informações
vinculadas a esta conta.
17
Figura 4 – Tela de contas
Figura 5 – Permissões necessárias
Após o login ser efetuado com sucesso, serão exibidas as informações do
usuário no topo na tela, o menu, e os botões de logout e revoke access.
18
Figura 6 – Tela do Menu Principal
Após este procedimento, se o usuário desejar fechar o aplicativo e retornar mais
tarde, seus dados estarão salvos e não é necessário efetuar login novamente.
Caso o usuário deseje se desconectar da conta para, por exemplo, utilizar uma
diferente, basta clicar no botão “Logout from Google”, que será levado à primeira tela
(Figura 2). Caso o usuário deseje desvincular sua conta ao aplicativo, basta clicar no
botão “Revoke Access” e também retornará a tela inicial (Figura 2). No primeiro caso,
se o usuário desejar acessar novamente o aplicativo com a mesma conta, será levado
automaticamente para a tela vista acima (Figura 5). No último caso, se o usuário desejar
conectar-se novamente, o procedimento funcionará como se fosse seu primeiro acesso,
sendo necessário concordar com as permissões mais uma vez.
19
Capítulo 5
Disciplinas
5.1– Resumo dos envolvidos e usuários
Nome Descrição Responsabilidades
Administrador Administrador do Aplicativo Manter o banco de dados do
fluxograma atualizado.
Aluno Usuário final com determinadas restrições e direitos.
Cadastrar seu histórico de disciplinas cursadas e em andamento.
Registrar opiniões sobre as matérias já cursadas.
Professor Usuário final com determinadas restrições e direitos.
Cadastrar as disciplinas que lecionará no período atual.
Informar o status de suas aulas.
Tabela 4 – Resumo dos envolvidos e usuários de Disciplinas
20
5.2– Modelagem dos Casos de Uso
De forma a modelar a seção de Disciplinas, organizamos os casos de usos na
tabela abaixo.
#UC Nome da UC Descrição
UC-01 Avaliar disciplina Registrar sua opinião na pesquisa do Google+.
UC-02 Visualizar opinião sobre disciplina
Acessar a pesquisa do Google+.
UC-03 Definir disciplina do período atual
Acessar a listagem de disciplinas por período e marcar a checkbox onde diz "cursando".
UC-04 Definir disciplina já cursada
Acessar a listagem de disciplinas por período, clicar onde diz "concluída" e confirmar “sim” no alerta que aparecerá na tela.
UC-05 Visualizar grade Acessar a opção grade e visualizar as disciplinas do período atual.
UC-06 Visualizar localização da aula Clicar em cima da disciplina presente na grade. Surgirá uma mensagem indicando a sala de aula.
UC-07 Visualizar Status da aula Clicar em cima da disciplina presente na grade. Surgirá uma mensagem indicando o status da aula.
UC-08 Definir Status da aula Clicar em cima da disciplina presente na grade. Surgirá uma mensagem, onde é possível determinar o status da aula.
UC-09 Atualizar Base de Dados Atualizar a Base de dados com as disciplinas atualizadas.
Tabela 5 – Casos de Uso de Disciplinas
21
5.3– Diagrama de Caso de Uso
Figura 7 - Diagrama de Casos de Uso de Disciplinas
5.4– Funcionamento
Para gerar o banco de dados via SQLite, foi utilizado um arquivo de texto
(extensão .txt) contendo toda a grade de disciplinas do curso de Engenharia Eletrônica e
de Computação. O arquivo continha uma sequencia de caracteres onde o ponto-e-
vírgula (“;”) foi utilizado como delimitador dos campos principais e dois pontos(“:”)
para os subcampos:
Código;Nome;Período;Créditos;PR1:PR2:PR3;DS1:DS2:DS3;Status
Onde PR indica o(s) pré-requisito(s) da matéria em questão, e DS indica o(s)
dia(s) da semana no(s) qual(is) a matéria é lecionada. Exemplo:
22
EEL410; Eletronica II;4; 5; EEL315;-;-;TER:QUI;H209;Concluída
A partir da leitura desse arquivo foi possível criar o banco de dados utilizando
uma classe que estende a SQLiteOpenHelper. Uma vez criada essa base é possível fazer
a leitura dessa informação e, então, popular a ListView.
Ao clicar em Disciplinas, será exibido um novo menu com as opções Grades,
Andamento e Qualidade (figura 8).
Figura 8 – Menu de Disciplinas
a. Andamento
Aqui serão disponibilizadas informações quanto ao progresso do
usuário na graduação. Será exibido um ListView com todas as possíveis
disciplinas da sua graduação, separadas por período. Cada item da lista
terá um checkbox à esquerda para ser selecionado quando a matéria está
em andamento, ou seja, pertence ao período atual. Clicando sobre o
status da disciplina, à direita, este irá alterar para “Concluída”.
23
Figura 9 – Inserção das situações das disciplinas
Para salvar tais informações será utilizada a ferramenta de banco
de dados SQLite, conforme descrito acima. Utilizando esta ferramenta,
os dados coletados serão salvos e utilizados para montar a grade do
usuário.
b. Grade
Selecionando a opção “Grade”, o sistema compara o dia de hoje
com os dias de cada disciplina (informação que é salva no banco de
dados, conforme mencionado acima) e então exibe apenas as matérias do
dia da semana equivalente. Além disso, verifica também a situação da
disciplina, isto é, qual status foi inserido na seção “Andamento” para
exibir somente as disciplinas com o status “cursando”. Estas serão
informadas através de um ListView.
24
Figura 10 – Grade do dia
Clicando em cima do nome da disciplina, aparecerá uma janela
pop-up contendo as seguintes informações, também coletadas do banco
de dados:
Localização: sala na qual a disciplina será ministrada neste dia.
Status: situação na qual se encontra a disciplina naquele
momento, podendo ser iniciada, atrasada ou cancelada.
25
Figura 11 – Pop-up com local e status da aula
c. Qualidade
Nesta seção estarão listadas todas as disciplinas presentes no
fluxograma do curso do usuário, organizadas por período. Ao clicar em
uma disciplina, o usuário será levado a uma postagem em uma
Comunidade do Google+, exclusiva para aquela matéria, com uma
pergunta sobre a qualidade da disciplina, com cinco opções para
resposta: péssima, ruim, média, boa e excelente.
26
Figura 12 – Lista com disciplinas a serem avaliadas
Figura 13 – Questionário para avaliação de disciplinas
O usuário poderá abrir o questionário apenas para consulta,
acessando na seta do canto superior direito a opção “ver resultados”.
Caso o usuário queira dar sua opinião a respeito da disciplina
selecionada, basta clicar em cima da opção desejada e seu voto será
computado. Só é possível opinar uma vez para cada disciplina, portanto,
caso o usuário já tenha respondido a determinada disciplina, sua nova
resposta substituirá a anterior.
Caso queira, o usuário também pode inserir comentários sobre a
disciplina em questão.
27
Capítulo 6
Conclusão
Este trabalho apresentou a proposta para um sistema que visa facilitar o
cotidiano dos alunos, professores e demais colaboradores da UFRJ. Para tal foi
desenvolvido o projeto de um aplicativo que tem como objetivo (i) Gerenciar o
fluxograma de disciplinas e avaliar a qualidade das mesmas, (ii) Promover o acesso à
informação sobre as opções disponíveis de alimentação e também avaliar sua qualidade,
(iii) Melhorar os processos relacionados a locação de livro e demais obras, e (iv)
Facilitar a busca de vagas no estacionamentos e também disponibilizar estimativas
sobre tempos de trajeto, sendo os três últimos descritos na referência [1].
Foram levantados os principais problemas e falhas encontrados no ambiente
acadêmico e as atuais tentativas de solução para os mesmos. A fim de melhorar esses
processos, foram propostas novas soluções mais práticas e eficientes a serem
implementadas via aplicativo para celular. As tecnologias utilizadas e a justificativas de
escolha das mesma foram previamente apresentadas.
Optou-se por implementar as seções “Gerenciamento de Usuários”,
“Disciplinas” e “Alimentação”, sendo este último abordado na referência [1], a fim de
comprovar a eficiência do projeto. O sistema foi desenvolvido através da IDE Android
Studio utilizando a linguagem de programação Java, a biblioteca SQLite, que
implementou o banco de dados, e também a rede social Google+. Os testes foram
realizados através de um emulador disponibilizado pelo próprio Android Studio, que
possui funcionamento idêntico ao de um celular com sistema operacional Android. Os
resultados obtidos foram satisfatórios e o aplicativo mostrou-se, então, eficiente para o
que havia sido proposto.
6.1– Principais dificuldades
Ao longo do desenvolvimento do projeto, foram encontradas algumas
dificuldades decorrentes das tecnologias escolhidas. Alguns problemas puderam ser
28
total ou parcialmente contornados, já outros necessitam de um estudo mais profundo e
serão melhor descritos em trabalhos futuros.
Na seção de “Gerenciamento de Usuários”, a ideia original era que o e-
mail utilizado para login tivesse exclusivamente extensão @poli.ufrj.br
(ou @ufrj.br caso o aplicativo englobasse a universidade como um todo).
O sistema do Google+ é capaz sim de fazer esse tipo de verificação,
porem é necessário que quando realizado o cadastro do aplicativo na
plataforma de desenvolvimento da Google seja feito o cadastro do
domínio desejado (no caso poli.ufrj.br ou ufrj.br). Esse tipo de cadastro
precisa ser validado com o administrator do domínio, o que inviabilizou
a etapa uma vez que não possuímos essa permissão.
Na seção de “Disciplinas” foi identificada a necessidade de
armazenamento de dados. Na maior parte da seção “Disciplinas”, uma
vez que os dados eram únicos de cada usuário, podemos contornar o uso
de um banco de dados no modelo cliente-servidor e optou-se pelo uso do
SQLite. Já em partes que necessitam integração entre usuários, como um
aluno visualizar o status de uma aula (atualizada pelo professor), esse
modelo de banco de dados se tornou necessário.
Na seção “Disciplinas”, citamos que um dos problemas seria quanto à
localização da sala. Em parte, esta questão foi solucionada, pois ao clicar
na disciplina desejada, é exibida uma janela pop-up com a referência da
sala. Entretanto, caso o aluno não conheça o prédio e a disposição das
salas, ainda assim será uma dificuldade. Para solucionar este caso, nossa
solução seria integrar o Google Maps ao aplicativo, pois ele já possui
diversos estabelecimentos mapeados internamente, porém a UFRJ ainda
não foi explorada nessa funcionalidade. Caso a UFRJ seja mapeada pelo
Google Maps, a sugestão seria integrá-lo ao aplicativo, de forma que, ao
clicar na disciplina desejada, o usuário poderá acessar o Google Maps,
que criará um caminho do seu local até a sala.
Inicialmente, tentamos utilizar a inserção das disciplinas pelo usuário de
forma mais automatizada: o usuário faria download do Boletim ou
Histórico no formato .pdf e o próprio sistema leria as informações e
29
organizaria em já cursadas anteriormente e cursando no período atual.
Após testarmos algumas bibliotecas disponíveis para leitura de pdf,
percebemos que, pelo formato do Boletim e do Histórico, com diversas
tabelas e colunas, a leitura não saía como desejada, então não
conseguimos concluir como o projeto inicial. Adicionalmente, as
bibliotecas que encontramos realizava a leitura da primeira linha do
arquivo, porém, para realizar a leitura completa, era necessário pagar
pelo uso da biblioteca, o que tornaria o projeto mais caro e poderia
impactar na sua viabilidade.
Conforme já dito acima, a intenção do projeto é facilitar diversas
atividades da universidade e ainda integrar os processos em uma única
solução. Algumas atividades já possuem soluções isoladas, como por
exemplo, o SIGA, sistema para inscrição e consulta de disciplinas e o
Minerva, sistema para busca de obras das Bibliotecas da UFRJ.
Idealmente, o aplicativo incorporaria todas elas, de forma que o usuário
já estaria acostumado com o seu uso e as otimizaria, acrescentando
funcionalidades extras ou aprimorando as existentes.
.
30
Bibliografia
[1] Natália França Tavares - Universidade Inteligente: Soluções Tecnológicas para
Melhoria do Cotidiano Universitário – Módulos alimentação, biblioteca e
transporte.
[2] “Android”
Acessado em julho de 2015. https://www.android.com
[3] “Google Developers”
Acessado em julho de 2015. https://developers.google.com/+/
[4] Suelen Goularte Carvalho. Android Studio - Vantagens e Desvantagens em
relação ao Eclipse. Revista iMasters #08 - Open web: ultrapassando os limites
do HTML5 Revista iMasters n.08 - Novembro/2013 (pagina 42)
[5] “Android - Persistência de dados usando SQLite.” Luciano Luzzi
Acessado em julho de 2015.
http://www.mobiltec.com.br/blog/index.php/android-persistencia-de-
dados-usando-sqlite/
[6] “Global Stats Counter”
Acessado em julho de 2015. http://gs.statcounter.com/
[7] “Android Developers”
Acessado em julho de 2015. https://developer.android.com/
[8] “Android Developers Blog”
Acessado em julho de 2015. http://android-developers.blogspot.com.br/
[9] “Sensores de Vagas”
31
Acessado em julho de 2015. http://www.prosiga.com.br/controle-
inteligente/
[10] “Base Minerva UFRJ”
Acessado em julho de 2015. www.minerva.ufrj.br/
[11] “Proto IO”
Acessado em Julho de 2015. http://proto.io/
[12] “Google Drive”
Acessado em Julho de 2015. https://drive.google.com
32
Apêndice A
A.1– Implementação das Classes
Este apêndice contem as principais classes utilizadas para implementar as tarefas
descritas nos capítulos 4 e 5.
A.1.1– Gerenciamento de Usuários
public class MainActivity extends Activity implements OnClickListener,
ConnectionCallbacks, OnConnectionFailedListener {
private static final int RC_SIGN_IN = 0;
// Logcat tag
private static final String TAG = "MainActivity";
private static final int PROFILE_PIC_SIZE = 400;
// Google client to interact with Google API
private GoogleApiClient mGoogleApiClient;
/**
* Flag que indica que um PendingIntent está ativo e previne
* que novos intents sejam iniciados
*/
private boolean mIntentInProgress;
private boolean mSignInClicked;
private ConnectionResult mConnectionResult;
private SignInButton btnSignIn;
private Button btnSignOut, btnRevokeAccess;
private ImageView imgProfilePic;
private TextView txtName, txtEmail;
private LinearLayout llProfileLayout;
private ListView menuList;
String[] menuOptions = new String[] { "Disciplinas","Alimentação", "Transporte",
"Biblioteca"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnSignIn = (SignInButton) findViewById(R.id.btn_sign_in);
btnSignOut = (Button) findViewById(R.id.btn_sign_out);
btnRevokeAccess = (Button) findViewById(R.id.btn_revoke_access);
imgProfilePic = (ImageView) findViewById(R.id.imgProfilePic);
txtName = (TextView) findViewById(R.id.txtName);
txtEmail = (TextView) findViewById(R.id.txtEmail);
llProfileLayout = (LinearLayout) findViewById(R.id.llProfile);
menuList = (ListView) findViewById(R.id.menuList);
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
menuOptions);
menuList.setAdapter(adapter);
menuList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long
id) {
Intent i;
switch (position) {
case 0:
i = new Intent(getApplicationContext(), Disciplinas.class);
33
startActivity(i);
break;
case 1:
i = new Intent(getApplicationContext(), Alimentacao.class);
startActivity(i);
break;
case 2:
i = new Intent(getApplicationContext(), Transporte.class);
startActivity(i);
break;
case 3:
i = new Intent(getApplicationContext(), Biblioteca.class);
startActivity(i);
break;
}
}
});
btnSignIn.setOnClickListener(this);
btnSignOut.setOnClickListener(this);
btnRevokeAccess.setOnClickListener(this);
mGoogleApiClient = new
GoogleApiClient.Builder(this).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).addApi(Plus.API)
.addScope(new Scope(Scopes.PROFILE)).build();
}
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
private void resolveSignInError() {
if (mConnectionResult.hasResolution()) {
try {
mIntentInProgress = true;
mConnectionResult.startResolutionForResult(this, RC_SIGN_IN);
} catch (SendIntentException e) {
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
@Override
public void onConnectionFailed(ConnectionResult result) {
if (!result.hasResolution()) {
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this,
0).show();
return;
}
if (!mIntentInProgress) {
// Armazena o ConnectionResult para uso posterior
mConnectionResult = result;
if (mSignInClicked) {
// O usuario ja clicou 'sign-in' entao e feita a tentativa
// de resolver todos os problemas
// ate que o usuario estaja logado, senao e cancelado
resolveSignInError();
}
}
}
@Override
protected void onActivityResult(int requestCode, int responseCode, Intent intent) {
if (requestCode == RC_SIGN_IN) {
if (responseCode != RESULT_OK) {
mSignInClicked = false;
}
mIntentInProgress = false;
if (!mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
}
}
34
@Override
public void onConnected(Bundle arg0) {
mSignInClicked = false;
Toast.makeText(this, "Usuário conectado!", Toast.LENGTH_LONG).show();
// Coletar informacoes do usuario
getProfileInformation();
// Atualizar a UI depois de conectar
updateUI(true);
}
/**
* Atualizar a UI, mostran/escondendo os botoes e o layout com o perfil
* */
private void updateUI(boolean isSignedIn) {
if (isSignedIn) {
btnSignIn.setVisibility(View.GONE);
btnSignOut.setVisibility(View.VISIBLE);
btnRevokeAccess.setVisibility(View.VISIBLE);
llProfileLayout.setVisibility(View.VISIBLE);
menuList.setVisibility(View.VISIBLE);
} else {
btnSignIn.setVisibility(View.VISIBLE);
btnSignOut.setVisibility(View.GONE);
btnRevokeAccess.setVisibility(View.GONE);
llProfileLayout.setVisibility(View.GONE);
menuList.setVisibility(View.GONE);
}
}
/**
* Coletar informacoes do usuario
* */
private void getProfileInformation() {
try {
if (Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null) {
Person currentPerson = Plus.PeopleApi
.getCurrentPerson(mGoogleApiClient);
String personName = currentPerson.getDisplayName();
String personPhotoUrl = currentPerson.getImage().getUrl();
String personGooglePlusProfile = currentPerson.getUrl();
String email = Plus.AccountApi.getAccountName(mGoogleApiClient);
Log.e(TAG, "Name: " + personName + ", plusProfile: "
+ personGooglePlusProfile + ", email: " + email
+ ", Image: " + personPhotoUrl);
txtName.setText(personName);
txtEmail.setText(email);
personPhotoUrl = personPhotoUrl.substring(0,
personPhotoUrl.length() - 2)
+ PROFILE_PIC_SIZE;
new LoadProfileImage(imgProfilePic).execute(personPhotoUrl);
} else {
Toast.makeText(getApplicationContext(),
"Informacao de usuário inválida", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
updateUI(false);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_sign_in:
signInWithGplus();
break;
case R.id.btn_sign_out:
signOutFromGplus();
break;
case R.id.btn_revoke_access:
revokeGplusAccess();
35
break;
}
}
private void signInWithGplus() {
if (!mGoogleApiClient.isConnecting()) {
mSignInClicked = true;
resolveSignInError();
}
}
private void signOutFromGplus() {
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
mGoogleApiClient.connect();
updateUI(false);
}
}
private void revokeGplusAccess() {
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
Plus.AccountApi.revokeAccessAndDisconnect(mGoogleApiClient)
.setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(Status arg0) {
Log.e(TAG, "User access revoked!");
mGoogleApiClient.connect();
updateUI(false);
}
});
}
}
/**
* Tarefa assincrona executada em backgroud para carregar a foto do usuario
* */
private class LoadProfileImage extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public LoadProfileImage(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
}
A.1.2– Disciplinas public class Disciplinas extends ActionBarActivity {
String[] menuOpDisciplinas = new String[] { "Grade","Andamento", "Qualidade"};
private ListView menuDisciplinas;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_disciplinas);
menuDisciplinas = (ListView) findViewById(R.id.menuDisciplinas);
ArrayAdapter<String> newAdapter =
new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
menuOpDisciplinas);
menuDisciplinas.setAdapter(newAdapter);
menuDisciplinas.setOnItemClickListener(new AdapterView.OnItemClickListener() {
36
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long
id) {
Calendar sCalendar = Calendar.getInstance();
int day = sCalendar.get(Calendar.DAY_OF_WEEK);
Intent i;
switch (position) {
case 0:
switch (day) {
case Calendar.SUNDAY:
i = new Intent(getApplicationContext(), Segunda.class);
startActivity(i);
break;
case Calendar.TUESDAY:
i = new Intent(getApplicationContext(), Terca.class);
startActivity(i);
break;
case Calendar.WEDNESDAY:
i = new Intent(getApplicationContext(),
Wednesday.class);
startActivity(i);
break;
case Calendar.THURSDAY:
i = new Intent(getApplicationContext(), Thursday.class);
startActivity(i);
break;
case Calendar.FRIDAY:
i = new Intent(getApplicationContext(), Friday.class);
startActivity(i);
break;
}
break;
case 1:
i = new Intent(getApplicationContext(), TesteAndamento2.class);
startActivity(i);
break;
case 2:
i = new Intent(getApplicationContext(), Qualidade.class);
startActivity(i);
break;
}
}
});
}
}
A.1.3– Grade public class Segunda extends ActionBarActivity {
final String[] local = new String[10];
TextView dayText;
MyDBHandler dbHandler;
MyDBHandler2 dbChecker;
String[] menuOptionsName, menuOptionsCode = new String[10];
private ListView gradeDoDia;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_segunda);
dayText = (TextView) findViewById(R.id.dayText);
dayText.setText("Olá! " + "\n" + "\n" + "Estas são suas aulas do dia:");
gradeDoDia = (ListView) findViewById(R.id.gradeDoDia);
dbChecker = new MyDBHandler2(this, null, null, 1);
dbHandler = new MyDBHandler(getApplicationContext(), null, null, 1);
menuOptionsName = dbChecker.getClassName("segunda").split(";");
menuOptionsCode = dbChecker.getClassID("segunda").split(";");
for(int i = 0; i < menuOptionsName.length; i++) {
local[i]= dbHandler.getLocal(menuOptionsCode[i]);
37
}
ArrayAdapter<String> newAdapter =
new ArrayAdapter<String>(
this, android.R.layout.simple_list_item_1, menuOptionsName);
gradeDoDia.setAdapter(newAdapter);
gradeDoDia.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(
AdapterView<?> parent, View view, int position, long id) {
AlertDialog alertDialog;
String cut;
switch (position) {
case 0:
cut = local[0].substring(0,4);
alertDialog = new AlertDialog.Builder(Segunda.this).create();
alertDialog.setTitle(menuOptionsName[0]);
alertDialog.setMessage("Local: " + cut + "\n" + "Status:
Confimada!");
alertDialog.setButton("OK", new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
alertDialog.show();
break;
case 1:
cut = local[1].substring(0,4);
alertDialog = new AlertDialog.Builder(Segunda.this).create();
alertDialog.setTitle(menuOptionsName[1]);
alertDialog.setMessage("Local: " + cut + "\n" + "Status:
Cancelada!");
alertDialog.setButton("OK", new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
alertDialog.show();
break;
case 2:
cut = local[2].substring(0, 4);
alertDialog = new AlertDialog.Builder(Segunda.this).create();
alertDialog.setTitle(menuOptionsName[2]);
alertDialog.setMessage("Local: " + cut + "\n" + "Status:
Confimada!");
alertDialog.setButton("OK", new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
alertDialog.show();
break;
case 3:
cut = local[3].substring(0, 4);
alertDialog = new AlertDialog.Builder(Segunda.this).create();
alertDialog.setTitle(menuOptionsName[2]);
alertDialog.setMessage("Local: " + cut + "\n" + "Status:
Confimada!");
alertDialog.setButton("OK", new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
alertDialog.show();
break;
case 4:
cut = local[4].substring(0, 4);
alertDialog = new AlertDialog.Builder(Segunda.this).create();
alertDialog.setTitle(menuOptionsName[2]);
alertDialog.setMessage("Local: " + cut + "\n" + "Status:
Confimada!");
alertDialog.setButton("OK", new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
alertDialog.show();
break;
}
}
});
}
}
38
A.1.4– Andamento
public class TesteAndamento2 extends ActionBarActivity implements
AdapterView.OnItemSelectedListener {
MyCustomAdapter dataAdapter = null;
TextView textView, titleText;
MyDBHandler dbHandler;
MyDBHandler2 dbChecker;
Spinner spinner;
SharedPreferences sharedpreferences, sharedprefString, getSharedprefInt;
String prename = "PREFERENCES";
String prename2 = "PREFSTRING";
String prename3 = "PREFINT";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_teste_andamento2);
titleText = (TextView) findViewById(R.id.titleText);
titleText.setText("Controle aqui as materias cursadas e em andamento:");
spinner = (Spinner) findViewById(R.id.spinner2);
spinner.setOnItemSelectedListener(this);
List<String> categories = new ArrayList<String>();
categories.add("1o Periodo");
categories.add("2o Periodo");
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, categories);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(dataAdapter);
getSharedprefInt = getSharedPreferences("spinner", Context.MODE_PRIVATE);
spinner.setSelection(getSharedprefInt.getInt("spinner",0));
getFields();
displayListView(spinner.getSelectedItemPosition());
}
private void displayListView(int position) {
loadPref2(spinner.getSelectedItem().toString());
final ArrayList<CheckMateria> materiaList = new ArrayList<CheckMateria>();
String codigo, nome, diaSemana, status, periodo;
CheckMateria itemList;
BufferedReader reader = null;
try {
reader = new BufferedReader(new
InputStreamReader(getAssets().open("123.txt")));
String mLine = reader.readLine();
switch (position){
case (0):
while (mLine != null) {
String[] message = mLine.split(";");
codigo = message[0];
nome = message[1];
periodo = message[2];
diaSemana = message[7];
status = message[9];
itemList = new CheckMateria(
codigo, nome, periodo, diaSemana, false, status);
if(periodo.equalsIgnoreCase("1"))
materiaList.add(itemList);
mLine = reader.readLine();
}
break;
39
case (1):
while (mLine != null) {
String[] message = mLine.split(";");
codigo = message[0];
nome = message[1];
periodo = message[2];
diaSemana = message[7];
status = message[9];
itemList = new CheckMateria(
codigo, nome, periodo, diaSemana, false, status);
if(periodo.equalsIgnoreCase("2"))
materiaList.add(itemList);
mLine = reader.readLine();
}
break;
}
} catch (IOException e) {
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
}
}
}
dataAdapter = new MyCustomAdapter(this, R.layout.materia_info, materiaList);
ListView listView = (ListView) findViewById(R.id.listView1);
listView.setAdapter(dataAdapter);
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
displayListView(spinner.getSelectedItemPosition());
int selPosition = spinner.getSelectedItemPosition();
SharedPreferences.Editor editor = getSharedprefInt.edit();
editor.putInt("spinner", selPosition).apply();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
public void getFields() {
dbHandler = new MyDBHandler(TesteAndamento2.this, null, null, 1);
String codigo, nome, periodo, creditos,
preRequisito_1, preRequisito_2, preRequisito_3, diaSemana, local,
status;
GradeCompletaDB gradeCompletaDB;
BufferedReader reader = null;
try {
reader = new BufferedReader(
new InputStreamReader(getAssets().open("123.txt")));
String mLine = reader.readLine();
while (mLine != null) {
String[] message = mLine.split(";");
codigo = message[0];
nome = message[1];
periodo = message[2];
creditos = message[3];
preRequisito_1 = message[4];
preRequisito_2 = message[5];
preRequisito_3 = message[6];
diaSemana = message[7];
local = message[8];
status = message[9];
gradeCompletaDB = new GradeCompletaDB(
codigo, nome, periodo, creditos,preRequisito_1,
diaSemana, local, status);
dbHandler.addMateria(gradeCompletaDB);
mLine = reader.readLine();
}
} catch (IOException e) {
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
}
}
40
}
}
private boolean loadSavedPreferences(String value) {
SharedPreferences sharedPreferences = getSharedPreferences(prename,
Context.MODE_PRIVATE);
boolean checkBoxValue = sharedPreferences.getBoolean(value, false);
if (checkBoxValue)
return true;
else
return false;
}
private String loadPref(String value) {
SharedPreferences sp = getSharedPreferences(prename2, Context.MODE_PRIVATE);
String st = sp.getString(value, "Pendente");
return st;
}
private int loadPref2(String value) {
SharedPreferences sp = getSharedPreferences(prename3, Context.MODE_PRIVATE);
int pos = sp.getInt(value, 0);
return pos;
}
public class MyCustomAdapter extends ArrayAdapter<CheckMateria> {
private ArrayList<CheckMateria> listMaterias;
public MyCustomAdapter(Context context,
int textViewResourceId,
ArrayList<CheckMateria> countryList) {
super(context, textViewResourceId, countryList);
this.listMaterias = new ArrayList<CheckMateria>();
this.listMaterias.addAll(countryList);
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
Context context = getContext();
dbChecker = new MyDBHandler2(context, null, null, 1);
final CheckMateria itemMat = listMaterias.get(position);
ViewHolder holder = null;
Log.v("ConvertView", String.valueOf(position));
sharedpreferences = getSharedPreferences(prename, Context.MODE_PRIVATE);
sharedprefString = getSharedPreferences(prename2, Context.MODE_PRIVATE);
final SharedPreferences.Editor editor = sharedpreferences.edit();
final SharedPreferences.Editor editor2 = sharedprefString.edit();
if (convertView == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.materia_info, null);
holder = new ViewHolder();
holder.code = (TextView) convertView.findViewById(R.id.code);
holder.status = (TextView) convertView.findViewById(R.id.status);
holder.name = (CheckBox) convertView.findViewById(R.id.checkBox1);
holder.status = (TextView) convertView.findViewById(R.id.status);
convertView.setTag(holder);
holder.name.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
final CheckBox cb = (CheckBox) v;
loadSavedPreferences(itemMat.getName());
loadPref(itemMat.getName());
if (cb.isChecked()) {
Toast.makeText(getApplicationContext(),
cb.getText() + ": Cursando",
Toast.LENGTH_LONG).show();
if (dbChecker.itemExists()) {
dbChecker.delMateria(itemMat.getCode());
}
GradeParcialDB materia = new GradeParcialDB(
itemMat.getCode(), itemMat.getName(),
itemMat.getDiaSemana(), "Cursando");
dbChecker.addMateria(materia);
41
editor2.putString(itemMat.getName(), "Cursando").apply();
} else {
Toast.makeText(getApplicationContext(),
cb.getText() + ": Pendente",
Toast.LENGTH_LONG).show();
if (dbChecker.itemExists()) {
dbChecker.delMateria(itemMat.getCode());
}
}
editor.putBoolean(itemMat.getName(), cb.isChecked()).apply();
editor2.putString(itemMat.getName(), "Pendente").apply();
}
});
holder.status.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
final TextView status = (TextView) v;
loadSavedPreferences(itemMat.getName());
AlertDialog alertDialog;
AlertDialog.Builder builder = new
AlertDialog.Builder(TesteAndamento2.this);
builder.setTitle(itemMat.getName());
builder.setMessage("Gostaria de concluir essa disciplina?");
builder.setPositiveButton("Sim!", new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
Toast.makeText(TesteAndamento2.this,
"concluida=" + arg1, Toast.LENGTH_SHORT).show();
if (dbChecker.itemExists()) {
dbChecker.delMateria(itemMat.getCode());
}
GradeParcialDB materia = new GradeParcialDB(
itemMat.getCode(), itemMat.getName(),
itemMat.getDiaSemana(), "Concluida");
dbChecker.addMateria(materia);
itemMat.setStatus("Concluida");
status.setText("Concluida");
editor2.putString(itemMat.getName(),
"Concluida").apply();
}
});
builder.setNeutralButton("Pendente", new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
Toast.makeText(TesteAndamento2.this,
"Pendente=" + arg1, Toast.LENGTH_SHORT).show();
if (dbChecker.itemExists()) {
dbChecker.delMateria(itemMat.getCode());
}
GradeParcialDB materia = new GradeParcialDB(
itemMat.getCode(), itemMat.getName(),
itemMat.getDiaSemana(), "Pendente");
dbChecker.addMateria(materia);
itemMat.setStatus("Pendente");
status.setText("Pendente");
editor2.putString(itemMat.getName(),
"Pendente").apply();
}
});
alertDialog = builder.create();
alertDialog.show();
}
});
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.code.setText(" (" + itemMat.getCode() + ")");
holder.name.setText(itemMat.getName());
42
holder.name.setChecked(itemMat.isSelected());
holder.name.setTag(itemMat);
holder.status.setText(loadPref(itemMat.getName()));
if (loadSavedPreferences(itemMat.getName()))
holder.name.setChecked(true);
return convertView;
}
private class ViewHolder {
TextView code;
TextView status;
CheckBox name;
}
}
}
A.1.5– Banco de dados (Contendo a grade completa do curso)
public class MyDBHandler extends SQLiteOpenHelper{
private static final int DATABASE_VERSION = 7;
private static final String DATABASE_NAME = "fluxogramaDB.db";
public static final String TABLE_FLUXOGRAMA = "fluxograma";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_CODIGO = "codigo";
public static final String COLUMN_NOME = "nome";
public static final String COLUMN_PERIODO = "periodo";
public static final String COLUMN_CREDITOS = "creditos";
public static final String COLUMN_PREREQUISITO1 = "preRequisito1";
public static final String COLUMN_DIASEMANA = "diaSemana";
public static final String COLUMN_LOCAL = "local";
public static final String COLUMN_STATUS = "status";
public MyDBHandler(Context context, String name, SQLiteDatabase.CursorFactory
factory, int version) {
super(context, DATABASE_NAME, factory, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String query = "CREATE TABLE " + TABLE_FLUXOGRAMA + "(" +
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COLUMN_CODIGO + " TEXT, " +
COLUMN_NOME + " TEXT, " +
COLUMN_PERIODO + " TEXT, " +
COLUMN_CREDITOS + " TEXT, " +
COLUMN_PREREQUISITO1 + " TEXT, " +
COLUMN_DIASEMANA + " TEXT, " +
COLUMN_LOCAL + " TEXT, " +
COLUMN_STATUS + " TEXT" +
");";
db.execSQL(query);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_FLUXOGRAMA);
onCreate(db);
}
public void addMateria(GradeCompletaDB gradeCompletaDB){
ContentValues values = new ContentValues();
values.put(COLUMN_CODIGO, gradeCompletaDB.get_codigo());
values.put(COLUMN_NOME, gradeCompletaDB.get_nome());
values.put(COLUMN_PERIODO, gradeCompletaDB.get_periodo());
values.put(COLUMN_CREDITOS, gradeCompletaDB.get_creditos());
values.put(COLUMN_PREREQUISITO1, gradeCompletaDB.get_preRequisito1());
values.put(COLUMN_DIASEMANA, gradeCompletaDB.get_diaSemana());
values.put(COLUMN_LOCAL, gradeCompletaDB.get_local());
values.put(COLUMN_STATUS, gradeCompletaDB.get_status());
SQLiteDatabase db = getWritableDatabase();
db.insert(TABLE_FLUXOGRAMA, null, values);
db.close();
}
public String getLocal(String codigo) {
String dbString = "";
SQLiteDatabase db = getWritableDatabase();
String query = "SELECT " + COLUMN_CODIGO + ", " + COLUMN_LOCAL + ", " +
COLUMN_NOME + " FROM " + TABLE_FLUXOGRAMA;
Cursor c = db.rawQuery(query, null);
43
c.moveToFirst();
while (!c.isAfterLast()) {
if (c.getString(c.getColumnIndex("codigo")) != null) {
if (c.getString(c.getColumnIndex("codigo")).equalsIgnoreCase(codigo)) {
dbString += c.getString(c.getColumnIndex("local"));
}
}
c.moveToNext();
}
db.close();
return dbString;
}
}
A.1.6– Banco de dados (Contendo o fluxograma do aluno) public class MyDBHandler2 extends SQLiteOpenHelper{
private static final int DATABASE_VERSION = 11;
private static final String DATABASE_NAME = "andamentoDB.db";
public static final String TABLE_ANDAMENTO = "andamento";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_CODIGO = "codigo";
public static final String COLUMN_NOME = "nome";
public static final String COLUMN_PERIODO = "periodo";
public static final String COLUMN_DIASEMANA = "diaSemana";
public static final String COLUMN_STATUS = "status";
public MyDBHandler2(Context context, String name, SQLiteDatabase.CursorFactory
factory, int version) {
super(context, DATABASE_NAME, factory, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String query = "CREATE TABLE " + TABLE_ANDAMENTO + "(" +
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COLUMN_CODIGO + " TEXT, " +
COLUMN_NOME + " TEXT, " +
COLUMN_PERIODO + " TEXT, " +
COLUMN_DIASEMANA + " TEXT, " +
COLUMN_STATUS + " TEXT " +
");";
db.execSQL(query);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_ANDAMENTO);
onCreate(db);
}
public void addMateria(GradeParcialDB materia){
ContentValues values = new ContentValues();
values.put(COLUMN_CODIGO, materia.get_codigo());
values.put(COLUMN_NOME, materia.get_nome());
values.put(COLUMN_PERIODO, materia.get_periodo());
values.put(COLUMN_DIASEMANA, materia.get_diaSemana());
values.put(COLUMN_STATUS, materia.get_status());
SQLiteDatabase db = getWritableDatabase();
db.insert(TABLE_ANDAMENTO, null, values);
db.close();
}
public void delMateria(String codigo){
SQLiteDatabase db = getWritableDatabase();
db.execSQL("DELETE FROM " + TABLE_ANDAMENTO + " WHERE " + COLUMN_CODIGO + "=\""
+ codigo + "\";");
}
public boolean itemExists(){
SQLiteDatabase db = getWritableDatabase();
String query = "SELECT * FROM " + TABLE_ANDAMENTO + " WHERE 1";
Cursor c = db.rawQuery(query, null);
c.moveToFirst();
while (!c.isAfterLast()) {
if (c.getString(c.getColumnIndex("codigo")) != null) {
return true;
}
44
c.moveToNext();
}
db.close();
return false;
}
public String getClassName(String day){
String dbString = "";
SQLiteDatabase db = getWritableDatabase();
String query = "SELECT * FROM " + TABLE_ANDAMENTO;
Cursor c = db.rawQuery(query, null);
c.moveToFirst();
while (!c.isAfterLast()) {
if (c.getString(c.getColumnIndex("codigo")) != null) {
String days = c.getString(c.getColumnIndex("diaSemana"));
String [] days2 = days.split(":");
for(int i = 0; i < days2.length; i++) {
if((c.getString(c.getColumnIndex("status")).equalsIgnoreCase("cursando")) &&
days2[i].equalsIgnoreCase(day)) {
dbString += c.getString(c.getColumnIndex("nome"));
dbString += ";";
}
}
}
c.moveToNext();
}
db.close();
return dbString;
}
public String getClassID(String day){
String dbString = "";
SQLiteDatabase db = getWritableDatabase();
String query = "SELECT * FROM " + TABLE_ANDAMENTO;
Cursor c = db.rawQuery(query, null);
c.moveToFirst();
while (!c.isAfterLast()) {
if (c.getString(c.getColumnIndex("codigo")) != null) {
String days = c.getString(c.getColumnIndex("diaSemana"));
String [] days2 = days.split(":");
for(int i = 0; i < days2.length; i++) {
if
((c.getString(c.getColumnIndex("status")).equalsIgnoreCase("cursando")) &&
days2[i].equalsIgnoreCase(day)) {
dbString += c.getString(c.getColumnIndex("codigo"));
dbString += ";";
}
}
}
c.moveToNext();
}
db.close();
return dbString;
}
}
A.1.7– Qualidade public class Qualidade extends Activity {
TextView textView;
ExpandableListAdapter listAdapter;
ExpandableListView expListView;
List<String> listDataHeader;
HashMap<String, List<String>> listDataChild;
@Override
protected void onCreate(Bundle savedInstanceState) {
45
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_qualidade);
TextView textView = (TextView)findViewById(R.id.textView);
textView.setText("Avalie aqui as disciplinas já cursadas!");
// get the listview
expListView = (ExpandableListView) findViewById(R.id.lvExp);
// preparing list data
prepareListData();
listAdapter = new ExpandableListAdapter(this, listDataHeader, listDataChild);
// setting list adapter
expListView.setAdapter(listAdapter);
// Listview Group click listener
expListView.setOnGroupClickListener(new
ExpandableListView.OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView parent, View v, int
groupPosition, long id) {
return false;
}
});
// Listview on child click listener
expListView.setOnChildClickListener(new
ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
Intent launchBrowser;
Uri uriUrl;
// TODO Auto-generated method stub
switch (groupPosition){
case 0:
switch(childPosition){
case 0:
uriUrl = Uri.parse(
"https://plus.google.com/107217033654580487496/posts/4T1mxZDG7hy");
launchBrowser = new Intent(Intent.ACTION_VIEW, uriUrl);
startActivity(launchBrowser);
break;
case 1:
uriUrl = Uri.parse(
"https://plus.google.com/107217033654580487496/posts/6WZjjeuAX7x");
launchBrowser = new Intent(Intent.ACTION_VIEW, uriUrl);
startActivity(launchBrowser);
break;
(...)
}
default:
Toast.makeText(getApplicationContext(),
"Desculpe, avalição não disponível no momento.",
Toast.LENGTH_SHORT).show();
break;
}
return false;
}
});
}
/*
* Preparing the list data
*/
private void prepareListData() {
listDataHeader = new ArrayList<String>();
listDataChild = new HashMap<String, List<String>>();
// Adding child data
listDataHeader.add("1º Período");
listDataHeader.add("2º Período");
(...)
// Adding child data
List<String> periodo1 = new ArrayList<String>();
periodo1.add("Cálculo I");
periodo1.add("Física I");
periodo1.add("Física Experimental I");
periodo1.add("Computação I");
46
periodo1.add("Química");
List<String> periodo2 = new ArrayList<String>();
periodo2.add("Cálculo II");
periodo2.add("Física II");
periodo2.add("Física Experimental II");
periodo2.add("Computação II");
periodo2.add("Álgebra Linear II");
periodo2.add("Circuitos Lógicos");
periodo2.add("Engenharia e Meio Ambiente");
(...)
listDataChild.put(listDataHeader.get(0), periodo1); // Header, Child data
listDataChild.put(listDataHeader.get(1), periodo2);
(...)
}
}
47
Apêndice B
B.1– Mind Map
No início do projeto, criamos um Mind Map para organizar os tópicos a serem
analisados. Devido ao tamanho do Mind Map, o dividimos em dois para que possa ser
bem visualizado.
Alguns tópicos foram modificados de acordo com as possibilidades e
tecnologias disponíveis e o cronograma do projeto, de forma a não prejudicar sua
viabilidade.
Figura 14 – Parte I do Mind Map
48
Figura 15 – Pate II do Mind Map
Recommended