Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

O aplicativo trava quando clico no ícone da câmera

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);
                String caminhoFoto = getExternalFilesDir(null) + "/" + System.currentTimeMillis() + ".jpg";
                File arquivoFoto = new File (caminhoFoto);
                intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(arquivoFoto));
                startActivity(intentCamera);
            }
        });
5 respostas

Parece que o programa Agenda não tem permissão para acessar a câmera. O problema é que não encontro ele na lista para incluir essa permissão. Obs: estou rodando o programa no meu próprio celular.

Olá Michel,

Qual a versão do Android no seu celular? Se você estiver usando a versão 7 ou superior vai ser necessário fazer um procedimento adicional para permitir que a câmera escreva na área de arquivos do nosso aplicativo.

Esse procedimento está descrito em uma das atividades da câmera e você pode acessá-lo no link abaixo clicando no botão para visualizar a opinião do instrutor:

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

Se a versão for anterior ao Android 7, posta aqui pra gente a mensagem de erro (a stack trace se existir) pra gente tentar ajudar, ok?

Meu android é o 7.0. Fiz os seguintes passos:

primeiro, alterei o AndroidManifest.xml:

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

    <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=".ListaAlunosActivity">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

        </activity>
        <activity android:name=".FormularioActivity">

        </activity>

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

Depois, criei uma pasta chamada xml dentro do res. Nela, criei o arquivo provider_paths.xml com o seguinte conteúdo:

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

Por fim, modifiquei a intent da câmera, no FormularioActivity.java. Ficou assim:

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 (this,BuildConfig.APPLICATION_ID + ".provider", arquivoFoto));
                startActivityForResult(intentCamera, CODIGO_CAMERA);
            }
        });
    }

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

O erro que dá é o seguinte: error:incompatible types cannot be converted to Context

solução!

Olá Michel,

Acredito que o problema esteja neste trecho de código:

 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 (this,BuildConfig.APPLICATION_ID + ".provider", arquivoFoto));
                startActivityForResult(intentCamera, CODIGO_CAMERA);
            }
        });

Repara que em algum momento chamamos esse código:

FileProvider.getUriForFile (this,BuildConfig.APPLICATION_ID + ".provider", arquivoFoto));

O método getUriForFile() pede como primeiro parâmetro um contexto, só que o this nesse ponto representa uma referência para uma classe anônima que é o listener do seu botão. Nesse caso, você pode trocar o this por getBaseContext() ou por FormularioActivity.this.

Tenta fazer essa modificação e vê se resolve o problema.

Funcionou. Coloquei FormularioActivity.this.

Nas instruções do link fala para colocar só this.

Obrigado.