Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
19
respostas

Problema ao persistir imagem da camera no Formulario

Senhores, boa tarde!

Não estou conseguindo persistir a imagem no formulário. Até chega a aparecer a imagem no campo quando tiro a foto, mas quando vou editar, a imagem já nao esta mais lá...

Segue meus codigos:

FormularioActivity Metodos: onCreate e onActivityResult

            @Override
            public void onClick(View v) {
                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 == CODIGO_CAMERA && resultCode == FormularioActivity.RESULT_OK) {
            ImageView campoFoto = (ImageView) findViewById(R.id.formulario_foto);
            Bitmap bitmap = BitmapFactory.decodeFile(caminhoFoto);
            Bitmap bitmapReduzido = bitmap.createScaledBitmap(bitmap, 300, 300, true);
            campoFoto.setImageBitmap(bitmapReduzido);
            campoFoto.setTag(caminhoFoto);
        }
    }

provider_paths (o link a partir do "http://" esta em cinza, dizendo que nao esta em uso.

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="." />
</paths>

AndroidManifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="br.com.tcc.tcc">

    <uses-permission android:name="android.permission.CALL_PHONE"/>


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".ListaPetsActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".FormularioActivity"
            android:label="@string/title_activity_formulario"
            />

        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
        </provider>

    </application>

</manifest>
19 respostas

Fala ai Vitor, tranquilo ?

Cara imagino que o problema esteja no seu helper no momento que você recupera o aluno do formulário, imagino que você tenha esquecido de setar a propriedade da foto nele, consegue confirmar isso para gente ?

Fala Matheus, beleza sim, e vc ?

Claro, vou disponibilizar abaixo:

public class FormularioHelper {

    private EditText campoAnimal;
    private EditText campoEndereco;
    private EditText campoTelefone;

    private Pet pet;

    public FormularioHelper(FormularioActivity activity) {
        this.campoAnimal = (EditText) activity.findViewById(R.id.formulario_animal);
        this.campoEndereco = (EditText) activity.findViewById(R.id.formulario_endereco);
        this.campoTelefone = (EditText) activity.findViewById(R.id.formulario_telefone);
        pet = new Pet();
    }

    public Pet pegaPet() {

        pet.setAnimal(campoAnimal.getText().toString());
        pet.setEndereco(campoEndereco.getText().toString());
        pet.setTelefone(campoTelefone.getText().toString());

        return pet;
    }

    public void preencheForm(Pet pet) {
        campoAnimal.setText(pet.getAnimal());
        campoEndereco.setText(pet.getEndereco());
        campoTelefone.setText(pet.getTelefone());
        this.pet = pet;
    }
}

Vitor repare que em nenhum momento você manipulou a foto ai no seu helper, precisa adequar seu código para que quando for preencher o form e quando pega as informações dele, a foto estar junto.

Olá Matheus,

Entendi, de qualquer forma a imagem não é um campo texto comum, como os demais fields do formulario.. Como poderia referenciar um campo de imagem no meu Helper? Em alguma aula o professor chegou a alterar o Helper?

você vai ter o image view lá.

Sim, ele faz essa refatoração no momento da camera e nos exercícios também.

Oi Matheus,

Desde ja agradeço sua ajuda. Mas estou procurando nos exercicios e nas aulas, e nao encontrei a aula no qual ele coloca no helper.. Poderia me enviar o link, pra ver se eu nao estou comendo "comendo bola" ? rsrsrs

https://cursos.alura.com.br/course/android-studio-ii-integracoes-e-recursos/task/23377

olha a opnião do instrutor

Show, achei.. Mas surgiu uma duvida: ele pede pra adicionarmos o carregaFoto no helper, eu tenho quew declarar o "foto" como um atributo tipo do tipo imageView na classe , como no exemplo abaixo? No codigo desse link que voce mandou, ele pede pra dicionarmos o carregaFoto no helper, conforme abaixo:

 public void carregaFoto(String caminhoFoto) {

        Bitmap bm = BitmapFactory.decodeFile(caminhoFoto);
        bm = Bitmap.createScaledBitmap(bm, 100, 100, true);
        foto.setImageBitmap(bm);
        foto.setScaleType(ImageView.ScaleType.FIT_XY);

    }

Neste caso o certo devemos adicionar um atributo na classe como imageView ? Igual fiz abaixo?

public class FormularioHelper {

    private EditText campoAnimal;
    private EditText campoEndereco;
    private EditText campoTelefone;
    private ImageView foto;


    private Pet pet;

    public FormularioHelper(FormularioActivity activity) {
        this.campoAnimal = (EditText) activity.findViewById(R.id.formulario_animal);
        this.campoEndereco = (EditText) activity.findViewById(R.id.formulario_endereco);
        this.campoTelefone = (EditText) activity.findViewById(R.id.formulario_telefone);
        pet = new Pet();
    }

    public Pet pegaPet() {

        pet.setAnimal(campoAnimal.getText().toString());
        pet.setEndereco(campoEndereco.getText().toString());
        pet.setTelefone(campoTelefone.getText().toString());

        return pet;
    }

    public void preencheForm(Pet pet) {
        campoAnimal.setText(pet.getAnimal());
        campoEndereco.setText(pet.getEndereco());
        campoTelefone.setText(pet.getTelefone());
        this.pet = pet;
    }

    public void carregaFoto(String caminhoFoto) {

        Bitmap bm = BitmapFactory.decodeFile(caminhoFoto);
        bm = Bitmap.createScaledBitmap(bm, 100, 100, true);
        foto.setImageBitmap(bm);
        foto.setScaleType(ImageView.ScaleType.FIT_XY);

    }
}

Exatamente!!!

Matheus, primeiramente gostaria de te agradecer por toda ajuda, e se estou com um pouco mais de logica foi pelo curso e material de voces rsrsrs

Otimo saber que estou no caminho certo, porém estou tomando o seguinte NullPointer:

FATAL EXCEPTION: main
                                                                Process: br.com.tcc.tcc, PID: 29067
                                                                java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.widget.ImageView.getTag()' on a null object reference
                                                                    at br.com.tcc.tcc.FormularioHelper.pegaPet(FormularioHelper.java:37)

Segue meus codigos:

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);

        final Intent intent = getIntent();
        Pet pet = (Pet) intent.getSerializableExtra("pet");
        if (pet != null){
            helper.preencheForm(pet);
        }

    Button botaoFoto = (Button) findViewById(R.id.formulario_botao_foto);
        botaoFoto.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                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) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CODIGO_CAMERA) {
            if (resultCode == RESULT_OK) {
                helper.carregaFoto(caminhoFoto);
            }
        }
    }

    @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:

                Pet pet = helper.pegaPet();
                PetDAO dao = new PetDAO(this);

                if(pet.getId() != null) {
                    dao.altera(pet);
                }else {

                    dao.insere(pet);
                }
                dao.close();

                Toast.makeText(FormularioActivity.this,"O seu PET: " +pet.getAnimal()+ " foi Cadastrado com Sucesso!", Toast.LENGTH_SHORT).show();

                finish();
                break;
        }

        return super.onOptionsItemSelected(item);
    }
}
public class Pet implements Serializable{

