5
respostas

android.os.FileUriExposedException:

Quando clico no botão aparece esse erro e fecha o meu aplicativo! Socorrooo

5 respostas

Anderson, tu tem que colocar mais explicações do teu erro. Cola aqui todo erro que aparece no teu logcat

Pelo oq eu vi na documentação o jeito ensinado aqui no curso não funciona no android 7.0 (Nougat) pois ele usa outros metodos para a segurança do dispositivo. Ele usa o FileProvider para liberar as permissões

E/AndroidRuntime: FATAL EXCEPTION: main Process: br.com.alura, PID: 461 android.os.FileUriExposedException: file:///data/user/0/br.com.alura/files/1478668498471.jpg exposed beyond app through ClipData.Item.getUri() at android.os.StrictMode.onFileUriExposed(StrictMode.java:1799) at android.net.Uri.checkFileUriExposed(Uri.java:2346) at android.content.ClipData.prepareToLeaveProcess(ClipData.java:832) at android.content.Intent.prepareToLeaveProcess(Intent.java:8909) at android.content.Intent.prepareToLeaveProcess(Intent.java:8894) at android.app.Instrumentation.execStartActivity(Instrumentation.java:1517) at android.app.Activity.startActivityForResult(Activity.java:4224) at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:48) at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:77) at android.app.Activity.startActivityForResult(Activity.java:4183) at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:859) at android.app.Activity.startActivity(Activity.java:4507) at android.app.Activity.startActivity(Activity.java:4475) at br.com.alura.ListaAluraActivity$1.onClick(ListaAluraActivity.java:45) at android.view.View.performClick(View.java:5609) at android.view.View$PerformClick.run(View.java:22262) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6077) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

também caí nesse erro

Amigos, a partir da API 24, o android considera uma falha grave de segurança a exposição de uris que digam respeito a arquivos (file://). Então, sempre que propagar um intent pelo sistema com uma uri desse tipo, receberá uma FileUriExposedException em resposta. A solução é criar um content provider especializado pra essa situação. Ele se chama File Provider. Vejam nos links abaixo como implementar. Abraços!

Esta atualização do Android deixou mais complexo fazer algo que é tão simples e trivial, eu consegui concluir o exercicio depois de algumas pesquisas.

Primeiro o arquivo AndroidManifest.xml deve ser alterado, adicionando a tag provider como nesse código:

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

    ...

    <application
       ...

        <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 se cria dentro da pasta res uma subpasta chamada xml, que deve contar o arquivo provider_paths.xml com o seguinte conteudo

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

No final, eu adicionei um objeto Uri, que segundo a documentação deve ter o retorno da função que faz uso desse xml. A chamada do intent ficará mais ou menos assim:

Button TirarFoto = (Button) findViewById(R.id.formulario_tirarfoto);
        TirarFoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intentTirarFoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                String caminhoFoto = getExternalFilesDir(null) + "/" + System.currentTimeMillis() + ".jpg";
                File foto = new File(caminhoFoto);
                Uri fotoURI = FileProvider.getUriForFile(FormularioActivity.this, BuildConfig.APPLICATION_ID + ".provider", foto);
                intentTirarFoto.putExtra(MediaStore.EXTRA_OUTPUT, fotoURI);
                startActivityForResult(intentTirarFoto, CODIGO_FOTO);
            }
        });

Aqui funcionou, pelo menos tira a foto e retorna para o app, vamos ver se nos proximos exercicios essa alteração vai influenciar nas respostas.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software