背景和日历

发布于 2024-10-04 11:43:12 字数 3973 浏览 2 评论 0原文

我正在使用一种方法将事件添加到手机的内部日历中。背景总是让我感到困惑,这次也不例外。方法契约需要应用程序上下文。方法调用是:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

别理我 2024-10-11 11:43:13

将其更改

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

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); 
默嘫て 2024-10-11 11:43:13

如果您位于 Activity 内部,则可以直接传递 this 而不是 getApplicationContext,因为 Activity 扩展了 Context。 ApplicationContext 是整个应用程序的上下文,而传递 this 允许您传递当前上下文。这可能会解决您的问题。

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.

听风念你 2024-10-11 11:43:13

有时你也可以做

(Activity)view.getParent()

而不是 Dateadder.this 或 dateadder.this.getapplicationContext()

Sometimes you can also do

(Activity)view.getParent()

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

紫罗兰の梦幻 2024-10-11 11:43:12

您的问题是您正在创建一个附加到应用程序上下文的对话框,该对话框是非可视的。正如我所见,您无论如何都不需要应用程序上下文,因为您所做的只是访问内容解析器。

您只需要将这一行: 更改

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

为:

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

错误就会消失。 (我测试过)。

附录:

还更改 addToCalendar() 的第一行以使用应用程序上下文,从而满足注释的要求,但我不相信它会产生影响。 IE:

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

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();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文