开发者

Context and Calendar

I am using a method to add an event to an internal calendar on the phone. Context has always confused me and this time is no different. The method contract wants the application context. The method call is:

addToCalendar(Context context, String title, long dtstart, long dtend);

This is my code to call the method when a button is pressed:

public class DateAdder extends Activity {
String shiftType;
Date d = new Date();


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.main); 




    Button AShift = (Button) findViewById(R.id.AShift);
    AShift.setOnClickListener(new View.OnClickListener(){
        public void onClick(View v) {
            TextView BtmTxt = (TextView) findViewById(R.id.BtmTxt);
            shiftType="A Shift";
            addToCalendar(DateAdder.this.getApplicationContext(), shiftType, d.getDate(), d.getDate()+1000);                
            BtmTxt.setText("Done");
        }});
} //END of onCreate



/**
 * Adds the event to a calendar. It lets the user choose the calendar
 * @param ctx Context ( Please use the application context )
 * @param title title of the event
 * @param dtstart Start time: The value is the number of milliseconds since Jan. 1, 1970, midnight GMT.
 * @param dtend End time: The value is the number of milliseconds since Jan. 1, 1970, midnight GMT.
 */
private static void addToCalendar(Context ctx, final String title, final long dtstart, final long dtend) {
    final ContentResolver cr = ctx.getContentResolver();
    Cursor cursor ;
    if (Integer.parseInt(Build.VERSION.SDK) == 8 )
        cursor = cr.query(Uri.parse("content://com.android.calendar/calendars"), new String[]{ "_id", "displayname" }, null, null, null);
    else
        cursor = cr.query(Uri.parse("content://calendar/calendars"), new String[]{ "_id", "displayname" }, null, null, null);
    if ( cursor.moveToFirst() ) {
        final String[] calNames = new String[cursor.getCount()];
        final int[] calIds = new int[cursor.getCount()];
        for (int i = 0; i < calNames.length; i++) {
            calIds[i] = cursor.getInt(0);
            calNames[i] = cursor.getString(1);
            cursor.moveToNext();
        }

        AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
        builder.setSingleChoiceItems(calNames, -1, new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int which) {
                ContentValues cv = new ContentValues();
                cv.put("calendar_id", calIds[which]);
                cv.put("title", title);
                cv.put("dtstart", dtstart );
                cv.put("dtend", dtend);
                cv.put("allday", 1);
                cv.put("hasAlarm", 0);

                Uri newEvent ;
                if (Integer.parseInt(Build.VERSION.SDK) == 8 )
                    newEvent = cr.insert(Uri.parse("content://com.android.calendar/events"), cv);
                else
                    newEvent = cr.insert(Uri.parse("content://com.android.calendar/events"), cv);

                if (newEvent != null) {
                    long id = Long.parseLong( newEvent.getLastPathSegment() );
                    ContentValues values = new ContentValues();
                    values.put( "event_id", id );
                    values.put( "method", 1 );
                    values.put( "minutes", 15 ); // 15 minuti
                    if (Integer.parseInt(Build.VERSION.SDK) == 8 开发者_开发百科)
                        cr.insert( Uri.parse( "content://com.android.calendar/reminders" ), values );
                    else
                        cr.insert( Uri.parse( "content://calendar/reminders" ), values );

                }
                dialog.cancel();
            }

        });

        builder.create().show();
    }
    cursor.close();
}

}

When I call this from my code I get a force close. The logcat reads:

android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application


Your problem is that you are creating a Dialog attached to the Application context, which is non-visual. As I see it you don't need the Application context anyway, since all you're doing is accessing the content resolver.

You just need to change this line:

addToCalendar(DateAdder.this.getApplicationContext(), 
    shiftType, d.getDate(), d.getDate()+1000);

to this:

addToCalendar(DateAdder.this, 
    shiftType, d.getDate(), d.getDate()+1000);

And the error goes away. (I tested it).

ADDENDUM:

Also change the first line of addToCalendar() to use the application context and thereby fulfill the commented requirement, but I'm unconvinced it makes a difference. I.e.:

final ContentResolver cr = ctx.getApplicationContext().getContentResolver();


change this

addToCalendar(getApplicationContext(), shiftType, d.getDate(), d.getDate()+1000);

to

addToCalendar(---yourClassName---.this.getApplicationContext(), shiftType, d.getDate(), d.getDate()+1000); 

an example :

addToCalendar(MainActivity.this.getApplicationContext(), shiftType, d.getDate(), d.getDate()+1000); 


If you're inside an activity, you can directly pass this instead of getApplicationContext, as Activity extends Context. ApplicationContext is the context for the whole application, whereas passing this allows you to pass the current context. This may solve your problem.


Sometimes you can also do

(Activity)view.getParent()

Instead of Dateadder.this or dateadder.this.getapplicationContext()

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