Проблема, открыв камеру в приложении Android

Кнопка, которую нажав на него откроет камера терминала через один intent , он сделает фотографию и будет сохранять ее в каталоге, вышеупомянутом с приложения.

Моя проблема появляется во время открытия камеры, я не могу открыть ее и получаю следующую ошибку, нажав на кнопку, которая была бы должна открывать ее:

И / камера: android.os. FileUriExposedException: file:///storage/emulated/0/imagen.jpg exposed beyond app through ClipData. Item.getUri ()

Здесь я оставляю вам код моего приложения:

MainActivity.java

import android.Manifest;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.FileUriExposedException;
import android.provider.MediaStore;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.File;

public class MainActivity extends AppCompatActivity {

    private static final int TAKE_PICTURE = 0;
    private Uri imageUri;

    @RequiresApi(api = Build.VERSION_CODES.N)

    public void hacerFoto(View view) {

        ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);

        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File photo = new File(Environment.getExternalStorageDirectory(), "imagen.jpg");
        intent.putExtra(MediaStore.EXTRA_OUTPUT,
                Uri.fromFile(photo));
        imageUri = Uri.fromFile(photo);
        try {
            startActivityForResult(intent, TAKE_PICTURE);
        } catch (Exception e) {
            Toast.makeText(this, "Error al abrir la cámara:"+e.toString(), Toast.LENGTH_SHORT)
                    .show();
            Log.e("Cámara ", e.toString());
        }
    }

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

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        setContentView(R.layout.activity_main);
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case TAKE_PICTURE:
                if (resultCode == Activity.RESULT_OK) {
                    Uri selectedImage = imageUri;
                    getContentResolver().notifyChange(selectedImage, null);
                    ImageView imageView = (ImageView) findViewById(R.id.imageView);
                    ContentResolver cr = getContentResolver();
                    Bitmap bitmap;
                    try {
                        bitmap = android.provider.MediaStore.Images.Media
                                .getBitmap(cr, selectedImage);

                        imageView.setImageBitmap(bitmap);
                        Toast.makeText(this, selectedImage.toString(),
                                Toast.LENGTH_LONG).show();
                    } catch (Exception e) {
                        Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT)
                                .show();
                        Log.e("Camera", e.toString());
                    }
                }
        }
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="asier.dam2.camaraandroid.MainActivity">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:srcCompat="@mipmap/ic_launcher"
        android:id="@+id/imageView"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_above="@+id/button" />

    <Button
        android:text="Hacer foto"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:id="@+id/button"
        android:onClick="hacerFoto" />
</RelativeLayout>

Разрешения, которые я добавляю в AndroidManifest.xml:

 <uses-permission android:name="android.permission.CAMERA" />
        <uses-feature android:name="android.hardware.camera" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Что я врежу?

3
задан 19.01.2017, 19:16
0 ответов

Эта ошибка FileUriExposedException произведена в Андроид Н:

android.os. FileUriExposedException: file:///storage/emulated/0/imagen.jpg exposed beyond app through ClipData. Item.getUri ()

Ты можешь реализовывать изменение, получив Uri файла посредством:

imageUri = Uri.parse(filepath);

Это было бы изменение в коде:

...
...
       Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        //File photo = new File(Environment.getExternalStorageDirectory(), "imagen.jpg");
        String filePath = Environment.getExternalStorageDirectory() +  "imagen.jpg";
        //intent.putExtra(MediaStore.EXTRA_OUTPUT,
                Uri.fromFile(new File(filepath)));
        //imageUri = Uri.fromFile(photo);

        //Validación de acuerdo al OS.            
        if (Build.VERSION.SDK_INT >=  Build.VERSION_CODES.N) {
              imageUri = Uri.parse(filepath);
        } else{
               imageUri = Uri.fromFile(new File(filepath));
        }

        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);

       try {
            startActivityForResult(intent, TAKE_PICTURE);
        } catch (Exception e) {
            Toast.makeText(this, "Error al abrir la cámara:"+e.toString(), Toast.LENGTH_SHORT)
                    .show();
            Log.e("Cámara ", e.toString());
        }
...
...

Другое решение состоит в том, чтобы менять targetSdkVersion в меньшую версию 24 (Android N)

6
ответ дан 03.12.2019, 17:37
  • 1
    ¿ Я спутан или это tambié n significarí в который aplicació n он не прокручивает изображение в окне в Android 24 +? Обычно serí чтобы лучше оставлять targetSdkVersion в самой недавней и отличать из-за anotació n, что mé все используется, или нет? –  19.01.2017, 23:19
  • 2
    Имеется maxSdkVersion, что определяет, который является самым большим API, который может выносить aplicació n, но если он не включается, из-за default определяют, что он может работать во всех не импортируя targetSdkVersion. developer.android.com/guide/topics/manifest/… –  19.01.2017, 23:24
  • 3
    В будущем, в algú n момент tendrí которого 24 менять в targetSdkVersion или последующие. Но solució n rá попросите, чтобы, чтобы предотвращать Буг, это была вторая, что я предлагаю. Идеальное состоит в том, чтобы санкционировать có я говорю как первая opció n для того, чтобы оно функционировало во всех (вЊђв – _в –) –  19.01.2017, 23:26

С API 24 уже не возможно имения URI в Intent. Проблема вызвана из-за:

       intent.putExtra(MediaStore.EXTRA_OUTPUT,
            Uri.fromFile(photo));

Чтобы это решать ты должен использовать поставщик:

    Uri contentUri = FileProvider.getUriForFile(getContext(),"com.your.package.fileProvider", newFile);

Спроси в stackoverflow на английском на теме

Документация на FileProvider

2
ответ дан 03.12.2019, 17:37
  • 1
    Привет дружелюбный Стефан, мне кажется, что проблема такая, как получается Uri в Андроид Н, сейчас должно быть с Uri.parse (); = | –  19.01.2017, 20:25