Cuando toma la foto get – java.lang.Throwable: file: // Uri expuesto a través de ClipData.Item.getUri ()
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í:
- Phonegap resolveLocalFileSystemURL no funciona para el contenido de uri en android
- Cómo obtener un uri de un recurso de imagen en android
- Problema con URI matcher en Android
- Cómo obtener la ruta completa del archivo desde URI
- Visualización de imágenes de una carpeta específica de la tarjeta SD mediante una vista de cuadrícula
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.
Sucede en Android 5.1 Aunque funciona bien en Android 4.3. ¿Hay alguien resolver el mismo problema? Pida un poco de avance. Esperando en línea …
- Convertir una ruta de acceso de archivo a Uri en Android
- Cómo recuperar ImageUri de un ImageView?
- ¿por qué java.net.UnknownHostException: Host no está resuelto: webservername.com:80?
- Android: Guardar el objeto android.net.Uri en la base de datos
- Agregar calendario y eventos en Android 2.2
- Obtener el camino real de URI, KitKat Android nuevo marco de acceso de almacenamiento
- Abrir archivo html local con el navegador de Android
- Convierta java.net.URI a android.net.Uri
Ya he resuelto este problema.
En primer lugar, este problema se produjo porque StrictMode
impide pasar URIs con un file://
scheme.
Así que hay dos soluciones:
-
Cambiar
StrictMode
. Ver el problema similar y su código . Pero para nuestras aplicaciones, no es realista modificar el código fuente de Android. -
Utilice otro esquema URI, en lugar de
file://
. Por ejemplo,content://
relacionado conMediaStore
.
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 solución .
Por lo tanto, estaba leyendo sobre esto, y parece que la solución correcta para manejar esto es lo 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 Google dice para crear un archivo "content: //" en lugar de un recurso "file: //".
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, necesitará 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
La razón de este error es que file: // uri esquema no más soportado porque la seguridad está expuesta. https://code.google.com/p/android/issues/detail?id=203555
Y no podemos usar file: // uri más después con targetSDK 'N'. https://commonsware.com/blog/2016/03/14/psa-file-scheme-ban-n-developer-preview.html
Por lo tanto, la respuesta es correcta. Cualquier persona que use file: // tiene que cambiar content: // para proporcionar tipos de archivos locales.
Para resumir: el esquema file: // ahora no se puede conectar con Intent en targetSdkVersion 24 (Android Nougat)
Tienes que cambiar tu código si planeas apoyar api 24 + dos enlaces: https://developer.android.com/training/camera/photobasics.html https://inthecheesefactory.com/blog/how-to-share- Acceso-a-archivo-con-fileprovider-on-android-nougat / es
- Uso de varios colores de texto en la vista de texto de Android
- ¿Cómo excluir tu propia aplicación del menú Compartir?