Skip to content

Commit 7dc164d

Browse files
#294 Calendar plugin along with Phonegap-Plugin-Push crashes the app in android.
1 parent 8b54dbc commit 7dc164d

File tree

4 files changed

+85
-52
lines changed

4 files changed

+85
-52
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,11 @@ Creating an event for 3 full days
265265
On Android 6 you need to request permission to use the Calendar at runtime when targeting API level 23+.
266266
Even if the `uses-permission` tags for the Calendar are present in `AndroidManifest.xml`.
267267

268+
Since plugin version 4.5.0 we transparently handle this for you in a just-in-time manner.
269+
So if you call `createEvent` we will pop up the permission dialog. After the user granted access
270+
to his calendar the event will be created.
271+
272+
You can also manually manage and check permissions if that's your thing.
268273
Note that the hasPermission functions will return true when:
269274

270275
- You're running this on iOS, or
@@ -273,6 +278,7 @@ Note that the hasPermission functions will return true when:
273278
- You've already granted permission.
274279

275280
```js
281+
// again, this is no longer needed with plugin version 4.5.0 and up
276282
function hasReadWritePermission() {
277283
window.plugins.calendar.hasReadWritePermission(
278284
function(result) {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "cordova-plugin-calendar",
3-
"version": "4.4.8-dev",
3+
"version": "4.5.0",
44
"description": "This plugin allows you to manipulate the native calendar.",
55
"cordova": {
66
"id": "cordova-plugin-calendar",

plugin.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
xmlns="http://apache.org/cordova/ns/plugins/1.0"
44
xmlns:android="http://schemas.android.com/apk/res/android"
55
id="cordova-plugin-calendar"
6-
version="4.4.8-dev">
6+
version="4.5.0">
77

88
<name>Calendar</name>
99

@@ -73,6 +73,6 @@
7373
target-dir="src/nl/xservices/plugins/accessor"/>
7474
<source-file src="src/android/nl/xservices/plugins/accessor/LegacyCalendarAccessor.java"
7575
target-dir="src/nl/xservices/plugins/accessor"/>
76-
<framework src="com.android.support:support-v4:+" />
76+
<dependency id="cordova-plugin-compat" version="^1.0.0" />
7777
</platform>
7878
</plugin>

src/android/nl/xservices/plugins/Calendar.java

Lines changed: 76 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,13 @@
1111
import android.net.Uri;
1212
import android.os.Build;
1313
import android.provider.CalendarContract;
14-
import android.support.v4.app.ActivityCompat;
15-
import android.support.v4.content.ContextCompat;
1614
import android.util.Log;
1715
import nl.xservices.plugins.accessor.AbstractCalendarAccessor;
1816
import nl.xservices.plugins.accessor.CalendarProviderAccessor;
1917
import nl.xservices.plugins.accessor.LegacyCalendarAccessor;
2018
import org.apache.cordova.CallbackContext;
2119
import org.apache.cordova.CordovaPlugin;
20+
import org.apache.cordova.PermissionHelper;
2221
import org.apache.cordova.PluginResult;
2322
import org.json.JSONArray;
2423
import org.json.JSONException;
@@ -49,16 +48,29 @@ public class Calendar extends CordovaPlugin {
4948
private static final String ACTION_LIST_CALENDARS = "listCalendars";
5049
private static final String ACTION_CREATE_CALENDAR = "createCalendar";
5150

51+
// write permissions
52+
private static final int PERMISSION_REQCODE_CREATE_CALENDAR = 100;
53+
private static final int PERMISSION_REQCODE_DELETE_EVENT = 101;
54+
private static final int PERMISSION_REQCODE_CREATE_EVENT = 102;
55+
56+
// read permissions
57+
private static final int PERMISSION_REQCODE_FIND_EVENTS = 200;
58+
private static final int PERMISSION_REQCODE_LIST_CALENDARS = 201;
59+
private static final int PERMISSION_REQCODE_LIST_EVENTS_IN_RANGE = 202;
60+
5261
private static final Integer RESULT_CODE_CREATE = 0;
5362
private static final Integer RESULT_CODE_OPENCAL = 1;
5463

64+
private JSONArray requestArgs;
5565
private CallbackContext callback;
5666

5767
private static final String LOG_TAG = AbstractCalendarAccessor.LOG_TAG;
5868

5969
@Override
6070
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
61-
callback = callbackContext;
71+
this.callback = callbackContext;
72+
this.requestArgs = args;
73+
6274
final boolean hasLimitedSupport = Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH;
6375

6476
if (ACTION_OPEN_CALENDAR.equals(action)) {
@@ -104,13 +116,13 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo
104116
hasReadWritePermission();
105117
return true;
106118
} else if (REQUEST_READ_PERMISSION.equals(action)) {
107-
requestReadPermission();
119+
requestReadPermission(0);
108120
return true;
109121
} else if (REQUEST_WRITE_PERMISSION.equals(action)) {
110-
requestWritePermission();
122+
requestWritePermission(0);
111123
return true;
112124
} else if (REQUEST_READWRITE_PERMISSION.equals(action)) {
113-
requestReadWritePermission();
125+
requestReadWritePermission(0);
114126
return true;
115127
}
116128
return false;
@@ -131,39 +143,59 @@ private void hasReadWritePermission() {
131143
calendarPermissionGranted(Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR)));
132144
}
133145

134-
private void requestReadPermission() {
135-
requestPermission(Manifest.permission.READ_CALENDAR);
146+
private void requestReadPermission(int requestCode) {
147+
requestPermission(requestCode, Manifest.permission.READ_CALENDAR);
136148
}
137149

138-
private void requestWritePermission() {
139-
requestPermission(Manifest.permission.WRITE_CALENDAR);
150+
private void requestWritePermission(int requestCode) {
151+
requestPermission(requestCode, Manifest.permission.WRITE_CALENDAR);
140152
}
141153

142-
private void requestReadWritePermission() {
143-
requestPermission(Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR);
154+
private void requestReadWritePermission(int requestCode) {
155+
requestPermission(requestCode, Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR);
144156
}
145157

146158
private boolean calendarPermissionGranted(String... types) {
147159
if (Build.VERSION.SDK_INT < 23) {
148160
return true;
149161
}
150162
for (final String type : types) {
151-
if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(this.cordova.getActivity(), type)) {
163+
if (!PermissionHelper.hasPermission(this, type)) {
152164
return false;
153165
}
154166
}
155167
return true;
156168
}
157169

158-
private void requestPermission(String... types) {
170+
private void requestPermission(int requestCode, String... types) {
159171
if (!calendarPermissionGranted(types)) {
160-
ActivityCompat.requestPermissions(
161-
this.cordova.getActivity(),
162-
types,
163-
555);
172+
PermissionHelper.requestPermissions(this, requestCode, types);
173+
}
174+
}
175+
176+
public void onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults) throws JSONException {
177+
for (int r : grantResults) {
178+
if (r == PackageManager.PERMISSION_DENIED) {
179+
Log.d(LOG_TAG, "Permission Denied!");
180+
this.callback.error("Please allow access to the Calendar and try again.");
181+
return;
182+
}
183+
}
184+
185+
// now call the originally requested actions
186+
if (requestCode == PERMISSION_REQCODE_CREATE_CALENDAR) {
187+
createCalendar(requestArgs);
188+
} else if (requestCode == PERMISSION_REQCODE_CREATE_EVENT) {
189+
createEvent(requestArgs);
190+
} else if (requestCode == PERMISSION_REQCODE_DELETE_EVENT) {
191+
deleteEvent(requestArgs);
192+
} else if (requestCode == PERMISSION_REQCODE_FIND_EVENTS) {
193+
findEvents(requestArgs);
194+
} else if (requestCode == PERMISSION_REQCODE_LIST_CALENDARS) {
195+
listCalendars();
196+
} else if (requestCode == PERMISSION_REQCODE_LIST_EVENTS_IN_RANGE) {
197+
listEventsInRange(requestArgs);
164198
}
165-
// this method executes async and we seem to have no known way to receive the result, so simply returning ok now
166-
this.callback.success();
167199
}
168200

169201
private void openCalendarLegacy(JSONArray args) {
@@ -215,8 +247,7 @@ private void listCalendars() {
215247
// note that if the dev didn't call requestReadPermission before calling this method and calendarPermissionGranted returns false,
216248
// the app will ask permission and this method needs to be invoked again (done for backward compat).
217249
if (!calendarPermissionGranted(Manifest.permission.READ_CALENDAR)) {
218-
requestReadPermission();
219-
this.callback.error("Please allow Read access to the Calendar and try again.");
250+
requestReadPermission(PERMISSION_REQCODE_LIST_CALENDARS);
220251
return;
221252
}
222253
cordova.getThreadPool().execute(new Runnable() {
@@ -247,8 +278,7 @@ private void createCalendar(JSONArray args) {
247278
// note that if the dev didn't call requestWritePermission before calling this method and calendarPermissionGranted returns false,
248279
// the app will ask permission and this method needs to be invoked again (done for backward compat).
249280
if (!calendarPermissionGranted(Manifest.permission.WRITE_CALENDAR)) {
250-
requestWritePermission();
251-
this.callback.error("Please allow Write access to the Calendar and try again.");
281+
requestWritePermission(PERMISSION_REQCODE_CREATE_CALENDAR);
252282
return;
253283
}
254284

@@ -359,8 +389,7 @@ private void deleteEvent(JSONArray args) {
359389
// note that if the dev didn't call requestWritePermission before calling this method and calendarPermissionGranted returns false,
360390
// the app will ask permission and this method needs to be invoked again (done for backward compat).
361391
if (!calendarPermissionGranted(Manifest.permission.WRITE_CALENDAR)) {
362-
requestWritePermission();
363-
this.callback.error("Please allow Write access to the Calendar and try again.");
392+
requestWritePermission(PERMISSION_REQCODE_DELETE_EVENT);
364393
return;
365394
}
366395

@@ -397,8 +426,7 @@ private void findEvents(JSONArray args) {
397426
// note that if the dev didn't call requestReadPermission before calling this method and calendarPermissionGranted returns false,
398427
// the app will ask permission and this method needs to be invoked again (done for backward compat).
399428
if (!calendarPermissionGranted(Manifest.permission.READ_CALENDAR)) {
400-
requestReadPermission();
401-
this.callback.error("Please allow Read access to the Calendar and try again.");
429+
requestReadPermission(PERMISSION_REQCODE_FIND_EVENTS);
402430
return;
403431
}
404432

@@ -429,8 +457,7 @@ private void createEvent(JSONArray args) {
429457
// note that if the dev didn't call requestWritePermission before calling this method and calendarPermissionGranted returns false,
430458
// the app will ask permission and this method needs to be invoked again (done for backward compat).
431459
if (!calendarPermissionGranted(Manifest.permission.WRITE_CALENDAR)) {
432-
requestWritePermission();
433-
this.callback.error("Please allow Write access to the Calendar and try again.");
460+
requestWritePermission(PERMISSION_REQCODE_CREATE_EVENT);
434461
return;
435462
}
436463

@@ -476,13 +503,11 @@ private void listEventsInRange(JSONArray args) {
476503
// note that if the dev didn't call requestReadPermission before calling this method and calendarPermissionGranted returns false,
477504
// the app will ask permission and this method needs to be invoked again (done for backward compat).
478505
if (!calendarPermissionGranted(Manifest.permission.READ_CALENDAR)) {
479-
requestReadPermission();
480-
this.callback.error("Please allow Read access to the Calendar and try again.");
506+
requestReadPermission(PERMISSION_REQCODE_LIST_EVENTS_IN_RANGE);
481507
return;
482508
}
483509
try {
484510
final JSONObject jsonFilter = args.getJSONObject(0);
485-
JSONArray result = new JSONArray();
486511
long input_start_date = jsonFilter.optLong("startTime");
487512
long input_end_date = jsonFilter.optLong("endTime");
488513

@@ -531,24 +556,26 @@ public void run() {
531556
"begin ASC");
532557

533558
int i = 0;
534-
while (cursor.moveToNext()) {
535-
try {
536-
result.put(
537-
i++,
538-
new JSONObject()
539-
.put("calendar_id", cursor.getString(cursor.getColumnIndex("calendar_id")))
540-
.put("event_id", cursor.getString(cursor.getColumnIndex("_id")))
541-
.put("title", cursor.getString(cursor.getColumnIndex("title")))
542-
.put("dtstart", cursor.getLong(cursor.getColumnIndex("begin")))
543-
.put("dtend", cursor.getLong(cursor.getColumnIndex("end")))
544-
.put("eventLocation", cursor.getString(cursor.getColumnIndex("eventLocation")) != null ? cursor.getString(cursor.getColumnIndex("eventLocation")) : "")
545-
.put("allDay", cursor.getInt(cursor.getColumnIndex("allDay")))
546-
);
547-
} catch (JSONException e) {
548-
e.printStackTrace();
559+
if (cursor != null) {
560+
while (cursor.moveToNext()) {
561+
try {
562+
result.put(
563+
i++,
564+
new JSONObject()
565+
.put("calendar_id", cursor.getString(cursor.getColumnIndex("calendar_id")))
566+
.put("event_id", cursor.getString(cursor.getColumnIndex("_id")))
567+
.put("title", cursor.getString(cursor.getColumnIndex("title")))
568+
.put("dtstart", cursor.getLong(cursor.getColumnIndex("begin")))
569+
.put("dtend", cursor.getLong(cursor.getColumnIndex("end")))
570+
.put("eventLocation", cursor.getString(cursor.getColumnIndex("eventLocation")) != null ? cursor.getString(cursor.getColumnIndex("eventLocation")) : "")
571+
.put("allDay", cursor.getInt(cursor.getColumnIndex("allDay")))
572+
);
573+
} catch (JSONException e) {
574+
e.printStackTrace();
575+
}
549576
}
577+
cursor.close();
550578
}
551-
cursor.close();
552579

553580
PluginResult res = new PluginResult(PluginResult.Status.OK, result);
554581
callback.sendPluginResult(res);

0 commit comments

Comments
 (0)