【问题标题】:Event added through Calendar Provider is not showing up on the Android Calendar App通过日历提供程序添加的事件未显示在 Android 日历应用程序上
【发布时间】:2017-10-27 00:24:06
【问题描述】:

我正在尝试将事件添加到默认的 android 日历,而不要求用户确认保存事件。 (所以不是故意的)

以下代码没有编译错误或运行时错误。点击按钮后,不会显示错误,也不会向 Android 日历应用程序添加任何事件。

我已经检查了清单中的日历授权并检查了 graddle 中的 de min sdk 版本(我在 android studio 上工作)

public void onAddEventClicked(View view) {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) != PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
    }
    else if(ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR) == PackageManager.PERMISSION_GRANTED) {
        ContentResolver cr = getContentResolver();
        Calendar beginTime = Calendar.getInstance();
        beginTime.set(2018, Calendar.OCTOBER, 27, 13, 30);
        Calendar endTime = Calendar.getInstance();
        endTime.set(2018, Calendar.OCTOBER, 27, 17, 30);
        ContentValues values = new ContentValues();
        values.put(CalendarContract.Events.DTSTART, beginTime.getTimeInMillis());
        values.put(CalendarContract.Events.DTEND, endTime.getTimeInMillis());
        values.put(CalendarContract.Events.TITLE, "doctor");
        values.put(CalendarContract.Events.DESCRIPTION, "doctor appointment");
        values.put(CalendarContract.Events.CALENDAR_ID, 0);
        values.put(CalendarContract.Events.EVENT_TIMEZONE, "Europe/Paris");
        values.put(CalendarContract.Events.EVENT_LOCATION, "Paris");
        Uri EVENTS_URI = Uri.parse(CalendarContract.Events.CONTENT_URI.toString());
        Uri uri = cr.insert(EVENTS_URI, values);
        Button b = (Button) findViewById(R.id.addEventButton);
        b.setText("Did it worked ?");
    }
}

【问题讨论】:

  • 你发现问题了吗??我也有同样的问题。这是因为日历 ID 不正确。首先,我们需要找出手机中所有日历的主日历 ID,然后使用该日历 ID 来创建事件。要获取主日历 ID,您可以按照 Malwinder Singh 的回答。我也尝试了相同的代码,令我惊讶的是,我得到了两个主日历 ID。我想知道使用哪一个。

标签: android calendar google-calendar-api android-calendar


【解决方案1】:

默认日历 ID 为 3,但您有 0,这可能是您看不到将其添加到日历中的原因。

Calendar Provider developer doc 开始,它会将日历 ID 硬编码为 3。

long calID = 3;
long startMillis = 0;
long endMillis = 0;
Calendar beginTime = Calendar.getInstance();
beginTime.set(2012, 9, 14, 7, 30);
startMillis = beginTime.getTimeInMillis();
Calendar endTime = Calendar.getInstance();
endTime.set(2012, 9, 14, 8, 45);
endMillis = endTime.getTimeInMillis();
...

ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put(Events.DTSTART, startMillis);
values.put(Events.DTEND, endMillis);
values.put(Events.TITLE, "Jazzercise");
values.put(Events.DESCRIPTION, "Group workout");
values.put(Events.CALENDAR_ID, calID);
values.put(Events.EVENT_TIMEZONE, "America/Los_Angeles");
Uri uri = cr.insert(Events.CONTENT_URI, values);

// get the event ID that is the last element in the Uri
long eventID = Long.parseLong(uri.getLastPathSegment());

为确保 3 是主日历 ID,您可以参考此 post 查询主/默认日历

