如何在Android上获取包含日历的帐户列表?

时间:2017-02-15 20:18:26

标签: android api calendar accountmanager

我正在为Android编写一个应用程序,它会在日历中为用户创建一系列事件,而正常的重复无法处理它。我想允许用户选择他们想要用于日历的帐户(主要用于以后共享日历)。

使用AccountManager,我可以获得所有帐户,但并非所有帐户都有日历。 Google帐户在技术上可行,但我想使用Exchange帐户或其他也有日历的帐户。

我读过的所有AccountManager API文档都说要搜索的功能是特定于身份验证器(并且可以更改)。保持一份清单几乎是不可能的。限制到已知帐户类型列表比我真正想要的更有限。

我错过了其他选择吗?

2 个答案:

答案 0 :(得分:1)

与我最初的看法相反,您实际上根本不需要触摸帐户列表。这有助于简化流程,减少所需权限的数量。

使用the information from this page(在查询日历下),您可以在日历表中写入查询,并获取日历及其所属帐户的完整列表。

最后,这种方法对我来说会更有用。基本上, EVENT_PROJECTION 的更改如下所示。

public static final String[] EVENT_PROJECTION = new String[] {
    Calendars._ID,
    Calendars.ACCOUNT_NAME,
    Calendars.CALENDAR_DISPLAY_NAME,
    Calendars.ACCOUNT_TYPE,
    Calendars.CALENDAR_ACCESS_LEVEL,
    Calendars.IS_PRIMARY
};
添加了

ACCOUNT_TYPE CALENDAR_ACCESS_LEVEL IS_PRIMARY ,以便我们知道a)哪个日历主要用于稍后进行排序的帐户,以及b )用户是否可以实际写入它,因为如果它是只读的我们不想要它。

此外,在日历表的实际查询中,我进行了以下更改。

// Run query
Cursor cur = null;
ContentResolver cr = getContentResolver();
Uri uri = Calendars.CONTENT_URI;
// Submit the query and get a Cursor object back.
cur = cr.query(uri, EVENT_PROJECTION, "", null, null);

由于我们希望所有日历都开始,示例中的选择 selectionArgs 变量都是无用的。

直到我们得到查询的最终结果,基本上示例中的其他所有内容都保持不变。

获得数据后,可以将其解析并放入 List HashMap 等,并根据需要进行排序和过滤。

答案 1 :(得分:0)

模型

import java.util.ArrayList;
import java.util.List;

public class CalendarAccount {

    private String name;
    private List<Calendar> calendars;

    public CalendarAccount(String name) {
        this(name, new ArrayList<Calendar>());
    }

    public CalendarAccount(String name, List<Calendar> calendars) {
        this.name = name;
        this.calendars = calendars;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Calendar> getCalendars() {
        return calendars;
    }

    public void setCalendars(List<Calendar> calendars) {
        this.calendars = calendars;
    }
}
import android.support.annotation.ColorInt;

public class Calendar {

    private long id;
    private String displayName;
    @ColorInt private int color;
    private boolean userActivated;

    public Calendar(long id, String displayName, @ColorInt int color) {
        this(id, displayName, color, false);
    }

    public Calendar(long id, String displayName, int color, boolean userActivated) {
        this.id = id;
        this.displayName = displayName;
        this.color = color;
        this.userActivated = userActivated;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getDisplayName() {
        return displayName;
    }

    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }

    public int getColor() {
        return color;
    }

    public void setColor(int color) {
        this.color = color;
    }

    public boolean isUserActivated() {
        return userActivated;
    }

    public void setUserActivated(boolean userActivated) {
        this.userActivated = userActivated;
    }
}

使用日历提供程序的实际代码

public static final String[] EVENT_PROJECTION = new String[] {
        Calendars._ID,                           // 0
        Calendars.ACCOUNT_NAME,                  // 1
        Calendars.CALENDAR_DISPLAY_NAME,         // 2
        Calendars.OWNER_ACCOUNT,                 // 3
        Calendars.CALENDAR_COLOR                 // 4
};

// The indices for the projection array above.
private static final int PROJECTION_ID_INDEX = 0;
private static final int PROJECTION_ACCOUNT_NAME_INDEX = 1;
private static final int PROJECTION_DISPLAY_NAME_INDEX = 2;
private static final int PROJECTION_OWNER_ACCOUNT_INDEX = 3;
private static final int PROJECTION_COLOR_INDEX = 4;


private List<CalendarAccount> getAccountCalendars() {
    // Run query
    Cursor cur;
    ContentResolver cr = context.getContentResolver();
    Uri uri = Calendars.CONTENT_URI;
    String selection = "(" + Calendars.VISIBLE + " = ?)";
    String[] selectionArgs = new String[] {"1"};
    // Submit the query and get a Cursor object back.
    cur = cr.query(uri, EVENT_PROJECTION, selection, selectionArgs, null);
    List<CalendarAccount> calendarAccounts = new ArrayList<>();
    // Use the cursor to step through the returned records
    while (cur.moveToNext()) {
        long calID = 0;
        String displayName = null;
        String accountName = null;
        String ownerName = null;
        @ColorInt int color = 0;

        // Get the field values
        calID = cur.getLong(PROJECTION_ID_INDEX);
        displayName = cur.getString(PROJECTION_DISPLAY_NAME_INDEX);
        accountName = cur.getString(PROJECTION_ACCOUNT_NAME_INDEX);
        ownerName = cur.getString(PROJECTION_OWNER_ACCOUNT_INDEX);
        color = cur.getInt(PROJECTION_COLOR_INDEX);

        Calendar calendar = new Calendar(calID, displayName, color);
        CalendarAccount calendarAccount = new CalendarAccount(accountName);
        int index = calendarAccounts.indexOf(calendarAccount);
        if (index != -1) {
            calendarAccount = calendarAccounts.get(index);
        } else {
            calendarAccounts.add(calendarAccount);
        }
        calendarAccount.getCalendars().add(calendar);
    }
    return calendarAccounts;
}