Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Content resolver - add new non local Calendar - calendar deleted when process ends

I am working on an Android app and I need to make a new Calendar for the user. I use Eclipse, Windows 7 and an Archos G9 tablet with Android ICS 4.0.3. I target the API 14 for now.

I am new to both Java, the Android environment, and Stack overflow, please be indulgent.

I use ContentResolver, and it works fine when I work with a LOCAL account type (although I can't seem to find the right parameter to get an event without attendee options).

When I tried to switch to a "com.google" account type, using the gmail account I resgistered with the tablet, and although it still works without any exceptions being thrown, the new calendar app and the events wouldn't show on Google Calendar native app ( it used to show instantly with the LOCAL account type ). And although I can get it listed while the app is running, if I relaunch and list it isn't there anymore ( it used to remain on Google calendar and could be listed when relaunching with the LOCAL account type ).

Here is my code, commented, so that I am clearer The main class:

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;
    }
}

And the utility class:

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, "[email protected]" );
        contentValues.put( CalendarContract.Calendars.ACCOUNT_TYPE, "com.google" ); //CalendarContract.ACCOUNT_TYPE_LOCAL );
        contentValues.put( CalendarContract.Calendars.OWNER_ACCOUNT, "[email protected]" );

        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, "[email protected]" )
            .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;
    }
}

I think the issue might be that I need to somehow sync those datas to the server. There are a few tutos online on how to add an event, and list calendars, but few about inserting one...

So I would be glad if anybody could help me with this. Thanks. Regards. Horsetopus.

like image 630
Horsetopus Avatar asked Nov 21 '25 07:11

Horsetopus


1 Answers

The app you create should have a sync adapter only then the above code works. I guess this would help you understand : How to properly setup the syncAdapter?

like image 112
Adi GuN Avatar answered Nov 22 '25 20:11

Adi GuN



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!