Prévia do material em texto
UNIJORGE Curso em Análise e Desenvolvimento de Sistemas PROGRAMAÇÃO PARA DISPOSITIVOS MÓVEIS Victor Luis da Silva Lima Trabalho apresentado à disciplina de Programação Para Dispositivos Móveis (IL10315) como método de avaliação. SALVADOR, BA 2024 Introdução A persistência é um recurso muito importante no desenvolvimento de aplicativos. Saber trabalhar com os diversos tipos de armazenamento permite que você desenvolva projetos mais robustos. O desenvolvimento de projetos com uso de banco de dados, seja local ou remoto, é um pré-requisito para o desenvolvimento de aplicativos modernos. Para a concretização dos conhecimentos obtidos nesta unidade, você deve definir um objeto para a criação de sua classe e desenvolver um projeto com uso de persistência de dados com uso do SQLite no Android para realizar a manutenção dos diferentes registros de armazenamento, com a listagem, inclusão, alteração e exclusão desses registros. Crie um aplicativo Android para trabalhar com uma base de dados com uma tabela para persistência de dados de um objeto escolhido por você. O objeto deve ser definido por meio de uma classe própria, com: • O mínimo de cinco atributos (com uso de três diferentes tipos de dados) mais o atributo id (long). • Pelo menos um método construtor. • Métodos de acesso (setters & getters) para todos os atributos. • Outros métodos que sejam necessários. A aplicação deverá tratar a inclusão, alteração e exclusão dos registros, além de tratar o acesso, abertura e fechamento do recurso do banco de dados do SQLite, com o uso da arquitetura em três camadas. O aplicativo deverá apresentar os dados dos objetos armazenados por meio de uma lista (ListView) e apresentar as funcionalidades de inclusão, exclusão e alteração, que podem ser realizadas de acordo com a sua escolha. Você pode montar as telas a seu critério, desde que atenda aos requisitos de listagem, inclusão, exclusão e alteração dos registros. Procedimentos para elaboração do TD Crie um projeto no Android Studio e desenvolva a aplicação. Prepare um documento do Word com uma capa (apresentado a instituição, o curso, a disciplina, o aluno e o professor); a introdução do trabalho; o conteúdo com a documentação do sistema, contendo a captura das telas e os códigos de desenvolvimento das telas (código XML da view); os códigos de programação de todas as classes com comentários e apresentação dos testes realizados com o aplicativo com as capturas das telas dos testes; a conclusão e a bibliografia do trabalho. Este trabalho tem como objetivo explorar o desenvolvimento de um aplicativo Android com foco na persistência de dados usando o SQLite, um sistema de gerenciamento de banco de dados leve e eficiente. A persistência de dados é fundamental para criar aplicativos robustos, e o uso de banco de dados, seja local ou remoto, é uma habilidade essencial no desenvolvimento de aplicativos modernos. Objetivo: O objetivo principal deste trabalho é criar um aplicativo Android que utilize o SQLite para armazenar e gerenciar dados de um objeto escolhido pelo desenvolvedor. O objeto será definido por meio de uma classe personalizada, incluindo pelo menos cinco atributos com três tipos de dados diferentes, além do atributo "id" do tipo "long". A classe também deve ter um método construtor e métodos de acesso (getters & setters) para todos os atributos, bem como outros métodos necessários. Metodologia: O desenvolvimento do aplicativo seguirá a arquitetura em três camadas, que inclui a camada de apresentação, a camada de lógica de negócios e a camada de acesso a dados. Essa abordagem garantirá a separação adequada das responsabilidades e facilitará a manutenção do código. Funcionalidades do Aplicativo: O aplicativo a ser desenvolvido deverá realizar as seguintes funcionalidades: • Listagem de Dados: O aplicativo apresentará os dados do objeto armazenados por meio de uma lista (ListView), permitindo que o usuário visualize os registros existentes. • Inclusão de Registros: Os usuários poderão adicionar novos registros do objeto, inserindo informações relevantes por meio de formulários. • Alteração de Registros: O aplicativo possibilitará a edição de registros existentes, permitindo que o usuário atualize as informações conforme necessário. • Exclusão de Registros: Os usuários terão a opção de excluir registros, removendo-os permanentemente da base de dados. • Gerenciamento do Banco de Dados: O aplicativo cuidará da abertura, fechamento e acesso ao recurso do banco de dados SQLite de forma eficiente e segura. Desenvolvimento CÓDIGOS XML (VIEW) • CÓDIGO XML (VIEW) – ACTIVITY_MAIN • Código XML (VIEW) - Activity_Tratar_Cliente app:layout_constraintStart_toStartOf="@+id/editText3" /> CÓDIGOS JAVA (CONTROLLER) • Código Java (Controller) - MainActivity package com.example.projeto2023; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import java.util.Iterator; import java.util.List; public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener{ // Componente lista da view ListView lista; // Declaração da intent Intent intent; // Determina o código da intent public static final int ACTIVITY_REQUEST_CLIENTE = 1; // Declara o objeto de persistência (acesso ao banco) private Cliente_DAO dao ; // Vetor com os dados das disciplinas para apresentar na lista private String[] clientes; // Vetor com o id dos registros para identificar o registro // para os casos de seleção na lista para alteração ou // exclusão private long[] idClientes; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lista = (ListView) findViewById(R.id.lista); // Altera o título da janela da atividade setTitle("AVA2 Aplicativos Móveis"); // Cria o objeto de acesso ao banco dao = new Cliente_DAO(this); // Abre o banco dao.open(); // Determina que os itens da lista serão clicáveis e // prepara o método de controle: onItemClick(..) lista.setOnItemClickListener(this); // Clique no item } // Sempre que a atividade passar pelo método onResume, a lista // será atualizada @Override protected void onResume () { dao.open(); super.onResume (); // Prepara a lista que será exibida ao usuário na tela // Busca no banco todos os registros List listaClientes = dao.getAll(); // Define o tamanho dos vetores de disciplinas e id // em função do tamanho (quantidade de registros) da tabela clientes = new String[listaClientes.size()]; idClientes = new long[listaClientes.size()]; // Primeiro índice dos vetores int i =0; // Cria um objeto iterator para preencher o vetor de disciplinas // com os dados dos registros Iterator iterator = listaClientes.iterator(); // Para cada registro preencher os vetores while (iterator.hasNext()) { // Objeto cliente auxiliar Cliente aux = new Cliente(); // Recebe no objeto auxiliar os dados de cada registro aux = (Cliente) iterator.next(); // Preenche o vetor de disciplinas para visualização na lista clientes[i] = aux.textoLista(); // Preenche o vetor de id para identificação do registro // ao se escolher um elemento da lista para // a alteração ou exclusão idClientes[i] = aux.getId(); // Próximo item dos vetores i++; } // Carrega o ArrayAdapter com os dados do vetor de clientes // ArrayAdapter ArrayAdapter adapter = new ArrayAdapter( this , android.R.layout.simple_list_item_1 , clientes ); //Clientes? // Preenche a lista com os dados do ArrayAdapter lista.setAdapter( adapter ); } // Fecha o recurso de acesso ao banco sempre que a atividade passar // por uma pausa @Override protected void onPause () { // Libera o recurso de acesso ao banco dao.close (); super.onPause (); } // Método para seleção de um item da lista para // alteração ou exclusão (atende à interface: AdapterView.OnItemClickListener) public void onItemClick(AdapterView parent, View view, int position, long ident) { // Position é a posição do item na lista // Armazena o índice do elemento escolhido na lista long id = idClientes[position]; // Preparação da intent com previsão de retorno de dados intent = new Intent(getApplicationContext(), TratarCliente.class); // Passa os dados do item escolhido para a atividade de tratamento intent.putExtra("acao", 0); intent.putExtra("id", id); // Chama a atividade startActivity(intent); } // Método de controle para chamada da atividade secundária para inclusão public void incluirCliente(View v){ // Intent para chamar a atividade secundária intent = new Intent(getApplicationContext(), TratarCliente.class); // Passa os dados do item escolhido para a atividade de tratamento intent.putExtra("acao", -1); intent.putExtra("id", 0L); // Chama a atividade startActivity(intent); } // Método para encerrar o aplicativo public void sair(View v){ finish(); } } • CÓDIGO JAVA (CONTROLLER) - TRATARCLIENTE package com.example.pacote2023; import androidx.appcompat.app.AppCompatActivity; import android.annotation.SuppressLint; import android.os.Bundle; import android.view.View; import android.widget.CheckBox; import android.widget.EditText; import android.widget.ImageButton; import android.widget.TextView; public class TratarCliente extends AppCompatActivity { // Declaração dos componentes de tela EditText ed1, ed2, ed3, ed4; TextView aviso, ok; ImageButton incluir, editar, excluir, voltar; CheckBox ed5; // Atributos de informações de acao: 0 : alteração ou exclusão // -1 : inclusão private int acao; // Id do registro para alteração ou exclusão // será usado com o método buscar para trazer os dados do registro private long id; @SuppressLint({"SetTextI18n", "Locale.US"}) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_tratar_cliente); editar = (ImageButton) findViewById(R.id.button); incluir = (ImageButton) findViewById(R.id.incluir); excluir = (ImageButton) findViewById(R.id.button2); voltar = (ImageButton) findViewById(R.id.voltar); ed1 = (EditText) findViewById(R.id.editText); ed2 = (EditText) findViewById(R.id.editText2); ed3 = (EditText) findViewById(R.id.editText3); ed4 = (EditText) findViewById(R.id.editText4); ed5 = (CheckBox) findViewById(R.id.checkBox); aviso = (TextView) findViewById(R.id.textView7); ok = (TextView) findViewById(R.id.ok); // Recebe os dados da atividade principal // e preenche a tela (view) acao = getIntent().getExtras().getInt("acao"); id = getIntent().getExtras().getLong("id"); // Altera o título e prepara a tela if (acao == -1) { //1 // Tela de inclusão // Usa dados-padrão setTitle("Inserir Cliente"); incluir.setVisibility(View.VISIBLE); voltar.setVisibility(View.VISIBLE); editar.setVisibility(View.INVISIBLE); excluir.setVisibility(View.INVISIBLE); excluir.setVisibility(View.GONE); ed3.setText(String.format("%d", 18)); ed4.setText(String.format("%3.2f", 0.00)); ed5.setVisibility(View.VISIBLE); ed5.setChecked(true); ed5.setText("Ativo"); } else { // Tela de alteração ou exclusão setTitle("Alterar ou Excluir Cliente"); incluir.setVisibility(View.INVISIBLE); incluir.setVisibility(View.GONE); voltar.setVisibility(View.VISIBLE); editar.setVisibility(View.VISIBLE); excluir.setVisibility(View.VISIBLE); // checkbox(); // Cria um objeto Cliente auxiliar para armazenar // os dados do registro Cliente aux = new Cliente(); // Cria o objeto de acesso ao banco Cliente_DAO dao = new Cliente_DAO(this); // Abre o banco dao.open(); // Faz a consulta pelo id do registro para // buscar os dados na tabela aux = dao.buscar(id); // Preenche os dados do registro na tela ed1.setText(aux.getNome()); ed2.setText(aux.getTelefone()); ed3.setText(String.format("%d", aux.getIdade())); ed4.setText(String.format("%3.2f", aux.getCredito())); if(aux.getAtivo().matches("Ativo")){ ed5.setChecked(true); ed5.setText("Ativo"); }else{ ed5.setChecked(false); ed5.setText("Inativo"); } // Libera o recurso de acesso ao banco de dados dao.close(); } } public void checkbox(){ boolean teste = ed5.isChecked(); if(teste == true){ ed5.setText("ATIVO"); }else { ed5.setText("INATIVO"); } } // Método para preparar os dados para retornar à atividade principal public void alterarInserir(View v) { aviso.setText(""); ok.setText(""); incluir.setVisibility(View.INVISIBLE); incluir.setVisibility(View.GONE); excluir.setVisibility(View.VISIBLE); voltar.setVisibility(View.VISIBLE); editar.setVisibility(View.VISIBLE); if(ed5.isChecked()){ checkbox(); ed5.setText("Ativo"); }else { checkbox(); ed5.setText("Inativo"); } String idade1, credito1, nome, telefone, ativo; double credito = 0; int idade = 0; int ok1 = 0; // Pega os dados preenchidos na tela, // para inclusão ou alteração nome = ed1.getText().toString(); telefone = ed2.getText().toString(); ativo = ed5.getText().toString(); idade1 = ed4.getText().toString(); credito1 = ed4.getText().toString(); credito1 = String.format("0")+credito1; //Tratamento dos Inputs if(ed1.getText().length() > 3 && nome.matches("[A-z\\s]*")) { }else{ //Valor referente a esse Input ok1 += 1; } if(telefone.length()de Erros dos Inputs switch(ok1){ case 1: aviso.setText(String.format("Verifique o campo NOME")); break; case 2: aviso.setText(String.format("Verifique o campo TELEFONE")); break; case 3: aviso.setText(String.format("Verifique os campos NOME e TELEFONE")); break; case 4: aviso.setText(String.format("Verifique o campo IDADE ")); break; case 5: aviso.setText(String.format("Verifique os campos NOME e IDADE")); break; case 6: aviso.setText(String.format("Verifique os campos TELEFONE e IDADE")); break; case 7: aviso.setText(String.format("Verifique os campos NOME, TELEFONE e IDADE")); break; case 8: aviso.setText(String.format("Verifique o campo CRÉDITO")); break; case 9: aviso.setText(String.format("Verifique os campos NOME e CRÉDITO")); break; case 10: aviso.setText(String.format("Verifique os campos TELEFONE e CRÉDITO")); break; case 11: aviso.setText(String.format("Verifique os campos NOME, TELEFONE e CRÉDITO")); break; case 12: aviso.setText(String.format("Verifique os campos IDADE e CRÉDITO")); break; case 13: aviso.setText(String.format("Verifique os campos NOME, IDADE e CRÉDITO")); break; case 14: aviso.setText(String.format("Verifique os campos TELEFONE, IDADE e CRÉDITO")); break; case 15: aviso.setText(String.format("Reveja todos os campos!")); break; default: aviso.setText(String.format("")); break; } if(ok1 == 0){ ok1 = 0; //reseta o contador de erros // Cria o objeto de acesso ao banco Cliente_DAO dao = new Cliente_DAO(this); // Abre o banco dao.open(); // Determina a ação if (acao == -1) { // Ação de inserção // Realiza a inclusão da disciplina na tabela dao.inserir(nome, telefone, idade, credito, ativo); } else { // Ação de alteração // Realiza a alteração do registro correspondente na tabela dao.alterar(id, nome, telefone, idade, credito, ativo); } // Libera o recurso de acesso ao banco dao.close(); // Encerra a atividade, retornando à atividade principal finish(); } } // Método para a exclusão de um registro de acordo com o id da disciplina public void excluir(View v) { aviso.setText(""); excluir.setVisibility(View.VISIBLE); // Confere se é uma ação de alteração ou exclusão if (acao == 0) { // Cria o objeto de acesso ao banco Cliente_DAO dao = new Cliente_DAO(this); // Abre o banco dao.open(); // Realiza a exclusão do registro por meio do id dao.apagar(id); // Libera o recurso de acesso ao banco dao.close(); } // Encerra a atividade, retornando à atividade principal finish(); } public void voltar(View v) { // Encerra a atividade, retornando à atividade principal finish(); } } CÓDIGOS JAVA (CLASSE) - Cliente package com.example.projeto2023; import android.annotation.SuppressLint; public class Cliente { // Definição dos atributos private long id; private String nome, ativo, telefone; private double credito; private int idade; // Métodos de acesso (setters & getters) public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public String getTelefone() { return telefone; } public void setTelefone(String telefone) { if (telefone.length() > 9 ) { this.telefone = telefone; }else{ this.telefone = ""; } } public double getCredito() { return credito; } public void setCredito(double credito) { this.credito = credito; } public int getIdade() { return idade; } public void setIdade(int idade) { if (idade > 17) { this.idade = idade; } } public String getAtivo() { return ativo; } public void setAtivo(String ativo) { this.ativo = ativo; } public long getId() { return id; } public void setId(long id) { this.id = id; } // Método construtor com definição dos valores-padrão public Cliente() { nome = ""; telefone = ""; idade = 18; credito = 0.00; ativo = "Ativo"; } // Método de formatação dos dados para exibição na lista @SuppressLint("DefaultLocale") public String textoLista() { String item; item = getNome(); item += "\nTelefone: " + getTelefone(); item += "\t Idade: " + String.format("%d Anos ", getIdade()); item += "\nCrédito: " + String.format("R$ %3.2f ", getCredito()); item += "\t Status: " + getAtivo();; return item; } } Código Java (Classe) - ClienteDAO package com.example.pacote2023; import java.util.ArrayList ; import java.util.List ; import android.content.ContentValues ; import android.content.Context; import android.database.Cursor ; import android.database.SQLException ; import android.database.sqlite.SQLiteDatabase ; // Camada de dados (Persistência) // Classe de definição para os acessos ao banco de dados public class Cliente_DAO { // Define um objeto banco de dados private SQLiteDatabase database; // Define as colunas da tabela private String [] columns = { ClienteSQLiteOpenHelper.COLUNA_ID , ClienteSQLiteOpenHelper.COLUNA_NOME , ClienteSQLiteOpenHelper.COLUNA_TELEFONE , ClienteSQLiteOpenHelper.COLUNA_IDADE , ClienteSQLiteOpenHelper.COLUNA_CREDITO, ClienteSQLiteOpenHelper.COLUNA_ATIVO }; private ClienteSQLiteOpenHelper sqliteOpenHelper ; // Método construtor public Cliente_DAO(Context context ) { sqliteOpenHelper = new ClienteSQLiteOpenHelper(context); } // Método para abrir o recurso de banco de dados public void open () throws SQLException { database = sqliteOpenHelper.getWritableDatabase(); } // Método para fechar o recurso de banco de dados public void close() { sqliteOpenHelper.close (); } // Método de inclusão de registro public void inserir (String nome, String telefone, int idade, double credito, String ativo) { // Prepara os valores das colunas da tabela para a inserção ContentValues values = new ContentValues(); values.put ( ClienteSQLiteOpenHelper.COLUNA_NOME, nome ); values.put ( ClienteSQLiteOpenHelper.COLUNA_TELEFONE, telefone ); values.put ( ClienteSQLiteOpenHelper.COLUNA_IDADE, String.valueOf(idade) ); values.put ( ClienteSQLiteOpenHelper.COLUNA_CREDITO, String.valueOf(credito) ); values.put ( ClienteSQLiteOpenHelper.COLUNA_ATIVO, String.valueOf(ativo) ); // Efetua a inclusão com retorno do id do registro long insertId = database.insert ( ClienteSQLiteOpenHelper.TABELA , null , values ); } // Método para atualização de um registro da tabela // Recebe os dados para a inserção public void alterar(long id, String nome, String telefone, int idade, double credito, String ativo){ // Prepara os dados para a atualização ContentValues values = new ContentValues(); values.put ( ClienteSQLiteOpenHelper.COLUNA_NOME , nome ); values.put ( ClienteSQLiteOpenHelper.COLUNA_TELEFONE , telefone ); values.put ( ClienteSQLiteOpenHelper.COLUNA_IDADE , String.valueOf(idade) ); values.put ( ClienteSQLiteOpenHelper.COLUNA_CREDITO , String.valueOf(credito) ); values.put ( ClienteSQLiteOpenHelper.COLUNA_ATIVO , String.valueOf(ativo) ); // Efetua a alteração do registro, de acordo com o id do registro database.update(ClienteSQLiteOpenHelper.TABELA , values,ClienteSQLiteOpenHelper.COLUNA_ID + "=" + id, null); } // Método para a exclusão de um registro // Recebe o id do registro que será excluído public void apagar ( long id ) { // Exclui o registro a partir do id database.delete ( ClienteSQLiteOpenHelper.TABELA , ClienteSQLiteOpenHelper.COLUNA_ID + " = " + id , null ); } // Método de busca de registro a partir do id // Busca os dados de cada registro a partir do id // Retorna um objeto Cliente com os dados do registro public Cliente buscar ( long id ) { // Realiza a busca a partirdo id do registro // Usado para buscar os dados para a montagem da tela e // para a alteração ou exclusão do registro // O objeto cursor armazena os registros da consulta // Como o filtro é o id, apenas um registro será selecionado Cursor cursor = database.query( ClienteSQLiteOpenHelper.TABELA, columns , ClienteSQLiteOpenHelper.COLUNA_ID + " = " + id, null , null , null , null, null ); cursor.moveToFirst(); // Cria um objeto Cliente auxiliar para retornar o objeto Cliente Cliente = new Cliente (); // Preenche os dados do registro do banco // nas propriedades do objeto auxiliar Cliente.setId ( cursor.getLong (0) ); Cliente.setNome ( cursor.getString (1) ); Cliente.setTelefone ( cursor.getString (2) ); Cliente.setIdade ( cursor.getInt (3) ); Cliente.setCredito ( cursor.getDouble (4) ); Cliente.setAtivo ( cursor.getString (5) ); // Fecha o recurso do cursor cursor.close(); // Retorna o objeto auxiliar do tipo Cliente return Cliente ; } // Método de montagem da lista de registros das Clientes // Monta a lista de Clientes para a carga da lista na tela principal // O método retornará uma lista com todas as Clientes armazenadas // no banco public List getAll () { // Prepara um Arraylist para retorno dos registros armazenado no banco List Clientes = new ArrayList () ; // Objeto cursor para armazenar temporariamente os dados // retornados pela consulta Cursor cursor = database.query ( ClienteSQLiteOpenHelper . TABELA , columns , null , null , null , null , null, null ); // Passa o ponteiro para o primeiro registro do cursor cursor.moveToFirst (); // Para cada registro, os dados da tabela são copiados para // o objeto Cliente da lista while (!cursor.isAfterLast ()) { Cliente cliente = new Cliente (); cliente.setId ( cursor.getLong (0) ); cliente.setNome ( cursor.getString (1) ); cliente.setTelefone ( cursor.getString (2) ); cliente.setIdade ( cursor.getInt (3) ); cliente.setCredito ( cursor.getDouble (4) ); cliente.setAtivo ( cursor.getString (5) ); Clientes.add ( cliente ); cursor.moveToNext(); } // Fecha o cursor cursor.close (); // Retorna à lista de clientes return Clientes; } } Código Java (Classe) - ClientesSQLITEopenhelper package com.example.pacote2023; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite . SQLiteOpenHelper; public class ClienteSQLiteOpenHelper extends SQLiteOpenHelper { // Definição da tabela e dos atributos // Os espaços antes e depois dos nomes são importantes, // pois será criada uma QUERY (consulta) com esses identificadores public static final String TABELA = " Cliente "; public static final String COLUNA_ID = " id "; public static final String COLUNA_NOME = " nome "; public static final String COLUNA_TELEFONE = " telefone "; public static final String COLUNA_IDADE = " idade "; public static final String COLUNA_CREDITO = " credito "; public static final String COLUNA_ATIVO = " ativo "; // Define o nome do banco de dados private static final String DATABASE_NAME = "clientes.db"; // Define a versão do banco // O valor deve ser incrementado somente em casos de alterações // na estrutura do banco (tabelas e atributos) private static final int DATABASE_VERSION = 4; // String de criação da tabela no banco de dados private static final String CRIAR_BANCO = " create table " + TABELA + "(" + COLUNA_ID + " integer primary key autoincrement , " + COLUNA_NOME + " text not null , " + COLUNA_TELEFONE + " text not null , " + COLUNA_IDADE + " integer not null , " + COLUNA_CREDITO + " double not null ," + COLUNA_ATIVO + " integer not null ) ;"; // Método construtor da classe para criação ou atualização do banco public ClienteSQLiteOpenHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } // Cria o banco de dados, caso não exista @Override public void onCreate ( SQLiteDatabase database ) { database.execSQL ( CRIAR_BANCO ); } // Atualiza o banco de dados, caso seja uma nova versão @Override public void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion) { db. execSQL (" DROP TABLE IF EXISTS " + TABELA ); onCreate (db); } } Testes de funcionamento Realizados testes para verificar o funcionamento do programa, conforme prints abaixo: Conclusão Este trabalho propõe o desenvolvimento de um aplicativo Android com foco na persistência de dados usando o SQLite, aplicando princípios de programação orientada a objetos e boas práticas de desenvolvimento. O aplicativo resultante permitirá aos usuários gerenciar registros de um objeto personalizado de forma eficaz, incluindo a listagem, inclusão, alteração e exclusão de dados. A implementação seguirá a arquitetura em três camadas para garantir a organização e a manutenção adequadas do código. Referências https://unijorge.instructure.com/courses/40518/modules/items/568158 https://unijorge.instructure.com/courses/40518/modules/items/568157 https://unijorge.instructure.com/courses/40518/modules/items/568159 https://unijorge.instructure.com/courses/40518/modules/items/568158 https://unijorge.instructure.com/courses/40518/modules/items/568157