【讨论】:

    【解决方案2】:

    我遇到了这个问题,然后我使用以下代码获取日历 ID。

    private fun getCalendarId(context: Context) : Long? {
        val projection = arrayOf(Calendars._ID, Calendars.CALENDAR_DISPLAY_NAME)
    
        var calCursor = context.contentResolver.query(
            Calendars.CONTENT_URI,
            projection,
            Calendars.VISIBLE + " = 1 AND " + Calendars.IS_PRIMARY + "=1",
            null,
            Calendars._ID + " ASC"
        )
    
        if (calCursor != null && calCursor.count >= 0) {
            calCursor = context.contentResolver.query(
                Calendars.CONTENT_URI,
                projection,
                Calendars.VISIBLE + " = 1",
                null,
                Calendars._ID + " ASC"
            )
        }
    
        if (calCursor != null) {
            if (calCursor.moveToFirst()) {
                val calName: String
                val calID: String
                val nameCol = calCursor.getColumnIndex(projection[1])
                val idCol = calCursor.getColumnIndex(projection[0])
    
                calName = calCursor.getString(nameCol)
                calID = calCursor.getString(idCol)
    
                Log.d("Calendar name = $calName Calendar ID = $calID")
    
                calCursor.close()
                return calID.toLong()
            }
        }
        return null
    }
    

    所以不要将 0、1 或 3 作为日历 ID 传递。请改用上述函数。

    【讨论】:

    • 是的,由于日历 ID 不正确,我也遇到了同样的问题。通过使用上面的代码,我得到了 2 个条目作为输出。现在我应该使用哪一个??我可以使用我获得的任何主要日历的日历 ID 来创建活动吗??
    • 你好。您是否有 2 个 Google 帐户登录到您的设备?你能告诉你得到的条目值吗?另外,我已经解决了问题:应该是 calCursor.count >= 0
    • 是的,我有 2 个帐户登录到我的设备。这是我得到的值 {calName='kondreddy pradeep kumar reddy', calID='8', accName='kpradeepreddy@gmail.com', accType='com.google', visible='1', primary ='1'} {calName='pradeep@abc.com', calID='17', accName='pradeep@abc.com', accType='com.google', visible='1', primary='1 '}
    • 您可以使用上述任何条目。在这种情况下,我认为您应该询问用户在有多个日历 ID 的情况下要将数据保存到哪个帐户。您需要修改函数以返回多个有效的日历 ID。另外,您能否更新此答案以返回多个日历 ID(如果存在)?
    • 好的。这对用户有什么影响?如果用户想要的只是创建一个事件并在事件发生之前得到通知,那么我认为我使用哪个帐户对用户来说并不重要?我尝试了两个日历 ID,并且能够创建事件并向这些事件添加提醒。这些事件在谷歌日历应用程序中可见。无论用户选择哪个帐户,功能都不会改变对吗??哦好的。如果用户从他的手机中删除其中一个帐户,那么该帐户的事件可能也会被删除?
    【解决方案3】:

    这会将事件添加到用户日历中。

    向清单添加权限:

     <uses-permission android:name="android.permission.READ_CALENDAR" />
     <uses-permission android:name="android.permission.WRITE_CALENDAR" />
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    
    
     <permission android:name="android.permission.READ_CALENDAR" />
     <permission android:name="android.permission.WRITE_CALENDAR" />
     <permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    

    添加到 oncreate:

    if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) !=          PackageManager.PERMISSION_GRANTED)
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_CALENDAR}, 1);
    

    添加到主要活动: (View view) (MenuItem mi) 用于菜单抽屉。

    public void onAddEventCal(MenuItem mi) {
    
        long calID = 3;
        ContentResolver cr = getContentResolver();
        Calendar beginTime = Calendar.getInstance();
        beginTime.set(2019, Calendar.FEBRUARY, 25, 3, 30);
        Calendar endTime = Calendar.getInstance();
        endTime.set(2019, Calendar.FEBRUARY, 25, 3, 30);
        ContentValues values = new ContentValues();
        values.put(CalendarContract.Events.DTSTART, beginTime.getTimeInMillis());
        values.put(CalendarContract.Events.DTEND, endTime.getTimeInMillis());
        values.put(CalendarContract.Events.TITLE, "Connect Treadmill app");
        values.put(CalendarContract.Events.DESCRIPTION, "Treadmill Data");
        values.put(CalendarContract.Events.CALENDAR_ID, calID);
        values.put(CalendarContract.Events.EVENT_TIMEZONE, "Europe/Paris");
        values.put(CalendarContract.Events.EVENT_LOCATION, "Paris");
        Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);
    
    
        Toast.makeText(this, "Calendar Event added", Toast.LENGTH_SHORT).show();
    
    }
    

    【讨论】:

      【解决方案4】:

      我认为问题出在许可范围内 尝试使用这些代码

      if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) != PackageManager.PERMISSION_GRANTED 
          && ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
      ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION},MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);}else if(ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_GRANTED 
              && ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR) == PackageManager.PERMISSION_GRANTED){
      
      
      
      }
      

      【讨论】:

      • 我只用数字 1 而不是你的“MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION”来测试它,因为谷歌说它应该是一个 const int 所以......让我们试试,因为我不知道我可以在哪里抓住它。我仍然通过这种方式获得相同的结果。我的意思是,当我单击按钮时,文本会发生变化,它会在所有代码中暂停,但日历中仍然没有新事件我只是将带有您修改的版本放在帖子上
      • 你检查是否有日历ID为日历
      • 只是添加,添加事件时必须指定vent所属的calendar_id。有关reference,请参阅此文档。要获取默认的 calendar_id,请检查此related SO post。希望这会有所帮助。
      • 感谢大家的帮助,但仍然无法正常工作。 @MR.Rebot:我不明白字段 calendar_id 正在等待一个 int 但在“相关 SO 帖子”中获取它的方式返回一个字符串?
      • 我真的需要一些帮助,有人有什么想法吗?我仍然不确定如何获取 calendar_id
      【解决方案5】:

      这个权限请求是我使用的。你可以修改成你想要的权限。

       onCreate
      
       // Ask for location && calendar permission if not already allowed
          Request_Permissions();
      
      
      
      
      ManActivity
      //Request permission
      private void Request_Permissions()
      {
          ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_CALENDAR, android.Manifest.permission.ACCESS_COARSE_LOCATION
          }, 1);
      }
      

      【讨论】:

        猜你喜欢
        • 2020-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多