2010-11-29 45 views
1

我正在使用一種方法將事件添加到手機上的內部日曆。背景一直困擾着我,這一次也不例外。方法契約需要應用程序上下文。該方法的調用是:上下文和日曆

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

這是我的代碼來調用方法時按下按鈕:

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

}

當我把這個從我的代碼,我收到了強制關閉。在logcat中寫道:

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

我認爲你的問題在別處。只有在向您的佈局動態添加視圖時纔會看到此消息(更具體地說,將佈局附加到應用的窗口時)。如何粘貼(a)更多的代碼,以及(b)來自logcat的完整堆棧跟蹤? – 2010-12-10 12:59:41

回答

3

你的問題是,你正在創建一個附加到應用程序上下文,這是非可視的對話框。正如我所看到的,無論如何您都不需要Application上下文,因爲您所做的只是訪問內容解析器。

你只需要改變這一行:

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

這樣:

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

和錯誤消失。 (我測試過)。

附錄:

而且改變addToCalendar()的第一行使用應用程序上下文,從而滿足了評論的要求,但我不相信它的確與衆不同。即:

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

改變這種

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

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

一個例子:

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

如果你是一個活動裏面,你可以直接傳遞this inste廣告getApplicationContext,因爲Activity擴展了上下文。 ApplicationContext是整個應用程序的上下文,而傳遞this允許您傳遞當前上下文。這可能會解決您的問題。

0

有時候你也可以做

(活動)view.getParent()

代替Dateadder.this或dateadder.this.getapplicationContext()