我正在开发一个 Android 应用程序,我需要为用户制作一个新日历。我使用 Eclipse、Windows 7 和带有 Android ICS 4.0.3 的 Archos G9 平板电脑。我现在以 API 14 为目标。
我对 Java、Android 环境和 Stack Overflow 都是新手,请多多包涵。
我使用 ContentResolver,当我使用 LOCAL 帐户类型时它工作正常(尽管我似乎无法找到正确的参数来获取没有与会者选项的事件)。
当我尝试切换到“com.google”帐户类型时,使用我在平板电脑上注册的 gmail 帐户,虽然它仍然可以正常工作而不会引发任何异常,但新的日历应用程序和事件不会显示在 Google 日历上本机应用程序(它曾经以 LOCAL 帐户类型立即显示)。虽然我可以在应用程序运行时列出它,但如果我重新启动并列出它不再存在(它曾经保留在 Google 日历上,并且可以在使用 LOCAL 帐户类型重新启动时列出)。
这是我的代码,已注释,以便我更清楚主类:
package com.example.testnativecalendar;
import android.os.Bundle;
import android.provider.CalendarContract;
import android.app.Activity;
import android.content.ContentResolver;
import android.util.Log;
import android.view.Menu;
public class MainActivity extends Activity
{
static private final String CALENDAR_NAME = "MyLocalTestCalendar";
static private final String CALENDAR_DISPLAY_NAME = "My local test calendar";
static private final String[] CALENDARS_PROJECTION = { CalendarContract.Calendars._ID,
CalendarContract.Calendars.ACCOUNT_NAME,
CalendarContract.Calendars.ACCOUNT_TYPE,
CalendarContract.Calendars.NAME,
};
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView( R.layout.activity_main );
ContentResolver contentResolver = getContentResolver();
// I first list to check what is there before I do anything.
// If I tried to add a local account, it is still here.
// If I tried a com.google account, it is not in the list anymore.
CalendarUtilities.listCalendars( contentResolver, CALENDARS_PROJECTION, " | " );
// I clean the old calendars I tried to insert, if they are here.
long[] calendarIDs = CalendarUtilities.getCalendarsIDs( contentResolver, CALENDAR_NAME );
if ( calendarIDs.length != 0 )
for ( long id : calendarIDs )
CalendarUtilities.removeCalendar( contentResolver, id );
// I had a calendar
calendarIDs = new long[] { CalendarUtilities.addCalendar( contentResolver, CALENDAR_NAME, CALENDAR_DISPLAY_NAME ) };
// When I list, I see it.
// If it is a local account, it is also in Google calendar native app whith the events if I add any.
// If it is my com.google acount, I see it listed here, but it is not on Google calendar native app.
CalendarUtilities.listCalendars( contentResolver, CALENDARS_PROJECTION, " | " );
}
@Override
public boolean onCreateOptionsMenu( Menu menu )
{
getMenuInflater().inflate( R.menu.activity_main, menu );
return true;
}
}
和实用程序类:
package com.example.testnativecalendar;
import java.util.Calendar;
import java.util.TimeZone;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;
import android.provider.CalendarContract;
import android.util.Log;
public class CalendarUtilities
{
static public void listCalendars( ContentResolver contentResolver, String[] projection, String separator )
{
Cursor cursor = contentResolver.query( CalendarContract.Calendars.CONTENT_URI, projection, null, null, null );
try
{
while ( cursor.moveToNext( ) )
{
String[] datas = new String[ cursor.getColumnCount() ];
for ( int i = 0; i < cursor.getColumnCount(); i++ )
datas[i] = cursor.getColumnName( i ) + ": " + cursor.getString( i );
Log.d( "trace", StringUtilities.join( datas, separator ) );
}
}
catch (Exception exception)
{
Log.e( "trace", exception.toString() );
}
cursor.close();
}
static public long addCalendar( ContentResolver contentResolver, String name, String displayName )
{
TimeZone timeZone = TimeZone.getDefault();
ContentValues contentValues = new ContentValues();
//So here when I use CalendarContract.ACCOUNT_TYPE_LOCAL, no problem, but local isn't what I whant.
//When I use my gmail address, it doesn't throw anything, but it doesn't leave
contentValues.put( CalendarContract.Calendars.ACCOUNT_NAME, "mygmailaddress@gmail.com" );
contentValues.put( CalendarContract.Calendars.ACCOUNT_TYPE, "com.google" ); //CalendarContract.ACCOUNT_TYPE_LOCAL );
contentValues.put( CalendarContract.Calendars.OWNER_ACCOUNT, "mygmailaddress@gmail.com" );
contentValues.put( CalendarContract.Calendars.NAME, name );
contentValues.put( CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, displayName );
contentValues.put( CalendarContract.Calendars.CALENDAR_COLOR, 0xFF000000 + Math.floor( Math.random() * 0xFF0000 ) );
contentValues.put( CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_OWNER );
contentValues.put( CalendarContract.Calendars.VISIBLE, 1);
contentValues.put( CalendarContract.Calendars.SYNC_EVENTS, 1);
contentValues.put( CalendarContract.Calendars.CALENDAR_TIME_ZONE, timeZone.getID() );
Uri calendarUri = CalendarContract.Calendars.CONTENT_URI;
calendarUri = calendarUri.buildUpon()
.appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true" )
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, "mygmailaddress@gmail.com" )
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, "com.google" ) //CalendarContract.ACCOUNT_TYPE_LOCAL )
.build();
try
{
Uri result = contentResolver.insert(calendarUri, contentValues);
return Long.parseLong( result.getLastPathSegment() );
}
catch( Exception exception )
{
Log.e( "trace", exception.toString() );
}
return -1;
}
static public int removeLocalCalendar( ContentResolver contentResolver, long id )
{
int result = contentResolver.delete( CalendarContract.Calendars.CONTENT_URI, BaseColumns._ID + "=?", new String[] { Long.toString( id ) } );
Log.d( "trace", "Calendar deleted: " + result );
return result;
}
}
我认为问题可能是我需要以某种方式将这些数据同步到服务器。网上有一些关于如何添加事件和列出日历的教程,但很少有关于插入一个...
因此,如果有人可以帮助我解决这个问题,我会很高兴。谢谢。问候。马头鱼。