18
respostas

Camera parou.

Erros ao fim da aula 2 com relação a câmera (no vídeo 1, que é só a criação de design tudo funcionou. No vídeo 2 aonde as funções do botão são implementadas e você pode tirar a foto de fato, só ao registrar a foto o apk parava de funcionar, a partir do vídeo 3 aonde a foto é salva na memoria, o apk nem executa mais e o emulador já abre dizendo que a agenda crashou se deseja abrir novamente. PS: Já segui as devidas correções e adaptações pro Android 7 e atualmente estou no Android 8 em minha maquina virtual.

Logcat:

Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3621)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2862)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
at android.database.CursorWindow.nativeGetString(Native Method)
at android.database.CursorWindow.getString(CursorWindow.java:438)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
at com.tales.agenda.DAO.AlunoDAO.buscaAlunos(AlunoDAO.java:78)
at com.tales.agenda.ListaAlunosActivity.carregaLista(ListaAlunosActivity.java:62)
at com.tales.agenda.ListaAlunosActivity.onResume(ListaAlunosActivity.java:72) 
...                                                      
Linha relacionada ao AlunoDAO java 78:
aluno.setFoto(c.getString(c.getColumnIndex("caminhoFoto")));

Relacionado ao ListaAlunos java 62:
AlunoDAO dao = new AlunoDAO(this);
        List<Aluno> alunos = dao.buscaAlunos();

Relacionado ao ListaAlunos 72:
carregaLista();

Codigo do AlunoDAO:
public class AlunoDAO extends SQLiteOpenHelper {
    public AlunoDAO (Context context) {
        super(context, "Agenda", null, 1);
    }
    @Override
    public void onCreate (SQLiteDatabase db) {
        String sql = "CREATE TABLE Alunos (id INTEGER PRIMARY KEY, nome TEXT NOT NULL, endereco TEXT, telefone TEXT, site TEXT, nota REAL, caminhoFoto TEXT);";
        db.execSQL(sql);
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        String sql = "";
        switch (oldVersion){
            case 1:
                sql = "ALTER TABLE Alunos ADD COLUMN caminhoFoto TEXT";
        }
        db.execSQL(sql);
    }
    public void insert(Aluno aluno)  {
        SQLiteDatabase db = getWritableDatabase();
        ContentValues dados = pegaDadosAluno(aluno);
        db.insert("Alunos", null, dados );
    }
    @NonNull
    private ContentValues pegaDadosAluno(Aluno aluno) {
        ContentValues dados = new ContentValues();
        dados.put("nome", aluno.getNome());
        dados.put("endereco", aluno.getEndereco());
        dados.put("telefone", aluno.getTelefone());
        dados.put("site", aluno.getSite());
        dados.put("nota", aluno.getNota());
        dados.put("caminhoFoto", aluno.getFoto());
        return dados;
    }
    public List<Aluno> buscaAlunos() {
        String sql = "SELECT * FROM Alunos;";
        SQLiteDatabase db = getReadableDatabase();
        Cursor c = db.rawQuery(sql, null);
        List<Aluno> alunos = new ArrayList<Aluno>();
        while (c.moveToNext()) {
            Aluno aluno = new Aluno();
            aluno.setId(c.getLong(c.getColumnIndex("id")));
            aluno.setNome(c.getString(c.getColumnIndex("nome")));
            aluno.setEndereco(c.getString(c.getColumnIndex("endereco")));
            aluno.setTelefone(c.getString(c.getColumnIndex("telefone")));
            aluno.setSite(c.getString(c.getColumnIndex("site")));
            aluno.setNota(c.getDouble(c.getColumnIndex("nota")));
            aluno.setFoto(c.getString(c.getColumnIndex("caminhoFoto")));

            alunos.add(aluno);
        }
        //fecha conexao com o banco de dados
        c.close();
        //retorna os alunos colhidos
        return alunos;
    }
    public void delet(Aluno aluno) {
        SQLiteDatabase db = getWritableDatabase();
        String [] params = {String.valueOf(aluno.getId())};injection passando uma lista de parametros por string
        db.delete("Alunos", "id = ?", params);
    }
    public void alter(Aluno aluno) {
        SQLiteDatabase db = getWritableDatabase();

        ContentValues dados = pegaDadosAluno(aluno);

        String[] params ={aluno.getId().toString()};
        db.update("Alunos", dados, "id = ?", params);
    }
}
18 respostas

