through studio item intent geturi fileuriexposedexception fileprovider exposed example clipdata beyond app and android camera uri mediastore image-capture

studio - java android take photo



cuando tome una foto, obtenga-java.lang.Throwable: file:// Uri expuesto a través de ClipData.Item.getUri() (5)

Además de la solución que utiliza FileProvider, hay otra forma de solucionar esto. Simplemente póngalo en el método Application.onCreate (). De esta manera, la máquina virtual ignora la exposición del archivo URI.

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

La excepción es:

file:// Uri exposed through ClipData.Item.getUri() java.lang.Throwable: file:// Uri exposed through ClipData.Item.getUri() at android.os.StrictMode.onFileUriExposed(StrictMode.java:1618) at android.net.Uri.checkFileUriExposed(Uri.java:2341) at android.content.ClipData.prepareToLeaveProcess(ClipData.java:808) at android.content.Intent.prepareToLeaveProcess(Intent.java:7926) at android.app.Instrumentation.execStartActivity(Instrumentation.java:1506) at android.app.Activity.startActivityForResult(Activity.java:3832) at android.app.Activity.startActivityForResult(Activity.java:3783) at android.support.v4.app.FragmentActivity.startActivityFromFragment(Unknown Source) at android.support.v4.app.Fragment.startActivityForResult(Unknown Source) at me.chunyu.ChunyuDoctor.Utility.w.takePhoto(Unknown Source) at me.chunyu.ChunyuDoctor.Dialog.ChoosePhotoDialogFragment.takePhoto(Unknown Source) at me.chunyu.ChunyuDoctor.Dialog.ChoosePhotoDialogFragment.access$000(Unknown Source) at me.chunyu.ChunyuDoctor.Dialog.b.onClick(Unknown Source) at me.chunyu.ChunyuDoctor.Dialog.ChoiceDialogFragment.onClick(Unknown Source) at android.view.View.performClick(View.java:4848) at android.view.View$PerformClick.run(View.java:20270) at android.os.Handler.handleCallback(Handler.java:815) at android.os.Handler.dispatchMessage(Handler.java:104) at android.os.Looper.loop(Looper.java:194) at android.app.ActivityThread.main(ActivityThread.java:5643) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

Mi código está aquí:

public static void takePhoto(Fragment fragment, int token, Uri uri) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (uri != null) { intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); } fragment.startActivityForResult(intent, token); }

Busqué los problemas y soluciones similares. Y modifique el código de la siguiente manera:

public static void takePhoto(Fragment fragment, int token, Uri uri) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); if (uri != null) { intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); } fragment.startActivityForResult(intent, token); }

Pero tampoco es trabajo.

Ocurrió en Android 5.1, mientras que funciona bien en Android 4.3. ¿Hay alguien que resuelva el mismo problema? Pide un poco de antelación. Esperando en línea ...




Entonces, en realidad estaba leyendo sobre esto, y parece que la solución correcta para manejar esto es la siguiente:

String mCurrentPhotoPath; private File createImageFile() throws IOException { // Create an image file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); File image = File.createTempFile( imageFileName, /* prefix */ ".jpg", /* suffix */ storageDir /* directory */ ); // Save a file: path for use with ACTION_VIEW intents mCurrentPhotoPath = "file:" + image.getAbsolutePath(); return image; } static final int REQUEST_TAKE_PHOTO = 1; private void dispatchTakePictureIntent() { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // Ensure that there''s a camera activity to handle the intent if (takePictureIntent.resolveActivity(getPackageManager()) != null) { // Create the File where the photo should go File photoFile = null; try { photoFile = createImageFile(); } catch (IOException ex) { // Error occurred while creating the File ... } // Continue only if the File was successfully created if (photoFile != null) { Uri photoURI = FileProvider.getUriForFile(this, "com.example.android.fileprovider", photoFile); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO); } } }

Observe que hay una nota que dice google para crear un archivo "contenido: //" en lugar de un recurso basado en "archivo: //".

Esto es de google:

Note: We are using getUriForFile(Context, String, File) which returns a content:// URI. For more recent apps targeting Android N and higher, passing a file:// URI across a package boundary causes a FileUriExposedException. Therefore, we now present a more generic way of storing images using a FileProvider.

Además, deberá configurar lo siguiente: Now, you need to configure the FileProvider. In your app''s manifest, add a provider to your application: Now, you need to configure the FileProvider. In your app''s manifest, add a provider to your application:

<application> ... <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.example.android.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"></meta-data> </provider> ... </application>

Nota: (Tomado del sitio de google) Make sure that the authorities string matches the second argument to getUriForFile(Context, String, File). In the meta-data section of the provider definition, you can see that the provider expects eligible paths to be configured in a dedicated resource file, res/xml/file_paths.xml. Here is the content required for this particular example: Make sure that the authorities string matches the second argument to getUriForFile(Context, String, File). In the meta-data section of the provider definition, you can see that the provider expects eligible paths to be configured in a dedicated resource file, res/xml/file_paths.xml. Here is the content required for this particular example:

<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="my_images" path="Android/data/com.example.package.name/files/Pictures" /> </paths>

Si desea más información: lea aquí https://developer.android.com/training/camera/photobasics.html


Ya he resuelto este problema.

Primero, este problema se produjo porque StrictMode evita pasar URI con un esquema file:// .

Así que hay dos soluciones:

  1. Cambiar StrictMode . Ver problema similar y su código . Pero para nuestras aplicaciones, no es realista modificar el código fuente de Android.

  2. Use otro esquema URI, en lugar de file:// . Por ejemplo, content:// relacionado con MediaStore .

Así que elegí el segundo método:

private void doTakePhoto() { try { ContentValues values = new ContentValues(1); values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpg"); mCameraTempUri = getActivity().getContentResolver() .insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); takePhoto(this, RequestCode.REQCODE_TAKE_PHOTO, mCameraTempUri); } catch (Exception e) { e.printStackTrace(); } } public static void takePhoto(Fragment fragment, int token, Uri uri) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); if (uri != null) { intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); } fragment.startActivityForResult(intent, token); }

Además, hay otra solution .