3

我正在开发一个 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;
    }
}

我认为问题可能是我需要以某种方式将这些数据同步到服务器。网上有一些关于如何添加事件和列出日历的教程,但很少有关于插入一个...

因此,如果有人可以帮助我解决这个问题,我会很高兴。谢谢。问候。马头鱼。

4

2 回答 2

2

您创建的应用程序应该有一个同步适配器,然后上面的代码才能工作。我想这会帮助你理解: 如何正确设置同步适配器?

于 2012-12-07T08:03:33.217 回答
0

仅当您作为同步适配器运行时才能插入新日历。看

在 API 指南中插入日历。

于 2012-11-05T22:29:11.973 回答