Codigo Lista Alunos:

public class ListaAlunosActivity extends AppCompatActivity {
    private ListView listaAlunos;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_lista_alunos);


        listaAlunos = (ListView) findViewById(R.id.lista_alunos_listaAlunos);

        listaAlunos.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> lista, View item, int posicao, long id) {
                Aluno aluno = (Aluno) listaAlunos.getItemAtPosition(posicao);

                Intent vaiProFormulario = new Intent(ListaAlunosActivity.this, FormularioActivity.class);
                vaiProFormulario.putExtra("aluno", aluno);
                startActivity(vaiProFormulario);
            }
        });

        Button novoAluno = (Button) findViewById(R.id.lista_alunos_novoAluno);
        novoAluno.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                Intent vaiProFormulario = new Intent(ListaAlunosActivity.this,FormularioActivity.class);
                startActivity(vaiProFormulario);
            }
        });

        registerForContextMenu(listaAlunos);
    }

    private void carregaLista()  {
        AlunoDAO dao = new AlunoDAO(this);
        List<Aluno> alunos = dao.buscaAlunos(); dao.close();

        listaAlunos = (ListView)  findViewById(R.id.lista_alunos_listaAlunos);
        ArrayAdapter<Aluno> adapter = new ArrayAdapter<Aluno>(this,  android.R.layout.simple_list_item_1, alunos);
        listaAlunos.setAdapter(adapter);
    }

    @Override
    protected void onResume() {
        super.onResume();
        carregaLista();
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, final ContextMenu.ContextMenuInfo menuInfo) {
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;

        final Aluno aluno = (Aluno) listaAlunos.getItemAtPosition(info.position);

        MenuItem itemLigar = menu.add("Ligar para " + aluno.getNome());
        itemLigar.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem menuItem) {
                if (ActivityCompat.checkSelfPermission(ListaAlunosActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(ListaAlunosActivity.this,
                            new String[]{Manifest.permission.CALL_PHONE}, 123);
                } else {
                    Intent intentLigar = new Intent(Intent.ACTION_CALL);
                    intentLigar.setData(Uri.parse("tel:" + aluno.getTelefone()));
                    startActivity(intentLigar);
                }
                return false;
            }
        });

        MenuItem itemSMS = menu.add("Enviar SMS para " + aluno.getNome());
        Intent intentSMS = new Intent(Intent.ACTION_VIEW);

        intentSMS.setData(Uri.parse("sms:" + aluno.getTelefone()));
        itemSMS.setIntent(intentSMS);

        MenuItem itemMapa = menu.add("Visualizar " + aluno.getNome() + " no Mapa");
        Intent intentMapa = new Intent(Intent.ACTION_VIEW);

        intentMapa.setData(Uri.parse("geo:0,0?q=" + aluno.getEndereco()));
        itemMapa.setIntent(intentMapa);

        MenuItem itemSite = menu.add("Visitar Site do(a) " + aluno.getNome());
        Intent intentSite = new Intent(Intent.ACTION_VIEW);

        String site = aluno.getSite();
        if (!site.startsWith("http://")){
            site = "http://" + site;
        }

        intentSite.setData(Uri.parse(site));
        itemSite.setIntent(intentSite);

        MenuItem deletar = menu.add("Deletar "  + aluno.getNome());
        deletar.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem menuItem) {
                AlunoDAO dao = new AlunoDAO(ListaAlunosActivity.this);
                dao.delet(aluno);
                dao.close();

                carregaLista();
                return false;
            }
        });
    }
}

Codigo Helper

public class FormularioHelper {
    private final EditText campoNome;
    private final EditText campoEndereco;
    private final EditText campoTelefone;
    private final EditText campoSite;
    private final RatingBar campoNota;
    private final ImageView campoFoto;

