studio programacion para móviles libros gratis español edición desarrollo desarrollar curso aprende aplicaciones android android-7.0-nougat android-7.1-nougat

android - programacion - IllegalArgumentException: la columna ''_data'' no existe



manual programacion android español pdf (4)

Esta función funciona correctamente en dispositivos antes de Android N

Funciona para muy pocos valores de Uri , puede que no tenga un resultado (por ejemplo, para cosas indexadas por MediaStore que no son archivos locales) y puede que no tenga un resultado utilizable (por ejemplo, para archivos en almacenamiento extraíble).

Así que por favor ayuda.

Use un ContentResolver y openInputStream() para obtener un InputStream en el contenido identificado por el Uri . Idealmente, solo usa esa secuencia directamente, para lo que sea que estés tratando de hacer. O, use ese InputStream y algo de FileOutputStream en un archivo que usted controla para hacer una copia del contenido, luego use ese archivo.

En Nougat, esta función no funciona.

String path = getRealPathFromURI(this, getIntent().getParcelableExtra(Intent.EXTRA_STREAM));


public String getRealPathFromURI(Context context, Uri contentUri) { Cursor cursor = null; try { String[] proj = {MediaStore.Images.Media.DATA}; cursor = context.getContentResolver().query(contentUri, proj, null, null, null); if (cursor == null) return contentUri.getPath(); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } finally { if (cursor != null) { cursor.close(); } } }

Registro de bloqueo:

java.lang.RuntimeException: Unable to start activity ComponentInfo{class path}: java.lang.IllegalArgumentException: column ''_data'' does not exist at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2659) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2724) at android.app.ActivityThread.-wrap12(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1473) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6123) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757) Caused by java.lang.IllegalArgumentException: column ''_data'' does not exist at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:333) at android.database.CursorWrapper.getColumnIndexOrThrow(CursorWrapper.java:87) at com.package.SaveImageActivity.getRealPathFromURI() at com.package.SaveImageActivity.onCreate() at android.app.Activity.performCreate(Activity.java:6672) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1140) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2612) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2724) at android.app.ActivityThread.-wrap12(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1473) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6123) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)

Esta función está funcionando correctamente en dispositivos antes de Android N. Leí el archivo del artículo : // el esquema ahora no se puede adjuntar con Intent en targetSdkVersion 24 (Android Nougat) . Pero no pude encontrar ninguna solución. Así que por favor ayuda.


// El siguiente código está funcionando en Android N:

private static String getFilePathForN(Uri uri, Context context) { Uri returnUri = uri; Cursor returnCursor = context.getContentResolver().query(returnUri, null, null, null, null); /* * Get the column indexes of the data in the Cursor, * * move to the first row in the Cursor, get the data, * * and display it. * */ int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE); returnCursor.moveToFirst(); String name = (returnCursor.getString(nameIndex)); String size = (Long.toString(returnCursor.getLong(sizeIndex))); File file = new File(context.getFilesDir(), name); try { InputStream inputStream = context.getContentResolver().openInputStream(uri); FileOutputStream outputStream = new FileOutputStream(file); int read = 0; int maxBufferSize = 1 * 1024 * 1024; int bytesAvailable = inputStream.available(); //int bufferSize = 1024; int bufferSize = Math.min(bytesAvailable, maxBufferSize); final byte[] buffers = new byte[bufferSize]; while ((read = inputStream.read(buffers)) != -1) { outputStream.write(buffers, 0, read); } Log.e("File Size", "Size " + file.length()); inputStream.close(); outputStream.close(); Log.e("File Path", "Path " + file.getPath()); Log.e("File Size", "Size " + file.length()); } catch (Exception e) { Log.e("Exception", e.getMessage()); } return file.getPath(); }


@Redturbo no puedo escribir un comentario, escribo aquí

IOUtils.copyStream(inputStream, outputStream);

TEMP_DIR_PATH - cualquier ruta de tu directorio, algo como esto

File rootDataDir = context.getFilesDir(); File copyFile = new File( rootDataDir + File.separator + fileName + ".jpg");


Según la respuesta dada por CommonsWare, el código de la solución es:

public static String getFilePathFromURI(Context context, Uri contentUri) { //copy file and send new file path String fileName = getFileName(contentUri); if (!TextUtils.isEmpty(fileName)) { File copyFile = new File(TEMP_DIR_PATH + File.separator + fileName); copy(context, contentUri, copyFile); return copyFile.getAbsolutePath(); } return null; } public static String getFileName(Uri uri) { if (uri == null) return null; String fileName = null; String path = uri.getPath(); int cut = path.lastIndexOf(''/''); if (cut != -1) { fileName = path.substring(cut + 1); } return fileName; } public static void copy(Context context, Uri srcUri, File dstFile) { try { InputStream inputStream = context.getContentResolver().openInputStream(srcUri); if (inputStream == null) return; OutputStream outputStream = new FileOutputStream(dstFile); IOUtils.copyStream(inputStream, outputStream); inputStream.close(); outputStream.close(); } catch (IOException e) { e.printStackTrace(); } }

Espero que esto te ayude.

El origen de IOUtils.copy es de este sitio: https://www.developerfeed.com/copy-bytes-inputstream-outputstream-android/ (Es posible que deba cambiar un poco la excepción, pero funciona según sea necesario)