Baixe o app para aproveitar ainda mais
Leia os materiais offline, sem usar a internet. Além de vários outros recursos!
Prévia do material em texto
UNIP INTERATIVA Projeto Integrado Multidisciplinar Cursos Superiores de Tecnologia Desenvolvimento de aplicações com persistência em Banco de Dados UNIP Polo Eden – Sorocaba – SP 2020 UNIP INTERATIVA Projeto Integrado Multidisciplinar Cursos Superiores de Tecnologia Desenvolvimento de aplicações com persistência em Banco de Dados Nome: Felipe Ferreira Rubim RA: 1982762 Nome: Leidiane Lopes dos Santos RA: 0521387 Nome: Wisley Ramos de Siqueira RA: 1980138 Nome: Raimundo Nonato Loureiro Castelo Branco RA: 0519978 Nome: Fabiana Machado dos Santos RA: 0528675 Curso: Análise e Desenvolvimento de Sistemas Semestre: 3º semestre UNIP Polo Eden – Sorocaba – SP 2020 RESUMO Projeto integrado Multidisciplinar(PIM VIII) deste bimestre proposto pela universidade paulista UNIP interativa. Consiste no desenvolvimento e codificação em C# do mecanismo de acesso a um trecho de banco de dados, assim como os protótipos de interface gráfica com o usuário em ASP.NET e Android. Na formatação do trabalho foram utilizados os conhecimentos adquiridos nas aulas dos módulos de gerenciamento de projetos de software, Desenvolvimento de Software para internet e Tópicos Especiais de Programação Orientada a Objetos. Será seguido para um bom gerenciamento de projeto, como prazos, métodos de desenvolvimento, testes e entrega do produto final, buscando sempre a proposta inicial e a entrega com qualidade. Palavras-chave: ASP.NET, Projeto, Gerenciamento, qualidade. ABSTRACT Multidisciplinary integrated project (PIM VIII) of this bimester proposed by the São Paulo UNIP interactive university. It consists of the development and related in C # of the mechanism of access to a database section, as well as the prototypes of graphical user interface in ASP.NET and Android. In the formatting of the work, the knowledge acquired in the classes of the modules of software project management, Software Development for internet and Special Topics of Object Oriented Programming were used. It will be followed for good project management, such as deadlines, development methods, tests and delivery of the final product, always looking for the initial proposal and quality delivery. Keywords: ASP.NET, Project, Management, quality. SUMÁRIO 1. INTRODUÇÃO.....................................................................................6 2. Criação de aplicação com MVC E Conexao com Banco de Dados Access...........................................................................................7 ao 18 2.1 Criando e configurando os objetos 2.2 Configurações da conexão 2.3 Configuração do comando a ser executado no banco 3.0 APLICAÇÃO WEB PARA CADASTRO DE USUARIOS......19 ao 22 3.1 Protótipos web e códigos fonte 4.0 INTERFACE ANDROID.........................................................23 ao 32 4.1 Protótipos Android e código fonte 5. CONCLUSÃO....................................................................................33 6. BIBLIOGRAFIA.................................................................................34 6 1. INTRODUÇÃO Um bom gerenciamento de projeto resulta no desenvolvimento de um projeto com qualidade. O gerenciamento de projeto no âmbito de engenharia de software tem aproximadamente 20 anos, onde a profissão de gerente de projetos vem aplicando e aperfeiçoando as ferramentas e técnicas, com base nas boas praticas de gestão de projetos publicadas a cada 4 anos no PMBOK (Project Meragement Body of Knowledge). No decorrer do gerenciamento e desenvolvimento de um projeto, precisamos seguir o que foi apresentado e aprovado pelo cliente, sempre deixando o mesmo informado através de meios de comunicação ricos. Como parte deste trabalho o desenvolvimento de uma aplicação web deve seguir um padrão de codificação, neste caso iremos utilizar arquitetura MVC (Model, View, Controller) para tal padronização. Utilizando a linguagem ASP.NET que será apresentada no andamento deste trabalho, iremos enfatizar alguns pontos importantes do desenvolvimento de uma aplicação web. Pensar em desenvolvimento web é ter a noção básica de diversos artefatos e processos, com os protótipos, os conceitos de cores, telas, controles de navegação são provenientes de um bom planejamento, mas principalmente de analise bem efetuada. Conceitos e ideias podem ser conhecidos mundialmente por meio da internet, estar atento ás essas tendências com ênfase na linguagem e nos layouts e utilizando os recursos de CSS, javascript podem garantir o sucesso e a qualidade do desenvolvimento de uma aplicação. 7 2. Criação de aplicação com MVC E Conexao com Banco de Dados Access Para criarmos nosso projeto, vamos definir as classes e seus relacionamentos, utilizaremos o diagrama de classes da UML. Onde Definimos seus atributos e seus métodos. Criamos nosso Padrão MVC, onde temos a nossa Camada Model e nossa Camada Controller. 8 Para mostrar como desenvolver uma aplicação com o padrao MVC, será implementado uma Entidade. A classe criada será a Pessoa, com os atributos: IdPessoa, Nome, Cpf e Telefone. A Imagem 1 mostra o código dessa classe que tem, além dos atributos, os métodos get e set. Imagem 1 9 A classe Pessoa tem um relacionamento de Agregação com Endereço e Telefone. A classe Telefone tem um TipoTelefone. 10 Para criarmos as tabelas no banco de dados vamos criar primeiramente nosso diagrama de entidade e relacionamento. Onde várias Pessoas podem ter o mesmo Endereço e um Pessoa pode ter muitos telefones. O padrão de projeto DAO surgiu com a necessidade de separarmos a lógica de negócios da lógica de persistência de dados. Este padrão permite que possamos mudar a forma de persistência sem que isso influencie em nada na lógica de negócio, além de tornar nossas classes mais legíveis. Classes DAO são responsáveis por trocar informações com o SGBD e fornecer operações CRUD .Vamos criar uma classe PessoaDAO para ter acesso aos nossos dados, salvar, alterar,buscar e excluir. 2.1 Criando e configurando os objetos Primeiramente criamos o objeto para identificar onde está localizado o nosso banco de dados 11 (arquivo .mdb). Quem nos fornece essa possibilidade é a classe OleDbConnection do namespace System.Data.OleDb. 2.2 Configuração da conexão OleDbConnection conexao = new OleDbConnection(); configuração do caminho ao banco de dados conexao.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Users\\... No primeiro comando criamos o objeto “conexao” que será a nossa instância da classe OleDbConnection. Através dele que poderemos configurar a localização do arquivo .mdb usando a propriedade “ConnectionString” (segundo comando). Nesse ponto já temos o necessário para a conexão. A segunda etapa é a criação do comando (SQL) a ser executado na conexão definida acima. Para isso usamos a classe OleDbCommand. 2.3 Configuração do comando a ser executado no banco OleDbCommand comando = new OleDbCommand("select * from usuarios where login = 'teste'; ", conexao); Ao criar o objeto “comando”, no seu construtor podemos atribuir diretamente qual o comando a ser executado e associar à conexão criada no início. Nesse ponto do código já temos a identificação da conexão e qual o comando será executado nela. Falta somente a execução efetiva dela no banco e verificar o que será retornado. Costumeiramente colocamos o trecho abaixo dentro de um bloco try/catch. Neste bloco precisamos executar os seguintes procedimentos: • Abrir a conexão• Executar o comando • Verificar o retorno (aplicar a lógica necessária à aplicação em desenvolvimento) • Fechar a conexão Quando executamos um comando de “select” precisamos armazenar o conteúdo do retorno em um componente chamado DataReader que, como estamos trabalhando com OLEDB, se chama OleDbDataReader. Na sua construção passamos a instrução de executar o comando criado anteriormente, ficando da seguinte forma: OleDbDataReader dados = comando.ExecuteReader(); Para manipular as linhas retornadas pelo comando “select” fazemos um “laço” de “enquanto” for possível ler. Por exemplo: while(dados.Read()){ //Lógica da aplicação } Caso o comando SQL envolva as diretivas insert, update ou delete não necessitamos do objeto DataReader pois não iremos pegar algum valor do banco de dados como acontece no select mas sim precisamos verificar a quantidade de linhas afetadas pelo comando. Nesses casos, após a abertura da conexão, podemos verificar a quantidade de linhas afetadas no banco de dados com o método ExecuteNonQuery()assim como no seguinte trecho de código: 12 conexao.Open(); if (comando.ExecuteNonQuery() != 0){ //Lógica da aplicação } O método ExecuteNonQuery() nos retorna a quantidade de linhas afetadas no banco de dados. Caso a quantidade seja diferente de zero significa que uma linha ou mais foi alterada e a nossa instrução do insert, update ou delete teve algum efeito. 13 Por fim, um exemplo com o código final ficará da seguinte forma: 14 15 16 17 18 19 3.0 APLICAÇÃO WEB PARA CADASTRO DE USUARIOS Neste projeto iremos desenvolver uma aplicação web utilizando ASP.NET, um framework que utilizado pela plataforma da Microsoft, é o sucessor da linguagem ASP e permite criar paginas dinâmicas através da framework .NET. O ASP.NET tem como base o framework .NET com todas as duas características legadas. Como toda aplicação .NET desenvolvida para esta plataforma podem ser utilizadas varias linguagens, entre elas C# e Visual Studio.NET. Por ser uma plataforma “simples” que podem ser desenvolvidas aplicações utilizando somente um editor de texto e um compilador .NET. O VisualStudio.NET é o ambiente mais utilizado pelos desenvolvedores para construir suas aplicações em ASP.NET, pois já possui ferramentas e características que ajudam os programadores, por exemplo os componentes visuais para elaboração de formulários de paginas web. Por ser uma linguagem orientada a objeto, qualquer aplicação web desenvolvida em ASP.NET pode reutilizar uma parte ou todo o código de um outro projeto escrito na plataforma .NET, mesmo que o código esteja escrito em VB.NET pode chamar os componentes escritos em C#. Ao contrario da tecnologia ASP, as aplicações desenvolvidas em ASP.NET são complicadas antes da execução, gerando um maior desempenho. Para a execução das aplicações web em ASP.NET é necessário o Framework .NET e do servidor de aplicações IIS, utilizada na plataforma WINDOWS. Já existe um projeto em desenvolvimento de um modulo que será capaz de permitir que um servidor Apache HTTP trabalhe em conjunto com o Framework .NET para rodar aplicações ASP.NET multiplataforma. 3.1 Protótipos web e códigos fonte Tela para realização de cadastro de clientes na página web: Figura. Print da tela do computador 20 Código fonte: Desenvolvido através da IDE Visual Studio 21 Tela para realização de consulta ao cadastro de clientes pela web: Figura. Print da tela do computador 22 Código fonte: Desenvolvido através IDE Visual Basic Code 23 4.0 INTERFACE ANDROID O protótipo de interface de acesso ao banco de dados desenvolvido para a solution cadastro de clientes em aplicativos para aparelhos Android foi desenvolvido na IDE (ambiente de desenvolvimento) Andoroid Studio, esta interface permite que os usuários realizem o que chamamos de CRUD, que são operações típicas em um sistema de banco de dados: cadastrar, alterar, excluir e consultar. No modelo arquitetural de desenvolvimento em camadas o código Xml do layout das activities ficam contidas na camada de apresentação do padrão MVC (Model-View-Controller), que é a camada responsável pelas configurações da interface de interação com o usuário. 4.1 Protótipos Android e código fonte Tela para realização de cadastro de clientes do aplicativo para Android: Fig. print do protótipo da tela do celular Android Código-Fonte A seguir código-fonte em xml do layout da Activity de cadastro de clientes desenvolvido no editor Android Studio para aparelhos Android. 24 <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/colorPrimary" android:minHeight="?attr/actionBarSize" android:theme="?attr/actionBarTheme" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <ImageView android:id="@+id/img_setatoolbar" android:layout_width="43dp" android:layout_height="32dp" android:contentDescription="@string/app_name" android:scrollbarSize="15dp" app:layout_constraintBottom_toBottomOf="@+id/toolbar" app:layout_constraintEnd_toStartOf="@+id/lbl_app_name" app:layout_constraintHorizontal_bias="0.347" app:layout_constraintStart_toStartOf="@+id/toolbar" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.444" app:srcCompat="@drawable/ic_baseline_west_24" /> <TextView android:id="@+id/lbl_app_name" android:layout_width="wrap_content" android:layout_height="wrap_content" 25 android:layout_marginBottom="16dp" android:fontFamily="@font/allerta" android:paddingLeft="10dp" android:paddingTop="20dp" android:text="@string/app_name" android:textColor="@color/design_default_color_surface" android:textSize="18sp" app:layout_constraintBottom_toBottomOf="@+id/toolbar" app:layout_constraintEnd_toEndOf="@+id/toolbar" app:layout_constraintHorizontal_bias="0.346" app:layout_constraintStart_toStartOf="@+id/toolbar" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="1.0" /> <TextView android:id="@+id/lbl_nome" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:fontFamily="@font/allerta" android:padding="10dp" android:text="@string/lbl_nome" app:layout_constraintBottom_toTopOf="@+id/edt_nome" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/toolbar" app:layout_constraintVertical_bias="0.0" /> <EditText android:id="@+id/edt_nome" android:layout_width="match_parent" android:layout_height="wrap_content"android:layout_marginBottom="10dp" android:ems="10" android:inputType="textPersonName" app:layout_constraintBottom_toTopOf="@+id/lbl_cpf" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" 26 app:layout_constraintTop_toBottomOf="@+id/lbl_nome" /> <TextView android:id="@+id/lbl_telefone" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:fontFamily="@font/allerta" android:paddingLeft="10dp" android:text="@string/lbl_telefone" app:layout_constraintBottom_toTopOf="@+id/edt_telefone" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/edt_cpf" /> <EditText android:id="@+id/edt_telefone" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="10dp" android:ems="10" android:inputType="textPersonName" android:padding="10dp" app:layout_constraintBottom_toTopOf="@+id/lbl_endereco" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/lbl_telefone" app:layout_constraintVertical_bias="0.251" /> <TextView android:id="@+id/lbl_cpf" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:fontFamily="@font/allerta" android:padding="10dp" android:text="@string/lbl_cpf" app:layout_constraintBottom_toTopOf="@+id/edt_cpf" 27 app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/edt_nome" /> <EditText android:id="@+id/edt_cpf" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="10dp" android:ems="10" android:inputType="textPersonName" app:layout_constraintBottom_toTopOf="@+id/lbl_telefone" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/lbl_cpf" /> <TextView android:id="@+id/lbl_endereco" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:fontFamily="@font/allerta" android:paddingLeft="10dp" android:text="@string/lbl_endereço" app:layout_constraintBottom_toTopOf="@+id/edt_endereco" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/edt_telefone" /> <EditText android:id="@+id/edt_endereco" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="128dp" android:ems="10" android:inputType="textPersonName" app:layout_constraintBottom_toBottomOf="parent" 28 app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/lbl_endereco" /> <Button android:id="@+id/btn_cadastrar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="28dp" android:layout_weight="1" android:fontFamily="@font/allerta" android:text="@string/btn_cadastrar" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/btn_limpar" app:layout_constraintHorizontal_bias="0.533" app:layout_constraintStart_toStartOf="parent" /> <Button android:id="@+id/btn_limpar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="48dp" android:layout_marginRight="48dp" android:layout_marginBottom="28dp" android:layout_weight="1" android:fontFamily="@font/allerta" android:text="@string/btn_limpardados" android:visibility="visible" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> 29 Fig. print do protótipo da tela do celular Android Código-Fonte A seguir código-fonte em xml do layout da Activity de consulta ao cadastro de clientes desenvolvido no editor Android Studio para aparelho Android. <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <androidx.appcompat.widget.Toolbar android:id="@+id/tbr_consultacadastro" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/colorPrimary" 30 android:minHeight="?attr/actionBarSize" android:theme="?attr/actionBarTheme" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="1.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <ImageView android:id="@+id/img_seta" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" app:layout_constraintBottom_toBottomOf="@+id/tbr_consultacadastro" app:layout_constraintEnd_toStartOf="@+id/lbl_appname" app:layout_constraintHorizontal_bias="0.471" app:layout_constraintStart_toStartOf="@+id/tbr_consultacadastro" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.0" app:srcCompat="@drawable/ic_baseline_west_24" /> <TextView android:id="@+id/lbl_appname" android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@font/allerta" android:text="@string/lbl_appname" android:textColor="@color/white" app:layout_constraintBottom_toBottomOf="@+id/tbr_consultacadastro" app:layout_constraintEnd_toEndOf="@+id/tbr_consultacadastro" app:layout_constraintHorizontal_bias="0.302" app:layout_constraintStart_toStartOf="@+id/tbr_consultacadastro" app:layout_constraintTop_toTopOf="@+id/tbr_consultacadastro" app:layout_constraintVertical_bias="0.567" /> <TextView android:id="@+id/lbl_escolhaopcao" android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@font/allerta" android:includeFontPadding="true" 31 android:text="@string/lbl_escolhaopcao" app:layout_constraintBottom_toTopOf="@+id/chk_nome"app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.497" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/tbr_consultacadastro" app:layout_constraintVertical_bias="0.895" /> <CheckBox android:id="@+id/chk_nome" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="168dp" android:layout_marginEnd="170dp" android:layout_marginRight="170dp" android:fontFamily="@font/allerta" android:text="@string/chk_name" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.502" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/lbl_appname" /> <CheckBox android:id="@+id/chk_cpf" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="176dp" android:layout_marginRight="176dp" android:fontFamily="@font/allerta" android:text="@string/chk_cpf" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.485" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/chk_nome" /> <EditText android:id="@+id/edt_inserirdados" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="296dp" 32 android:ems="10" android:fontFamily="@font/allerta" android:inputType="textPersonName" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.427" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/lbl_appname" /> <Button android:id="@+id/btn_pesquisar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@font/allerta" android:text="@string/btn_pesquisar" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.496" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/edt_inserirdados" app:layout_constraintVertical_bias="0.321" /> </androidx.constraintlayout.widget.ConstraintLayout> 33 5. CONCLUSÃO Conforme a proposta do Projeto Integrado Multidisciplinar VIII, desenvolvemos um mecanismo de acesso a um trecho do banco de dados que é responsável por manter o cadastro de pessoas em um sistema em C#. Criamos um protótipo em ASP .Net e Android que permitem ao usuário interagir com o trecho do banco de dados em multiplataformas, utilizando a IDE Microsoft Visual Studio Code para o desenvolvimento das interfaces desktop e a IDE Android Studio para desenvolvimento das interfaces para Android. Foram desenvolvidas interfaces gráficas com o usuário em ASP .Net e Android que permitem que o usuário realize operações típicas de um sistema que opera em uma base de dados como: cadastrar, alterar, excluir e consultar, o que chamamos de CRUD (Create, Read, Update, Delete). Seguimos o modelo arquitetural em camadas padrão MVC (Model-View-Controller), um modelo de camadas bastante empregado para a implementação de projetos nos diversos níveis (desktop, web e mobile). 34 6. BIBLIOGRAFIA • Desenvolvimento Android, https://developer.android.com/guide/components/activities/intro-activities?hl=pt-br, acesso em 15/11/2020 as 16:18hr. • Desenvolvimento web, https://dotnet.microsoft.com/apps/aspnet acesso em 16/11/2020 as 19:30hr. https://developer.android.com/guide/components/activities/intro-activities?hl=pt-br https://dotnet.microsoft.com/apps/aspnet%20acesso%20em%2016/11/2020 https://dotnet.microsoft.com/apps/aspnet%20acesso%20em%2016/11/2020
Compartilhar