    private Long Id;
    private String animal;
    private String endereco;
    private String telefone;
    private String caminhoFoto;



    public Pet() {
    }

    public Long getId() {
        return Id;
    }

    public void setId(Long id) {
        Id = id;
    }

    public String getAnimal() {
        return animal;
    }

    public void setAnimal(String animal) {
        this.animal = animal;
    }

    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 getCaminhoFoto() {
        return caminhoFoto;
    }

    public void setCaminhoFoto(String caminhoFoto) {
        this.caminhoFoto = caminhoFoto;
    }

    @Override
    public String toString()  {
        return getId() + " - " + getAnimal();
    }
}

No seu helper você esqueceu de fazer a busca pelo image view, ou seja, o findviewbyid

public class FormularioHelper {

    private EditText campoAnimal;
    private EditText campoEndereco;
    private EditText campoTelefone;
    private ImageView foto;


    private Pet pet;

    public FormularioHelper(FormularioActivity activity) {
        this.campoAnimal = (EditText) activity.findViewById(R.id.formulario_animal);
        this.campoEndereco = (EditText) activity.findViewById(R.id.formulario_endereco);
        this.campoTelefone = (EditText) activity.findViewById(R.id.formulario_telefone);
        pet = new Pet();
    }

    public Pet pegaPet() {

        pet.setAnimal(campoAnimal.getText().toString());
        pet.setEndereco(campoEndereco.getText().toString());
        pet.setTelefone(campoTelefone.getText().toString());
        pet.setCaminhoFoto((String) foto.getTag());

        return pet;
    }

    public void preencheForm(Pet pet) {
        campoAnimal.setText(pet.getAnimal());
        campoEndereco.setText(pet.getEndereco());
        campoTelefone.setText(pet.getTelefone());
        this.pet = pet;

        if (pet.getCaminhoFoto() != null) {
            carregaFoto(pet.getCaminhoFoto());
        }
    }

    public void carregaFoto(String caminhoFoto) {

        Bitmap bm = BitmapFactory.decodeFile(caminhoFoto);
        bm = Bitmap.createScaledBitmap(bm, 100, 100, true);
        foto.setImageBitmap(bm);
        foto.setScaleType(ImageView.ScaleType.FIT_XY);
        foto.setTag(caminhoFoto);

    }


}

Você não o buscou na tela, percebe que fez isso para os outros campos no construtor e o campo de foto não foi lembrado?

Exatamente Matheus,

Agora a exception foi que nao encontrou o campo do caminhoFoto conforme abaixo:

