背景和日历
我正在使用一种方法将事件添加到手机的内部日历中。背景总是让我感到困惑,这次也不例外。方法契约需要应用程序上下文。方法调用是:
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();
}
}
当我从代码中调用此方法时,我会强制关闭。日志猫显示:
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
将其更改
为
示例:
change this
to
an example :
如果您位于 Activity 内部,则可以直接传递
this
而不是getApplicationContext
,因为 Activity 扩展了 Context。 ApplicationContext 是整个应用程序的上下文,而传递this
允许您传递当前上下文。这可能会解决您的问题。If you're inside an activity, you can directly pass
this
instead ofgetApplicationContext
, as Activity extends Context. ApplicationContext is the context for the whole application, whereas passingthis
allows you to pass the current context. This may solve your problem.有时你也可以做
(Activity)view.getParent()
而不是 Dateadder.this 或 dateadder.this.getapplicationContext()
Sometimes you can also do
(Activity)view.getParent()
Instead of Dateadder.this or dateadder.this.getapplicationContext()
您的问题是您正在创建一个附加到应用程序上下文的对话框,该对话框是非可视的。正如我所见,您无论如何都不需要应用程序上下文,因为您所做的只是访问内容解析器。
您只需要将这一行: 更改
为:
错误就会消失。 (我测试过)。
附录:
还更改 addToCalendar() 的第一行以使用应用程序上下文,从而满足注释的要求,但我不相信它会产生影响。 IE:
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:
to this:
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.: