8

even though i have declared the uses-permissions in the manifest, it gives me an error saying i need to add the permissions.

android manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="groep2.project4">
    <uses-permission android:name="android.permission.READ_CALENDAR"/>
    <uses-permission android:name="android.permission.WRITE_CALENDAR"/>
    <uses-permission-sdk-23 android:name="android.permission.READ_CALENDAR"/>
    <uses-permission-sdk-23 android:name="android.permission.WRITE_CALENDAR"/>

error:

FATAL EXCEPTION: main 
Process: groep2.project4, PID: 3188 
java.lang.SecurityException: Permission Denial: 
opening provider com.android.providers.calendar.CalendarProvider2 
from ProcessRecord{81d3d48 3188:groep2.project4/u0a58} (pid=3188, uid=10058) 
requires android.permission.READ_CALENDAR or android.permission.WRITE_CALENDAR
                                                               at android.os.Parcel.readException(Parcel.java:1599)
                                                               at android.os.Parcel.readException(Parcel.java:1552)
                                                               at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:3550)
                                                               at android.app.ActivityThread.acquireProvider(ActivityThread.java:4778)
                                                               at android.app.ContextImpl$ApplicationContentResolver.acquireProvider(ContextImpl.java:1999)
                                                               at android.content.ContentResolver.acquireProvider(ContentResolver.java:1421)
                                                               at android.content.ContentResolver.insert(ContentResolver.java:1225)
                                                               at groep2.project4.Fragments.pushAppointmentsToCalendar.pushAppointmentsToCalender(pushAppointmentsToCalendar.java:50)
                                                               at groep2.project4.Fragments.TimePickerFragment.makeReminder(TimePickerFragment.java:46)
                                                               at groep2.project4.Fragments.TimePickerFragment.onTimeSet(TimePickerFragment.java:41)
                                                               at android.app.TimePickerDialog.onClick(TimePickerDialog.java:145)
                                                               at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:163)
                                                               at android.os.Handler.dispatchMessage(Handler.java:102)
                                                               at android.os.Looper.loop(Looper.java:148)
                                                               at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                               at java.lang.reflect.Method.invoke(Native Method)
                                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

and here is the pushappointmentstocalendar.java

package groep2.project4.Fragments;

import android.app.Activity;
import android.content.ContentValues;
import android.net.Uri;

/**
 * Created by Dennis on 28-6-2016.
 */
public class pushAppointmentsToCalendar {
    public static long pushAppointmentsToCalender(Activity curActivity, String title, String addInfo, String place, int status, long startDate, boolean needReminder, boolean needMailService) {
        /***************** Event: note(without alert) *******************/

        String eventUriString = "content://com.android.calendar/events";
        ContentValues eventValues = new ContentValues();

        eventValues.put("calendar_id", 1); 
        eventValues.put("title", title);
        eventValues.put("description", addInfo);
        eventValues.put("eventLocation", place);

        long endDate = startDate + 1000 * 60 * 60; // For next 1hr

        eventValues.put("dtstart", startDate);
        eventValues.put("dtend", endDate);

        eventValues.put("allDay", 0);
        eventValues.put("eventStatus", status);
        eventValues.put("eventTimezone", "UTC/GMT +2:00");

    /*eventValues.put("visibility", 3); // visibility to default (0),
                                        // confidential (1), private
                                        // (2), or public (3):
    eventValues.put("transparency", 0); // You can control whether
                                        // an event consumes time
                                        // opaque (0) or transparent
                                        // (1).
      */
        eventValues.put("hasAlarm", 1); // 0 for false, 1 for true

        Uri eventUri = curActivity.getApplicationContext().getContentResolver().insert(Uri.parse(eventUriString), eventValues);
        long eventID = Long.parseLong(eventUri.getLastPathSegment());

        if (needReminder) {    
            String reminderUriString = "content://com.android.calendar/reminders";

            ContentValues reminderValues = new ContentValues();

            reminderValues.put("event_id", eventID);
            reminderValues.put("minutes", 5); // Default value of the
            // system. Minutes is a
            // integer
            reminderValues.put("method", 1); // Alert Methods: Default(0),
            // Alert(1), Email(2),
            // SMS(3)

            Uri reminderUri = curActivity.getApplicationContext().getContentResolver().insert(Uri.parse(reminderUriString), reminderValues);
        }

        /***************** Event: Meeting(without alert) Adding Attendies to the meeting *******************/

        if (needMailService) {
            String attendeuesesUriString = "content://com.android.calendar/attendees";

            /********
             * To add multiple attendees need to insert ContentValues multiple
             * times
             ***********/
            ContentValues attendeesValues = new ContentValues();

            attendeesValues.put("event_id", eventID);
            attendeesValues.put("attendeeName", "xxxxx"); // Attendees name
            attendeesValues.put("attendeeEmail", "yyyy@gmail.com");// Attendee
            // E
            // mail
            // id
            attendeesValues.put("attendeeRelationship", 0); // Relationship_Attendee(1),
            // Relationship_None(0),
            // Organizer(2),
            // Performer(3),
            // Speaker(4)
            attendeesValues.put("attendeeType", 0); // None(0), Optional(1),
            // Required(2), Resource(3)
            attendeesValues.put("attendeeStatus", 0); // NOne(0), Accepted(1),
            // Decline(2),
            // Invited(3),
            // Tentative(4)

            Uri attendeuesesUri = curActivity.getApplicationContext().getContentResolver().insert(Uri.parse(attendeuesesUriString), attendeesValues);
        }

        return eventID;

    }
}

i cant figure out why it doesn't work. ive even tried adding the other SDK version of the permission but it still didn't work.

Dennis Lukas
  • 483
  • 2
  • 6
  • 20
  • 1
    https://stackoverflow.com/questions/32635704/android-permission-doesnt-work-even-if-i-have-declared-it – CommonsWare Jun 29 '16 at 22:13
  • Check this: https://stackoverflow.com/questions/47855036/calendar-provider-permission-denial-on-android-8 – Divyesh Dec 09 '19 at 13:55
  • Check this: https://stackoverflow.com/questions/47855036/calendar-provider-permission-denial-on-android-8 – Divyesh Dec 09 '19 at 13:55

1 Answers1

13

Once you are targeting android SDK 23 you should work with RunTime permissions, below is a simple method to help you on getting started.

private void checkPermissions(int callbackId, String... permissionsId) {
    boolean permissions = true;
    for (String p : permissionsId) {
        permissions = permissions && ContextCompat.checkSelfPermission(this, p) == PERMISSION_GRANTED;
    }

    if (!permissions)
        ActivityCompat.requestPermissions(this, permissionsId, callbackId);
}

You can use it like this:

 final int callbackId = 42;
 checkPermission(callbackId, Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR);

The requestPermissions method returns a callback in witch you can proceed to deal with the permissions being denied or accepted:

@Override
public void onRequestPermissionsResult(int callbackId,
        String permissions[], int[] grantResults) {...}
Gabriel Kaffka
  • 1,039
  • 8
  • 9
  • already give runtime both permission then also throw error permission denial – Makvin Jun 27 '19 at 05:49
  • Thanks Gabriel! For those who stumble across this answer in the future please keep in mind that onRequestPermissionsResult is now deprecated. See this [SO answer](https://stackoverflow.com/a/66552678/848353) for the current method that will need to be adapted for Calendar permissions. – yerty Jun 11 '21 at 13:34