android.os.FileUriExposedException: file.jpg expuestos más allá de la aplicación a través de ClipData.Elemento.getUri()

Trataré de hacer un botón que abra la cámara y tomar la foto. mi código es aquí

//for imports check on bottom of this code block

public class HomeProfileActivity extends AppCompatActivity {
//Button camera
public static final String TAG = HomeProfileActivity.class.getSimpleName();
public static final int REQUEST_TAKE_PHOTO = 0;
public static final int REQUEST_TAKE_VIDEO = 1;
public static final int REQUEST_PICK_PHOTO = 2;
public static final int REQUEST_PICK_VIDEO = 3;
public static final int MEDIA_TYPE_IMAGE = 4;
public static final int MEDIA_TYPE_VIDEO = 5;

private Uri mMediaUri;
private ImageView photobutton;
private Button buttonUploadImage, buttonTakeImage;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home_profile);
    ButterKnife.bind(this);
}

@OnClick(R.id.buttonTakeImage)
void takePhoto() {
    mMediaUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
    if (mMediaUri == null) {
        Toast.makeText(this,
                "There was a problem accessing your device's external storage.",
                Toast.LENGTH_LONG).show();
    }
    else {
        Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, mMediaUri);
        startActivityForResult(takePhotoIntent, REQUEST_TAKE_PHOTO);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == RESULT_OK){
        if (requestCode == REQUEST_TAKE_PHOTO) {
            Intent intent = new Intent(this, ViewImageActivity.class);
            intent.setData(mMediaUri);
            startActivity(intent);
        }
    }
    else if (resultCode != RESULT_CANCELED){
        Toast.makeText(this, "Sorry, there was an error", Toast.LENGTH_SHORT).show();
    }
}

private Uri getOutputMediaFileUri(int mediaType) {
    //check for external storage
    if (isExternalStorageAvailable()) {
        //get the URI

        //1. Get the external storage directory
        File mediaStorageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);

        //2. Create a unique file name
        String fileName = "";
        String fileType = "";
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());

        if (mediaType == MEDIA_TYPE_IMAGE) {
            fileName = "IMG_" + timeStamp;
            fileType = ".jpg";
        } else if (mediaType == MEDIA_TYPE_VIDEO) {
            fileName = "VID_" + timeStamp;
            fileType = ".mp4";
        } else {
            return null;
        }
        //3. Create the file
        File mediaFile;
        try {
            mediaFile = File.createTempFile(fileName, fileType, mediaStorageDir);
            Log.i(TAG, "File: " + Uri.fromFile(mediaFile));

            //4. Return the file's URI
            return Uri.fromFile(mediaFile);
        }
        catch (IOException e) {
                Log.e(TAG, "Error creating file: " +
                        mediaStorageDir.getAbsolutePath() + fileName + fileType);
            }
        }

        //something went wrong
        return null;
    }

private boolean isExternalStorageAvailable(){
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)){
        return true;
    }
    else {
        return false;
    }
}

import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import butterknife.ButterKnife;
import butterknife.OnClick;

También tengo un problema con startActivityForResult en el método onclick
y la importación java.text.SimpleDateFormat; también saltar en la excepción en tiempo de ejecución
estoy trabajando con buildtoolsversion sdk de 25

InformationsquelleAutor Omer | 2017-02-15

