您如何获得 Android 上具有日历的帐户列表?
How do you get a list of accounts on Android that have calendars?
我正在为 Android 编写一个应用程序,它会在日历中为用户创建一系列事件,而正常的重复事件无法处理这些事件。我想让用户选择他们想要用于日历的帐户(主要是为了以后共享日历)。
使用 AccountManager,我可以获得所有帐户,但并非所有帐户都有日历。 Google 帐户在技术上是可行的,但我想使用 Exchange 帐户或其他也有日历的帐户。
我读过的所有 AccountManager API 文档都说要搜索的功能是特定于身份验证器的(并且可以更改)。保留一份清单几乎是不可能的。仅限于已知帐户类型的列表比我真正想要的要多。
还有我错过的其他选择吗?
与我最初的看法相反,您实际上根本不需要触摸帐户列表。这有助于简化流程并减少所需权限的数量。
使用 the information from this page(在查询日历下),您可以编写对日历的查询 table 并获取日历及其所属帐户的完整列表。
最后,这种方法对我来说会更有用。基本上,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) 用户是否可以实际写入它,因为如果它是只读的,我们不想要它。
此外,在日历的实际查询中table,我做了以下更改。
// 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);
由于我们希望所有日历都开始,因此示例中的 selection 和 selectionArgs 变量没有用。
直到我们得到查询的最终结果,基本上示例中的其他所有内容都保持不变。
一旦我们有了数据,就可以将其解析并放入 List、HashMap 等中,并根据需要进行排序和过滤.
型号
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;
}
}
使用 Calendar Provider 的实际代码
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;
}
我正在为 Android 编写一个应用程序,它会在日历中为用户创建一系列事件,而正常的重复事件无法处理这些事件。我想让用户选择他们想要用于日历的帐户(主要是为了以后共享日历)。
使用 AccountManager,我可以获得所有帐户,但并非所有帐户都有日历。 Google 帐户在技术上是可行的,但我想使用 Exchange 帐户或其他也有日历的帐户。
我读过的所有 AccountManager API 文档都说要搜索的功能是特定于身份验证器的(并且可以更改)。保留一份清单几乎是不可能的。仅限于已知帐户类型的列表比我真正想要的要多。
还有我错过的其他选择吗?
与我最初的看法相反,您实际上根本不需要触摸帐户列表。这有助于简化流程并减少所需权限的数量。
使用 the information from this page(在查询日历下),您可以编写对日历的查询 table 并获取日历及其所属帐户的完整列表。
最后,这种方法对我来说会更有用。基本上,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) 用户是否可以实际写入它,因为如果它是只读的,我们不想要它。
此外,在日历的实际查询中table,我做了以下更改。
// 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);
由于我们希望所有日历都开始,因此示例中的 selection 和 selectionArgs 变量没有用。
直到我们得到查询的最终结果,基本上示例中的其他所有内容都保持不变。
一旦我们有了数据,就可以将其解析并放入 List、HashMap 等中,并根据需要进行排序和过滤.
型号
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;
}
}
使用 Calendar Provider 的实际代码
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;
}