¿Hay una manera de acceder a las entradas del calendario sin utilizar gdata-java-cliente?

StackOverflow https://stackoverflow.com/questions/846942

  •  21-08-2019
  •  | 
  •  

Pregunta

¿Es posible conseguir las entradas del calendario desde el teléfono sin conexión? Se parece la única manera es usar gdata-java-cliente .

¿Fue útil?

Solución

Estas respuestas son buenas, pero todos ellos implican la codificación dura de la Calendar URI (que he visto en tres encarnaciones diferentes a través de diferentes dispositivos Android).

Una mejor manera de conseguir que URI (que dura códigos el nombre de una clase y un campo en su lugar) sería algo como esto:

Class<?> calendarProviderClass = Class.forName("android.provider.Calendar");
Field uriField = calendarProviderClass.getField("CONTENT_URI");
Uri calendarUri = (Uri) uriField.get(null);

Esto no es perfecta (se romperá si alguna vez se retire la android.provider.Calendar clase o la CONTENT_URI campo) pero funciona en más plataformas que cualquier solo disco de código URI.

Tenga en cuenta que estos métodos de reflexión tirarán exceptions que tendrá que ser capturados o re-lanzada por el método de llamada.

Otros consejos

Josef y soluciones de Isaac para acceder al calendario sólo funcionan en Android 2.1 y anteriores. Google ha cambiado el contenido URI base en 2.2 de "contenido: // calendario" a "contenido: //com.android.calendar". Este cambio significa que el mejor enfoque consiste en intentar obtener un cursor utilizando la antigua base URI, y si el cursor devuelto es nulo, entonces prueba el nuevo URI base.

Tenga en cuenta que tengo este enfoque de la que Shane Conder y Lauren Darcey proporcionan con su Trabajar con el Calendario Android artículo.

private final static String BASE_CALENDAR_URI_PRE_2_2 = "content://calendar";
private final static String BASE_CALENDAR_URI_2_2 = "content://com.android.calendar";
/*
 * Determines if we need to use a pre 2.2 calendar Uri, or a 2.2 calendar Uri, and returns the base Uri
 */
private String getCalendarUriBase() {
    Uri calendars = Uri.parse(BASE_CALENDAR_URI_PRE_2_2 + "/calendars");
    try {
        Cursor managedCursor = managedQuery(calendars, null, null, null, null);
        if (managedCursor != null) {
            return BASE_CALENDAR_URI_PRE_2_2;
        }
        else {
            calendars = Uri.parse(BASE_CALENDAR_URI_2_2 + "/calendars");
            managedCursor = managedQuery(calendars, null, null, null, null);

            if (managedCursor != null) {
                return BASE_CALENDAR_URI_2_2;
            }
        }
    } catch (Exception e) { /* eat any exceptions */ }

    return null; // No working calendar URI found
}

En la actualidad, esto no es posible sin necesidad de utilizar las API privadas (ver post de Josef.) Hay un proveedor de calendario, pero aún no es pública. Podría cambiar en cualquier momento y romper su aplicación.
Sin embargo, es probable que no va a cambiar (no creo que la cambiarán de "calendario"), por lo que podría ser capaz de utilizarlo. Pero mi recomendación es usar una clase separada de esta manera:

public class CalendarProvider {
     public static final Uri CONTENT_URI = Uri.parse("content://calendar");
     public static final String TITLE = "title";
     public static final String ....

Y el uso de éstos en lugar de las cuerdas directamente. Esto le permitirá cambiar muy fácilmente si / cuando los cambios en la API o que se haga pública.

Puede utilizar el proveedor de contenido de calendario (com.android.providers.calendar.CalendarProvider). Ejemplo:


ContentResolver contentResolver = context.getContentResolver();
Cursor cursor = contentResolver.query(Uri.parse("content://calendar/events"), null, null, null, null);

while(cursor.moveToNext()) {
    String eventTitle = cursor.getString(cursor.getColumnIndex("title"));
    Date eventStart = new Date(cursor.getLong(cursor.getColumnIndex("dtstart")));
    // etc.
}

editar : es posible que desee poner esto en una envoltura (ver después de Isaac ), ya que es actualmente una API privada.

Puede utilizar el CalendarContract desde aquí: https://github.com/dschuermann/android- calendario-compatibilidad

Es la misma clase API como disponible en Android 4, pero hecho para trabajar con Android> = 2,2.

Acerca de la API que puede cambiar ... El enfoque ContentProvider conjunto no va a cambiar rápidamente de modo que ya se puede superar muchos de los problemas sólo por la actualización de las cuerdas. Para ello crear constantes vuelve a utilizar durante todo el proyecto.

public static final String URI_CONTENT_CALENDAR_EVENTS = "content://calendar/events";

ContentResolver contentResolver = context.getContentResolver();
Cursor cursor = contentResolver.query(Uri.parse(URI_CONTENT_CALENDAR_EVENTS), null, null, null, null);
    //etc

Si desea una API privada adecuada tendrá que crear un POJO y algunos servicios como esto:

public class CalendarEvent {
    private long id;
    private long date;
    //etc...
}

public interface CalendarService {

    public Set<CalendarEvent> getAllCalendarEvents();

    public CalendarEvent findCalendarEventById(long id);

    public CalendarEvent findCalendarEventByDate(long date);

}

y así sucesivamente. De esta manera sólo tendrá que actualizar el objeto CalendarEvent y este servicio en caso de que los cambios en la API.

solución de Nick implica managedQuery, que no está definido en la clase contexto. Muchas veces cuando se está ejecutando cosas en el fondo que se desea utilizar un objeto de contexto. Aquí está una versión modificada:

Cadena getCalendarUriBase pública () {

retorno (android.os.Build.VERSION.SDK_INT> = 8)? "Contenido: //com.android.calendar": "Contenido: // calendario"; }

La captura de nulo no debe llevarse a cabo aquí, ya que puede haber más excepciones, incluso si el managedQuery sucedieron antes.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top