    private Aluno aluno;
    public FormularioHelper(FormularioActivity activity) {
        campoNome = (EditText) activity.findViewById(R.id.formulario_nome);
        campoEndereco = (EditText) activity.findViewById(R.id.formulario_endereco);
        campoTelefone = (EditText) activity.findViewById(R.id.formulario_telefone);
        campoSite = (EditText) activity.findViewById(R.id.formulario_site);
        campoNota = (RatingBar) activity.findViewById(R.id.formulario_nota);
        campoFoto = (ImageView) activity.findViewById(R.id.formulario_foto);
        aluno = new Aluno();
    }

    public Aluno pegaAluno() {
        aluno.setNome(campoNome.getText().toString());
        aluno.setEndereco(campoEndereco.getText().toString());
        aluno.setTelefone(campoTelefone.getText().toString());
        aluno.setSite(campoSite.getText().toString());
        aluno.setNota(Double.valueOf(campoNota.getProgress()));
        aluno.setFoto((String) campoFoto.getTag());
        return aluno;
    }

    public void preencheFormulario(Aluno aluno)  {
        campoNome.setText(aluno.getNome());
        campoEndereco.setText(aluno.getEndereco());
        campoTelefone.setText(aluno.getTelefone());
        campoSite.setText(aluno.getSite());
        campoNota.setProgress(aluno.getNota().intValue());
        carregaImagem(aluno.getFoto());
        this.aluno = aluno;
    }

    public void carregaImagem(String caminhoFoto) {
        if (caminhoFoto != null){
            Bitmap bitmap = BitmapFactory.decodeFile(caminhoFoto);
            Bitmap bitmapReduzido = Bitmap.createScaledBitmap(bitmap, 300,300,true);
            campoFoto.setImageBitmap(bitmapReduzido);
            campoFoto.setScaleType(ImageView.ScaleType.FIT_XY);
            campoFoto.setTag(caminhoFoto);
        }
    }
}

Codigo Aluno

public class Aluno implements Serializable {
    private Long id;
    private String nome;
    private String endereco;
    private String telefone;
    private String site;
    private Double nota;
    private String foto;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getEndereco() {
        return endereco;
    }

    public void setEndereco(String endereco) {
        this.endereco = endereco;
    }

    public String getTelefone() {
        return telefone;
    }

    public void setTelefone(String telefone) {
        this.telefone = telefone;
    }

    public String getSite() {
        return site;
    }

    public void setSite(String site) {
        this.site = site;
    }

    public Double getNota() {
        return nota;
    }

    public void setNota(Double nota) {
        this.nota = nota;
    }

    public String getFoto() {
        return foto;
    }

    public void setFoto(String foto) {
        this.foto = foto;
    }
string
    @Override
    public String toString()  {
        return getId() + " - " + getNome();
    }
}

Codigo Formulario Activity:

public class FormularioActivity extends AppCompatActivity {

    public static final int CODIGO_CAMERA = 567;
    private FormularioHelper helper;
    private String caminhoFoto;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_formulario);

        helper = new FormularioHelper(this);

        Intent intent = getIntent();
        Aluno aluno = (Aluno) intent.getSerializableExtra("aluno");
        if (aluno.getId() != null){
            helper.preencheFormulario(aluno);
        }
        Button botaoFoto = (Button) findViewById(R.id.formulario_botao_foto);
        botaoFoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intentCamera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                caminhoFoto = getExternalFilesDir(null) + "/" + System.currentTimeMillis() + ".jpg";
                File arquivoFoto = new File(caminhoFoto);
                intentCamera.putExtra(MediaStore.EXTRA_OUTPUT,
                        FileProvider.getUriForFile(FormularioActivity.this,
                                BuildConfig.APPLICATION_ID + ".provider", arquivoFoto));
                startActivityForResult(intentCamera, CODIGO_CAMERA);
            }
        });
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == Activity.RESULT_OK){
            if (requestCode == CODIGO_CAMERA){
                helper.carregaImagem(caminhoFoto);
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_formulario, menu);
        return super.onCreateOptionsMenu(menu);
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch(item.getItemId()){
            case R.id.menu_formulario_ok:
                Aluno aluno = helper.pegaAluno();

                AlunoDAO dao = new AlunoDAO(this);
                if (aluno.getId() != null){
                    dao.alter(aluno);
                } else {
                    dao.insert(aluno);
                }
                dao.close();
                Toast.makeText(FormularioActivity.this, "Aluno " + aluno.getNome() + " salvo!", Toast.LENGTH_SHORT).show();

                finish();
                break;
        }
        return super.onOptionsItemSelected(item);
    }
}

