¿Qué causa que ContentResolver.query () de Android devuelva nulo?

¿Bajo qué condiciones ContentResolver.query () devuelve null en lugar de un objeto de cursor? He obtenido cursores vacíos anteriormente, pero me di cuenta de que el método también puede devolver nulo. Sin embargo, no he podido rastrear las circunstancias en que esto sucede.

Acabo de tropezar con el mismo problema debido a un informe de locking del usuario que recibí hoy para una aplicación mía. Si la documentación de Android no está clara sobre algo, ayuda a mirar el código fuente. Esto es lo que encontré sobre las causas para que ContentResolver.query() devuelva null :

  1. El proveedor de contenido no puede ser adquirido. Esto puede deberse a un problema con el Uri especificado o simplemente porque no existe en el sistema. Si el Uri es el problema, las causas son: el protocolo no es content:// o el Uri no tiene una porción de cadena de autoridad (Uri.getAuthority () == null).

  2. El método de consulta del proveedor adquirido devuelve null .

  3. El proveedor de contenido podría ser adquirido, pero se lanzó una excepción remota durante una consulta.

Especialmente debido a (2.) es bastante arbitrario lo que podría ser la causa de null como resultado, ya que no hay reglas definidas. Pero, por lo general, si SQLite es el back-end de un ContentProvider , puede esperar al menos algún objeto Cursor vacío como resultado en lugar de simplemente null .

Sin embargo, el sistema de Android ContentProvider hace algunas comprobaciones antes de devolver algo. Si la entrada no es la esperada, existe la posibilidad poco probable de que se devuelva null . Pero para ser honesto, eso nunca me había sucedido antes. Normalmente recibo una IllegalArgumentException en caso de problemas con los parámetros de consulta. Tal vez algunas implementaciones de ContentProvider devuelvan null en caso de conjuntos de resultados vacíos.

De cualquier manera. Parece que es necesario comprobar siempre nulo . Especialmente el número de motivo (3.) es probablemente algo que puede suceder en cualquier dispositivo Android.

ContentResolver.query devuelve null si el esquema uri no tiene el content:// del formulario content:// o si el contentProvider para el esquema en sí no existe.

ContentResolver.query () devolverá nulo en los siguientes casos:

  1. Si intentas pasar nombres de columna que no existen en la base de datos (un caso muy común es cuando los desarrolladores usan constantes como nombres de columna, porque se parecen a las columnas).

  2. Es probable que sea nulo porque su argumento URI no es válido.

Puede haber otros casos en los que devolverá nulo. Sin embargo, los dos casos anteriores son razones muy comunes por las que los desarrolladores jalan sus pelos 🙂

Yo tuve el mismo problema. Mi error fue no cerrar un Cursor para el Proveedor, por lo que una llamada de consulta posterior lleva a nulo.

Si olvida declarar el proveedor en manifiesto sus consultas pueden devolver nulo.

Estoy tratando de recuperar la ruta completa de la imagen desde la galería. Cambio el fragmento de

 Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("image/*"); startActivityForResult(intent, SELECT_PHOTO); 

a

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); intent.setType("image/*"); startActivityForResult(intent, SELECT_PHOTO); } else { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("image/*"); startActivityForResult(intent, SELECT_PHOTO); } 

El cambio principal es la statement de intenciones para KitKat y posterior. Luego query () devuelve el cursor.

Si no hay resultado, devuelve nulo. Quiero decir que si la consulta de la base de datos dada no arroja nada (ni siquiera una sola fila de datos), entonces query () devuelve null.