Est-il possible d'accéder aux entrées du calendrier sans utiliser gdata-java-client?

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

  •  21-08-2019
  •  | 
  •  

Question

Est-il possible d'obtenir des entrées de l'agenda du téléphone hors ligne? Il semble le seul moyen est d'utiliser gdata-java-client .

Était-ce utile?

La solution

Ces réponses sont bonnes, mais elles impliquent toutes coder en dur l'Calendar URI (que je l'ai vu dans trois incarnations différentes dans les différents appareils Android).

Une meilleure façon d'obtenir ce URI (qui code en dur le nom d'une classe et d'un champ à la place) serait quelque chose comme ceci:

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

Ce n'est pas parfait (il se brisera s'ils enlèvent jamais la classe ou le android.provider.Calendar champ CONTENT_URI) mais il fonctionne sur plusieurs plates-formes que tout dur code unique URI.

Notez que ces méthodes de réflexion jetteront qui devra exceptions être pris ou relancées par la méthode d'appel.

Autres conseils

Josef et les solutions d'Isaac pour accéder au calendrier ne fonctionnent que dans Android 2.1 et versions antérieures. Google a modifié le contenu de base URI 2.2 de « contenu: // calendrier » à « contenu: //com.android.calendar ». Ce changement signifie que la meilleure approche consiste à tenter d'obtenir un curseur en utilisant l'ancien URI de base, et si le curseur retourné est nul, alors essayez la nouvelle URI de base.

S'il vous plaît noter que je suis arrivé cette approche du code de test open source que Shane Conder et Lauren Darcey fournir leur de travail avec le calendrier Android article.

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
}

À l'heure actuelle, ce n'est pas possible sans utiliser des API privées (voir le poste de Josef.) Il est un fournisseur de calendrier, mais il est pas encore public. Cela pourrait changer à tout moment et briser votre application.
Cependant, il ne sera probablement pas changer (je ne pense pas qu'ils vont changer de « calendrier »), de sorte que vous pourriez être en mesure de l'utiliser. Mais ma recommandation est d'utiliser une classe séparée comme ceci:

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

Et utiliser à la place des chaînes directement. Cela vous permettra de changer très facilement si / quand les modifications de l'API ou il est rendu public.

Vous pouvez utiliser le fournisseur de contenu du calendrier (com.android.providers.calendar.CalendarProvider). Exemple:


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.
}

modifier : vous pouvez mettre cela dans une enveloppe (voir après Isaac de ) comme il est actuellement une API privée.

Vous pouvez utiliser le CalendarContract d'ici: https://github.com/dschuermann/android- calendrier compatibilité

Il est de la même classe API comme disponible sur Android 4, mais fait fonctionner avec Android> = 2.2.

A propos de l'API qui peut changer ... L'approche globale de ContentProvider ne changera pas qui peut rapidement si déjà surmonté beaucoup de problèmes en mettant à jour uniquement les chaînes. Créer des constantes à cet effet vous réutilisez sur l'ensemble du projet.

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 vous voulez une API privée appropriée, vous devrez créer un POJO et certains services comme ceci:

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);

}

et ainsi de suite. De cette façon, vous aurez seulement à mettre à jour l'objet CalendarEvent et ce service dans le cas où les modifications de l'API.

La solution de Nick implique ManagedQuery, qui n'est pas définie dans la classe de contexte. Plusieurs fois, lorsque vous utilisez les choses en arrière-plan que vous voulez utiliser un objet de contexte. Voici une version modifiée:

public String getCalendarUriBase () {

retour (android.os.Build.VERSION.SDK_INT> = 8)? "Contenu: //com.android.calendar": "Contenu: // calendrier"; }

Les prises pour nul ne doit pas être effectuée ici car il pourrait y avoir plus d'exceptions même si le ManagedQuery réussit plus tôt.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top