Fala ai Tales, de boa ?

Cara vi que a versão do seu banco tá na 1, imagino que tenha esquecido de evoluir a versão, tenta colocar a depois e vê o que rola.

Fala Matheus, eu notei isso pouco depois (não atualizei aqui) mas atualizei no programa e ele permaneceu dando erro

Consegue me mostrar exatamente a exception para podermos ver ?

Vou executar o projeto de novo e já mando a exception que aparecer, vou fazer uma execução limpa, com uma maquina virtual nova

03-26 17:01:28.525 5239-5239/com.tales.agenda E/AndroidRuntime: FATAL EXCEPTION: main
                                                                Process: com.tales.agenda, PID: 5239
                                                                java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tales.agenda/com.tales.agenda.FormularioActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Long com.tales.agenda.Model.Aluno.getId()' on a null object reference
                                                                    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778)
                                                                    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
                                                                    at android.app.ActivityThread.-wrap11(Unknown Source:0)
                                                                    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
                                                                    at android.os.Handler.dispatchMessage(Handler.java:106)
                                                                    at android.os.Looper.loop(Looper.java:164)
                                                                    at android.app.ActivityThread.main(ActivityThread.java:6494)
                                                                    at java.lang.reflect.Method.invoke(Native Method)
                                                                    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
                                                                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
                                                                 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Long com.tales.agenda.Model.Aluno.getId()' on a null object reference
                                                                    at com.tales.agenda.FormularioActivity.onCreate(FormularioActivity.java:50)
                                                                    at android.app.Activity.performCreate(Activity.java:7009)
                                                                    at android.app.Activity.performCreate(Activity.java:7000)
                                                                    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
                                                                    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)

Tales,

