2010-11-29 36 views
1

J'utilise une méthode pour ajouter un événement à un calendrier interne sur le téléphone. Le contexte m'a toujours confondu et cette fois n'est pas différent. Le contrat de méthode veut le contexte de l'application. L'appel de méthode est:Contexte et calendrier

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

Ceci est mon code pour appeler la méthode quand un bouton est pressé:

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

}

je reçois une force proche Quand j'appelle cela de mon code . Le logcat lit comme suit:

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

Je pense que votre problème est ailleurs. Ce message ne doit s'afficher que lorsque vous ajoutez dynamiquement des Vues à votre mise en page (plus précisément, lorsque vous joignez la mise en page à la fenêtre de l'application). Que diriez-vous de coller (a) plus de code, et (b) la trace de pile complète de logcat? –

+0

Je pense que vous avez raison Rueben. Va ajouter mon code sous peu. – Phobos

Répondre

3

Votre problème est que vous créez une boîte de dialogue attachée au contexte d'application, qui est non-visuelle. Comme je le vois, vous n'avez pas besoin du contexte d'application, puisque tout ce que vous faites est d'accéder au résolveur de contenu.

Vous avez juste besoin de changer cette ligne:

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

à ceci:

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

Et l'erreur disparaît. (Je l'ai testé).

ADDENDA:

changer également la première ligne de addToCalendar() pour utiliser le contexte d'application et de remplir ainsi l'exigence commenté, mais je ne suis pas convaincu qu'il fait une différence. À savoir:

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

changer cette

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

à

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

un exemple:

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

Si vous êtes dans une activité, vous pouvez passer directement this inste annonce de getApplicationContext, en tant qu'Activité étend le contexte. ApplicationContext est le contexte pour l'ensemble de l'application, tandis que le passage this vous permet de passer le contexte actuel. Cela peut résoudre votre problème.

0

Parfois, vous pouvez aussi faire

(activité) view.getParent()

Au lieu de Dateadder.this ou dateadder.this.getapplicationContext()