FATAL EXCEPTION: main
                                                                Process: br.com.tcc.tcc, PID: 31865
                                                                android.database.sqlite.SQLiteException: no such column: caminhoFoto (code 1): , while compiling: UPDATE PET SET animal=?,caminhoFoto=?,telefone=?,endereco=? WHERE id = ?
                                                                    at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)

Neste caso como posso resolver ?

 public PetDAO(Context context) {
        super(context, "TCC", null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
            String sql = "CREATE TABLE PET (id INTEGER PRIMARY KEY, animal TEXT NOT NULL, caminhoFoto TEXT, endereco TEXT NOT NULL, telefone TEXT NOT NULL);";
            db.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //String sql = "DROP TABLE IF EXISTS PET;";
        String sql = "";
        switch (oldVersion){
            case 1 :
                sql = "Alter table PET add colunm caminhoFoto text;";
                db.execSQL(sql);

        }
        //db.execSQL(sql);
        //onCreate(db);

    }

    public void insere(Pet pet) {

        SQLiteDatabase db = getWritableDatabase();

        ContentValues dados = pegaDadosDoPet(pet);
        dados.put("caminhoFoto", pet.getCaminhoFoto());

        db.insert("PET",null,dados);

    }

    @NonNull
    private ContentValues pegaDadosDoPet(Pet pet) {
        ContentValues dados = new ContentValues();
        dados.put("animal", pet.getAnimal());
        dados.put("endereco",pet.getEndereco());
        dados.put("telefone", pet.getTelefone());
        return dados;
    }

    public List<Pet> buscaPets() {
        String sql = "SELECT * FROM PET;";
        SQLiteDatabase db = getReadableDatabase();
        Cursor c = db.rawQuery(sql,null);

        List<Pet> pets = new ArrayList<Pet>();
        while (c.moveToNext()) {
            Pet pet = new Pet();
            pet.setId(c.getLong(c.getColumnIndex("id")));
            pet.setAnimal(c.getString(c.getColumnIndex("animal")));
            pet.setEndereco(c.getString(c.getColumnIndex("endereco")));
            pet.setTelefone(c.getString(c.getColumnIndex("telefone")));


            pets.add(pet);
        }
        c.close();

            return pets;
    }

    public void deleta(Pet pet) {
        SQLiteDatabase db = getWritableDatabase();
        String[] params = {pet.getId().toString()};
        db.delete("Pet", "id= ?", params);
    }

    public void altera(Pet pet) {
        SQLiteDatabase db = getWritableDatabase();

        ContentValues dados = pegaDadosDoPet(pet);
        dados.put("caminhoFoto", pet.getCaminhoFoto());

        String[] params = {pet.getId().toString()};
        db.update("PET", dados, "id = ?", params);
    }

Voce não alterou a versão do banco, da uma olhadinha no super que você chama no construtor.

Alterei agora pra version:2, mas continua tomando a exception de nao encontrar a coluna caminhoFoto...

public class PetDAO extends SQLiteOpenHelper{


    public PetDAO(Context context) {
        super(context, "TCC", null, 2);
    }
FATAL EXCEPTION: main
                                                                Process: br.com.tcc.tcc, PID: 32486
                                                                android.database.sqlite.SQLiteException: no such column: caminhoFoto (code 1): , while compiling: UPDATE PET SET animal=?,caminhoFoto=?,telefone=?,endereco=? WHERE id = ?
                                                                    at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)

Matheus,

Exclui a aplicaçao e reinstalei, nao estou mais tomando erros, mas mesmo assim quando vou editar o cadastro a imagem nao esta persistindo

solução!

Vitor, você escreveu errou no momento de alterar, é column e não colonm. rs

Acho que você também não tá completando as informações na hora de editar e salvar, só tá mandando a foto, precisa mandar tudo.

Ufaaaaaa! Valeu Matheus, finalmente conseguimos resolver, valeu mesmo... Como voce disse no metodo de listar, eu nao havia colocado o atributo do caminho da foto, ficou assim:

public List<Pet> buscaPets() {
        String sql = "SELECT * FROM PET;";
        SQLiteDatabase db = getReadableDatabase();
        Cursor c = db.rawQuery(sql,null);

        List<Pet> pets = new ArrayList<Pet>();
        while (c.moveToNext()) {
            Pet pet = new Pet();
            pet.setId(c.getLong(c.getColumnIndex("id")));
            pet.setAnimal(c.getString(c.getColumnIndex("animal")));
            pet.setEndereco(c.getString(c.getColumnIndex("endereco")));
            pet.setTelefone(c.getString(c.getColumnIndex("telefone")));
            pet.setCaminhoFoto(c.getString(c.getColumnIndex("caminhoFoto")));


            pets.add(pet);
        }
        c.close();

            return pets;
    }

Aproveitei e mudei o "colunm" para "column" rsrsrsrsrrs Valeu mesmo querido, vocês saão 10!