Android上的日历应用程序可以合并多个独立的日历:本地电话日历、Google日历等。
我该如何在Android手机上添加一个新的日历? 我想动态生成该日历中的事件,而不需要访问任何在线资源,比如Google。
编辑:我希望支持安卓1.5和2.3.4的手机。将来可能会有更新到4.0的较新手机,但我们谁也不知道那会是什么时候...
Android上的日历应用程序可以合并多个独立的日历:本地电话日历、Google日历等。
我该如何在Android手机上添加一个新的日历? 我想动态生成该日历中的事件,而不需要访问任何在线资源,比如Google。
编辑:我希望支持安卓1.5和2.3.4的手机。将来可能会有更新到4.0的较新手机,但我们谁也不知道那会是什么时候...
我刚刚成功使用ICS的新API添加了一个日历。Stefan的答案有所帮助,但想要能够写入所有列,必须将操作作为同步适配器进行。您可以使用CalendarContract.ACCOUNT_TYPE_LOCAL从普通应用程序中执行此操作。以下代码应该在ICS上工作。可能某些列值不正确。请查看CalendarContract.Calendars的文档。不幸的是,我无法为旧版本的Android提供帮助,但CalendarContract仅用于一些常量字符串值。也许这些也适用于旧版本。
Uri calUri = CalendarContract.Calendars.CONTENT_URI;
ContentValues cv = new ContentValues();
cv.put(CalendarContract.Calendars.ACCOUNT_NAME, yourAccountName);
cv.put(CalendarContract.Calendars.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL);
cv.put(CalendarContract.Calendars.NAME, yourInternalName);
cv.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, yourDisplayName);
cv.put(CalendarContract.Calendars.CALENDAR_COLOR, yourColor);
cv.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_OWNER);
cv.put(CalendarContract.Calendars.OWNER_ACCOUNT, true);
cv.put(CalendarContract.Calendars.VISIBLE, 1);
cv.put(CalendarContract.Calendars.SYNC_EVENTS, 1);
calUri = calUri.buildUpon()
.appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, ACCOUNT_NAME)
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL)
.build();
Uri result = this.getContentResolver().insert(calUri, cv);
我已经编写了下面的活动(以及一些资源等),以便在API级别为15的模拟器上插入一个日历(不同步),因为那里的日历应用程序没有添加日历的功能,与我的手机上的应用程序不同(API 8),或者我没有找到它...)。布局有两个文本字段,用于日历的名称和显示名称,一个添加按钮和一个状态文本视图,在插入后提供反馈。请确保在清单中设置了权限:
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
<uses-permission android:name="android.permission.READ_CALENDAR"/>
public class CalUtilActivity extends Activity {
private EditText name;
private EditText display;
private TextView status;
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.main);
this.name = (EditText) this.findViewById(R.id.name);
this.display = (EditText) this.findViewById(R.id.displayname);
this.status = (TextView) this.findViewById(R.id.status);
final Button b = (Button) this.findViewById(R.id.add);
b.setOnClickListener(new OnClickListener() {
@Override
public void onClick(final View v) {
CalUtilActivity.this.addCalendar();
}
});
}
private void addCalendar() {
final String cname = this.name.getText().toString();
final String dname = this.display.getText().toString();
if( cname.length() == 0 || dname.length() == 0 ) {
this.status.setText(this.getResources().getString(R.string.errorNames));
return;
}
this.status.setText("");
final Uri calUri = CalendarContract.Calendars.CONTENT_URI;
final ContentValues v = new ContentValues();
v.put(CalendarContract.Calendars.NAME, cname);
v.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, dname);
v.put(CalendarContract.Calendars.VISIBLE, 1);
final Uri result = this.getContentResolver().insert(calUri, v);
this.status.setText(result.toString());
}
对于API 13及以前的版本,您无法使用内容提供程序,必须直接访问数据库。要添加日历,您必须向Calendars表中添加一行,该表根据以下创建语句进行定义:
CREATE TABLE Calendars (_id INTEGER PRIMARY KEY,_sync_account TEXT,_sync_account_type TEXT,_sync_id TEXT,_sync_version TEXT,_sync_time TEXT,_sync_local_id INTEGER,_sync_dirty INTEGER,_sync_mark INTEGER,url TEXT,name TEXT,displayName TEXT,hidden INTEGER NOT NULL DEFAULT 0,color INTEGER,access_level INTEGER,selected INTEGER NOT NULL DEFAULT 1,sync_events INTEGER NOT NULL DEFAULT 0,location TEXT,timezone TEXT,ownerAccount TEXT, organizerCanRespond INTEGER NOT NULL DEFAULT 1);
如果您不需要同步日历,则设置_id、名称和displayName应该是可行的。但是,您无法在模拟器上进行测试,因为日历应用程序及其数据库缺失。理论上,设备供应商可能已经修改了数据库架构,但由于有很多日历应用程序可用,我个人认为他们没有修改数据库架构。
content://calendar
content://com.android.calendar