2010-11-29 5 views
1

Ich verwende eine Methode, um ein Ereignis zu einem internen Kalender auf dem Telefon hinzuzufügen. Kontext hat mich immer verwirrt und diese Zeit ist nicht anders. Der Methodenvertrag möchte den Anwendungskontext. Der Methodenaufruf ist:Kontext und Kalender

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

Das ist mein Code ist die Methode aufzurufen, wenn eine Taste gedrückt wird:

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

}

Als ich das von meinem Code aufrufen bekomme ich eine Kraft schließen . Die logcat lautet:

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

Ich denke, Ihr Problem ist woanders. Diese Nachricht sollte nur beim dynamischen Hinzufügen von Ansichten zu Ihrem Layout angezeigt werden (insbesondere beim Anfügen von Layout an das Fenster der App). Wie wäre es mit (mehr) Code und (b) dem vollständigen Stack-Trace von logcat? –

+0

Ich denke du hast Recht Rueben. Wird meinen Code in Kürze hinzufügen. – Phobos

Antwort

3

Ihr Problem besteht darin, dass Sie einen Dialog erstellen, der an den Anwendungskontext angehängt ist, der nicht visuell ist. Wie ich es sehe, brauchen Sie den Anwendungskontext sowieso nicht, da Sie lediglich auf den Content Resolver zugreifen.

Sie müssen nur diese Zeile ändern:

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

dazu:

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

Und der Fehler geht weg. (Ich habe es getestet).

NACHTRAG:

auch die erste Zeile der addToCalendar() ändern Sie den Anwendungskontext zu verwenden und dadurch die kommentierte Anforderung zu erfüllen, aber ich bin nicht überzeugt es einen Unterschied macht. Dh:

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

Änderung dieses

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

zu

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

ein Beispiel:

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

Wenn Sie in einer Aktivität sind, können Sie direkt übergeben this inste Anzeige von getApplicationContext, wie Aktivität Kontext erweitert. ApplicationContext ist der Kontext für die gesamte Anwendung, während die Übergabe this Ihnen ermöglicht, den aktuellen Kontext zu übergeben. Dies kann Ihr Problem lösen.

0

Manchmal kann man auch

(Aktivität) view.getParent tun()

Statt Dateadder.this oder dateadder.this.getapplicationContext()