Se não chegar um aluno, você não consegue fazer algo com ele :(

  if (aluno.getId() != null){
            helper.preencheFormulario(aluno);
        }

Nesse código você pode ter um aluno como não pode, o que eu sugiro fazer é :

  if (aluno  != null){
            helper.preencheFormulario(aluno);
        }

Putz cara, funcionou ele começando a funcionar só não ta salvando agora no contato

Ele tá gerando alguma exception ? Ou só não está salvando mesmo ?

Nenhuma Exception.

Tales, faz o seguinte:

  • desinstala o aplicativo e tenta executar novamente, nesse momento fica atento no logcat(console) quando você tentar fazer uma inserção e fala o que aconteceu por gentileza
03-27 18:42:00.472 6727-6727/? I/zygote: Not late-enabling -Xcheck:jni (already on)
03-27 18:42:00.486 6727-6727/? W/zygote: Unexpected CPU variant for X86 using defaults: x86
03-27 18:42:00.823 6727-6727/? I/InstantRun: starting instant run server: is main process
03-27 18:42:01.151 6727-6747/? D/OpenGLRenderer: HWUI GL Pipeline
03-27 18:42:01.188 6727-6747/? I/zygote: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
03-27 18:42:01.189 6727-6747/? I/OpenGLRenderer: Initialized EGL, version 1.4
03-27 18:42:01.189 6727-6747/? D/OpenGLRenderer: Swap behavior 1
03-27 18:42:01.189 6727-6747/? W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
03-27 18:42:01.189 6727-6747/? D/OpenGLRenderer: Swap behavior 0
03-27 18:42:01.198 6727-6747/? D/EGL_emulation: eglCreateContext: 0x9cf07440: maj 3 min 0 rcv 3
03-27 18:42:01.253 6727-6747/? D/EGL_emulation: eglMakeCurrent: 0x9cf07440: ver 3 0 (tinfo 0xa4d9b4f0)
03-27 18:42:01.358 6727-6747/? D/EGL_emulation: eglMakeCurrent: 0x9cf07440: ver 3 0 (tinfo 0xa4d9b4f0)
03-27 18:42:21.349 6727-6747/com.tales.agenda D/EGL_emulation: eglMakeCurrent: 0x9cf07440: ver 3 0 (tinfo 0xa4d9b4f0)
03-27 18:42:21.393 6727-6732/com.tales.agenda I/zygote: Do partial code cache collection, code=18KB, data=23KB
03-27 18:42:21.393 6727-6732/com.tales.agenda I/zygote: After code cache collection, code=18KB, data=23KB
03-27 18:42:21.393 6727-6732/com.tales.agenda I/zygote: Increasing code cache capacity to 128KB
03-27 18:42:21.394 6727-6732/com.tales.agenda I/zygote: Do partial code cache collection, code=18KB, data=40KB
03-27 18:42:21.394 6727-6732/com.tales.agenda I/zygote: After code cache collection, code=18KB, data=40KB
03-27 18:42:21.394 6727-6732/com.tales.agenda I/zygote: Increasing code cache capacity to 256KB
03-27 18:42:21.394 6727-6732/com.tales.agenda I/zygote: JIT allocated 71KB for compiled code of void android.widget.TextView.<init>(android.content.Context, android.util.AttributeSet, int, int)
03-27 18:42:21.394 6727-6732/com.tales.agenda I/zygote: Compiler allocated 4MB to compile void android.widget.TextView.<init>(android.content.Context, android.util.AttributeSet, int, int)
03-27 18:42:21.484 6727-6727/com.tales.agenda V/View: dispatchProvideAutofillStructure(): not laid out, ignoring 0 children of 1073741835
03-27 18:42:21.491 6727-6727/com.tales.agenda I/AssistStructure: Flattened final assist data: 3656 bytes, containing 1 windows, 13 views
03-27 18:42:25.231 6727-6747/com.tales.agenda D/EGL_emulation: eglMakeCurrent: 0x9cf07440: ver 3 0 (tinfo 0xa4d9b4f0)
03-27 18:42:30.265 6727-6747/com.tales.agenda D/EGL_emulation: eglMakeCurrent: 0x9cf07440: ver 3 0 (tinfo 0xa4d9b4f0)
03-27 18:42:30.799 6727-6732/com.tales.agenda I/zygote: Do full code cache collection, code=122KB, data=90KB
03-27 18:42:30.799 6727-6732/com.tales.agenda I/zygote: After code cache collection, code=113KB, data=67KB
03-27 18:42:41.206 6727-6747/com.tales.agenda D/EGL_emulation: eglMakeCurrent: 0x9cf07440: ver 3 0 (tinfo 0xa4d9b4f0)
03-27 18:42:41.218 6727-6747/com.tales.agenda D/EGL_emulation: eglMakeCurrent: 0x9cf07440: ver 3 0 (tinfo 0xa4d9b4f0)
03-27 18:42:41.263 6727-6732/com.tales.agenda I/zygote: Do partial code cache collection, code=124KB, data=77KB
03-27 18:42:41.263 6727-6732/com.tales.agenda I/zygote: After code cache collection, code=124KB, data=77KB
03-27 18:42:41.263 6727-6732/com.tales.agenda I/zygote: Increasing code cache capacity to 512KB

Tales, não identifiquei nenhum problema :(

Quer me passar o código via github ? Que dessa forma rodo e debugo o sistema para você ?

não possuo GitHub, segue o link para baixar o projeto pelo drive, no aguardo de informações https://drive.google.com/drive/folders/1PHObwGS-n-EcwpuAL59tjuUqLztUeV2x?usp=sharing

Deu em algo, Matheus?

Tales

Funcionou tive que fazer uma pequena alteração no seu código:


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_OK){
            if (requestCode == CODIGO_CAMERA){
                helper.carregaImagem(caminhoFoto);
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

De restante funcionou sem problemas. Imagino que você tenha se enrolado no momento de alterar as versões e não deve ter funcionado corretamente :(