3 Kommentare

  1. 124

    Además de la solución mediante el FileProvider, no hay otra forma de solucionar este problema. Simplemente poner

     StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
     StrictMode.setVmPolicy(builder.build());

    en la Aplicación.onCreate() método. De esta manera, el VM ignora el URI del archivo de la exposición.

    • Esto funcionó para mí, gracias, cualquier cosa que debo saber para un posible problema futuro o soy bueno para un rato?
    • trabaja muy bien, gracias rahul
    • Gracias por la gran respuesta..
    • sigue recibiendo el mismo error
    • muy bonita respuesta, muchas Gracias.
    • Funciona de verdad!
    • StrictMode está desactivado por defecto, y los usuarios deben introducir «Developer mode» en su dispositivo Android para activarlo. Que hace que la solución de la utilización de StrictMode irrelevante.
    • alguien ha probado en la producción y trabajado?
    • muy bonito lo que realmente trabajó como un encanto… gracias
    • Gracias Guru de su trabajo…
    • Gracias, trabajando para mí. Dispositivo de prueba de Android : 7.0 targetSdkVersion 26
    • superrr yar…… gracias
    • Trabajó como un encanto!

  2. 26

    Esta info es de:
    FileUriExposedException

    Este es lanzado para aplicaciones dirigidas a la N o superior.
    Aplicaciones de la orientación de anteriores versiones de SDK permite compartir
    file://Uri, pero se recomienda.

    Así que si tu app/build.gradle del archivo compileSdkVersion (build target) es Android N (API level 24) o mayor, este error se produce si se escribir en un archivo que, posiblemente, puede obtener acceso a otras aplicaciones. Lo que es más importante, aquí es cómo se supone que para hacer que se mueva hacia adelante:

    tomado de aquí:
    FileProvider

    Cambio:

    return Uri.fromFile(mediaFile);

    a ser

    return FileProvider.getUriForFile(getApplicationContext(), getPackageName()+".fileprovider", mediaFile);

    Nota: si el control de mydomain.com también se puede sustituir getPackageName()+".fileprovider" con "com.mydomain.fileprovider" (lo mismo va para su AndroidManifest.xml a continuación.

    También es necesario agregar el siguiente a su AndroidManifest.xml archivo justo antes de su </application> etiqueta

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

    Entonces usted necesita para agregar un archivo llamado filepaths.xml a su app/src/main/res/xml directorio con el siguiente contenido

    <paths>
        <external-files-path name="Pictures" path="Pictures" />
    </paths>

    Nota: para nadie, hemos utilizado external-files-path anteriormente, ya que Omer utilizado getExternalFilesDir(Environment.DIRECTORY_PICTURES) en el código. Para cualquier otro lugar, por favor, compruebe FileProvider bajo la «Especificación Disponible sección» Archivos » y cambiar external-files-path a uno de los siguientes basado en donde se encuentran sus archivos:

    files-path
    cache-path
    external-path
    external-files-path
    external-cache-path

    También, revisar Pictures de arriba para ser su nombre de la carpeta.

    Un importante anti-patrón para evitar que se debe NO uso if (Build.VERSION.SDK_INT < 24) { para permitir que usted haga de la manera antigua, porque no es su versión de Android que requiere este, es su versión de compilación (me perdí la primera vez que me codificado).

    Sé que esto es más trabajo, sin embargo, esto permite Android para permitir el paso de otra aplicación que vas a compartir, el acceso temporal para el archivo, que es más segura para la privacidad del usuario.

    • Sólo la edición rápida: el path=»fotos» es sensible a mayúsculas y minúsculas. Cuando se utiliza el medio Ambiente.DIRECTORY_PICTURES en mi final, tuve que sacar provecho como path=»Imágenes», de lo contrario no podía figura de un camino.
    • Gracias por darse cuenta de que, he actualizado mi respuesta para reflejar el caso de medio Ambiente.DIRECTORY_PICTURES, que evalúa a las «Imágenes» (Título)
  3. 0
    Add the below code where the SharingIntent called:-
    
    if(Build.VERSION.SDK_INT>=24){
                        try{
                            Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure");
                            m.invoke(null);
                            shareImage(Uri.fromFile(new File(Path)));
                        }catch(Exception e){
                            e.printStackTrace();
                        }
                    }

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Recent Articles

Python «set» con duplicados/elementos repetidos

Hay una forma estándar de representar un "conjunto" que puede contener elementos duplicados. Como yo lo entiendo, un conjunto tiene exactamente un cero o...

Python: generador de expresión vs rendimiento

En Python, ¿hay alguna diferencia entre la creación de un generador de objetos a través de un generador de expresión versus el uso de...

Cómo exportar/importar la Masilla lista de sesiones?

Hay una manera de hacer esto? O tengo que tomar manualmente cada archivo de Registro? InformationsquelleAutor s.webbandit | 2012-10-23

no distingue mayúsculas de minúsculas coincidentes en xpath?

Por ejemplo, para el xml a continuación <CATALOG> <CD title="Empire Burlesque"/> <CD title="empire burlesque"/> <CD...